Loading go-apps/meep-ipe/MEC/init.go +3 −1 Changes for go-apps/meep-ipe/MEC/init.go: 3 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -446,6 +446,7 @@ func InitMEC(cfg map[string]interface{}) { // Step # 7: Create a Node on the oneM2M platform to represent the MEC IPE service // nodeName := "mec_ipe_node" nodeID := uuid.NewString() err = onem2m.CreateNode(onem2m.NodeName(), nodeID) if err != nil { log.Printf("Failed to create a Node on the oneM2M platform: %v", err) Loading Loading @@ -496,7 +497,8 @@ func InitMEC(cfg map[string]interface{}) { // -> Create a flex container for each service and publish it onto the CSE url = fmt.Sprintf("%s:%s/~/%s/%s", config["CSE-URL"], config["CSE-PORT"], config["CSE-ID"], config["CSE-NAME"]) for _, service := range responseData { containerName := fmt.Sprintf("%s-%s", service.SerName, config["sandboxName"]) // Containers live under this IPE's node, so the service name alone is unique containerName := service.SerName // Sent Get request to service endpoint fullUrl, err := fetchAndAppendHref(fmt.Sprintf("%suser-api/", service.TransportInfo.Endpoint.Uris[0])) if err != nil { Loading go-apps/meep-ipe/MEC/mec_iot_pltf_notification.go +7 −3 Changes for go-apps/meep-ipe/MEC/mec_iot_pltf_notification.go: 7 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import ( "io" "log" "net/http" "strconv" oneM2M "meep-ipe/oneM2M" // utils "meep-ipe/utils" Loading @@ -21,7 +22,10 @@ func MecIotPltfNotificationHandler(w http.ResponseWriter, r *http.Request) { } log.Printf("Request Body: %s", string(body)) statusCode, respBody, err := oneM2M.CreateAE(body) rsc, statusCode, respBody, err := oneM2M.CreateAE(body) if rsc != 0 { w.Header().Set("X-M2M-RSC", strconv.Itoa(rsc)) } if err != nil { log.Printf("Error creating AE: %v", err) // Still relay whatever the CSE said, if we have anything Loading @@ -34,9 +38,9 @@ func MecIotPltfNotificationHandler(w http.ResponseWriter, r *http.Request) { return } log.Printf("Response from oneM2M: status %d, body: %s", statusCode, string(respBody)) log.Printf("Response from oneM2M: RSC %d, body: %s", rsc, string(respBody)) // Relay the CSE's actual status code and body back to the sandbox // Relay the CSE's RSC, status code and body back to the sandbox w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) w.Write(respBody) Loading go-apps/meep-ipe/config.env +7 −0 Changes for go-apps/meep-ipe/config.env: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -80,9 +80,16 @@ MEEP_CSE_NAME=laboai-cse-in # (or "S") per oneM2M originator rules. MEEP_LOCATION_NAME and # MEEP_SANDBOX_NAME are appended automatically, e.g. # CMecIPE -> CMecIPE-mep1-sbxoon0fww # Allowed characters: A-Z a-z 0-9 _ - # Default if empty: "CMecIPE" MEEP_AE_ID=CMecIPE # Set to "true" to append MEEP_LOCATION_NAME and MEEP_SANDBOX_NAME to # MEEP_CSE_ID and MEEP_CSE_NAME, matching meep-acme-mn-cse naming, e.g. # acme-mep-id-mn-cse -> acme-mep-id-mn-cse-mep1-sbxoon0fww # Empty parts are skipped. Default if empty: false (IDs used as-is). MEEP_INITIATED_MN_CSE=false # HTTP Basic auth credentials for the CSE. Leave both empty if the CSE has # no authorization enabled (no Authorization header is sent). MEEP_CSE_USER= Loading go-apps/meep-ipe/entrypoint.sh +10 −0 Changes for go-apps/meep-ipe/entrypoint.sh: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -117,6 +117,16 @@ if [ -z "${MEEP_AE_ID}" ]; then else AE_ID="${MEEP_AE_ID}" fi if [[ ! "${AE_ID}" =~ ^[A-Za-z0-9_-]+$ ]]; then echo "$0: MEEP_AE_ID '${AE_ID}' is invalid, only [A-Za-z0-9_-] is allowed" exit 1 fi # A standalone (outside sandbox) IPE must set its own base AE-ID; falling back to # the default would share node/subscription names with the in-sandbox IPE on the same CSE. if [ "${MEEP_STANDALONE}" == "true" ] && [ -z "${MEEP_AE_ID}" ]; then echo "$0: MEEP_STANDALONE=true requires MEEP_AE_ID to be set" exit 1 fi if [ -n "${MECPLATFORM}" ]; then AE_ID="${AE_ID}-${MECPLATFORM}" fi Loading go-apps/meep-ipe/oneM2M/createAE.go +19 −13 Changes for go-apps/meep-ipe/oneM2M/createAE.go: 19 added lines, 13 removed lines. Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ import ( "fmt" "io" "log" "net/http" "meep-ipe/utils" ) Loading Loading @@ -49,15 +48,17 @@ type outgoingAE struct { // CreateAE creates an Application Entity (AE) on the oneM2M platform, // using rn/api extracted from the incoming notification body. func CreateAE(body []byte) (int, []byte, error) { // It returns the oneM2M Response Status Code (X-M2M-RSC), the CSE's HTTP status // and the CSE response body. RSC 2001, 4105 and 4117 are treated as success. func CreateAE(body []byte) (int, int, []byte, error) { log.Println("Creating Application Entity (AE)...") var incoming incomingAE if err := json.Unmarshal(body, &incoming); err != nil { return 0, nil, fmt.Errorf("failed to parse incoming AE body: %w", err) return 0, 0, nil, fmt.Errorf("failed to parse incoming AE body: %w", err) } if incoming.M2MAE.RN == "" || incoming.M2MAE.API == "" { return 0, nil, fmt.Errorf("incoming body missing rn/api: %s", string(body)) return 0, 0, nil, fmt.Errorf("incoming body missing rn/api: %s", string(body)) } var outgoing outgoingAE Loading @@ -71,7 +72,7 @@ func CreateAE(body []byte) (int, []byte, error) { log.Printf("Config[MEC App name]: %+v", config["mecAppName"]) reqBodyBytes, err := json.Marshal(outgoing) if err != nil { return 0, nil, fmt.Errorf("failed to build outgoing AE body: %w", err) return 0, 0, nil, fmt.Errorf("failed to build outgoing AE body: %w", err) } reqBody := string(reqBodyBytes) Loading @@ -82,20 +83,25 @@ func CreateAE(body []byte) (int, []byte, error) { resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 2, config["AE-ID"].(string)) if err != nil { return 0, nil, err return 0, 0, nil, err } defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) log.Printf("Response from CSE: status %d, body: %s", resp.StatusCode, string(respBody)) rsc, err := responseRSC(resp) if err != nil { return 0, resp.StatusCode, respBody, fmt.Errorf("failed to create AE: %v, body: %s", err, string(respBody)) } log.Printf("Response from CSE: RSC %d, body: %s", rsc, string(respBody)) if resp.StatusCode == http.StatusCreated { if isCreateSuccess(rsc) { if rsc == RscCreated { log.Println("✓ Application Entity (AE) created successfully") return resp.StatusCode, respBody, nil } else if resp.StatusCode == http.StatusConflict || resp.StatusCode == http.StatusForbidden { log.Println("⚠ AE already exists") return 0, nil, fmt.Errorf("AE already exists") } else { log.Printf("⚠ AE already exists (RSC %d)", rsc) } return rsc, resp.StatusCode, respBody, nil } return 0, nil, fmt.Errorf("failed to create AE: status %d, body: %s", resp.StatusCode, string(respBody)) return rsc, resp.StatusCode, respBody, fmt.Errorf("failed to create AE: RSC %d, body: %s", rsc, string(respBody)) } Loading
go-apps/meep-ipe/MEC/init.go +3 −1 Changes for go-apps/meep-ipe/MEC/init.go: 3 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -446,6 +446,7 @@ func InitMEC(cfg map[string]interface{}) { // Step # 7: Create a Node on the oneM2M platform to represent the MEC IPE service // nodeName := "mec_ipe_node" nodeID := uuid.NewString() err = onem2m.CreateNode(onem2m.NodeName(), nodeID) if err != nil { log.Printf("Failed to create a Node on the oneM2M platform: %v", err) Loading Loading @@ -496,7 +497,8 @@ func InitMEC(cfg map[string]interface{}) { // -> Create a flex container for each service and publish it onto the CSE url = fmt.Sprintf("%s:%s/~/%s/%s", config["CSE-URL"], config["CSE-PORT"], config["CSE-ID"], config["CSE-NAME"]) for _, service := range responseData { containerName := fmt.Sprintf("%s-%s", service.SerName, config["sandboxName"]) // Containers live under this IPE's node, so the service name alone is unique containerName := service.SerName // Sent Get request to service endpoint fullUrl, err := fetchAndAppendHref(fmt.Sprintf("%suser-api/", service.TransportInfo.Endpoint.Uris[0])) if err != nil { Loading
go-apps/meep-ipe/MEC/mec_iot_pltf_notification.go +7 −3 Changes for go-apps/meep-ipe/MEC/mec_iot_pltf_notification.go: 7 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import ( "io" "log" "net/http" "strconv" oneM2M "meep-ipe/oneM2M" // utils "meep-ipe/utils" Loading @@ -21,7 +22,10 @@ func MecIotPltfNotificationHandler(w http.ResponseWriter, r *http.Request) { } log.Printf("Request Body: %s", string(body)) statusCode, respBody, err := oneM2M.CreateAE(body) rsc, statusCode, respBody, err := oneM2M.CreateAE(body) if rsc != 0 { w.Header().Set("X-M2M-RSC", strconv.Itoa(rsc)) } if err != nil { log.Printf("Error creating AE: %v", err) // Still relay whatever the CSE said, if we have anything Loading @@ -34,9 +38,9 @@ func MecIotPltfNotificationHandler(w http.ResponseWriter, r *http.Request) { return } log.Printf("Response from oneM2M: status %d, body: %s", statusCode, string(respBody)) log.Printf("Response from oneM2M: RSC %d, body: %s", rsc, string(respBody)) // Relay the CSE's actual status code and body back to the sandbox // Relay the CSE's RSC, status code and body back to the sandbox w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) w.Write(respBody) Loading
go-apps/meep-ipe/config.env +7 −0 Changes for go-apps/meep-ipe/config.env: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -80,9 +80,16 @@ MEEP_CSE_NAME=laboai-cse-in # (or "S") per oneM2M originator rules. MEEP_LOCATION_NAME and # MEEP_SANDBOX_NAME are appended automatically, e.g. # CMecIPE -> CMecIPE-mep1-sbxoon0fww # Allowed characters: A-Z a-z 0-9 _ - # Default if empty: "CMecIPE" MEEP_AE_ID=CMecIPE # Set to "true" to append MEEP_LOCATION_NAME and MEEP_SANDBOX_NAME to # MEEP_CSE_ID and MEEP_CSE_NAME, matching meep-acme-mn-cse naming, e.g. # acme-mep-id-mn-cse -> acme-mep-id-mn-cse-mep1-sbxoon0fww # Empty parts are skipped. Default if empty: false (IDs used as-is). MEEP_INITIATED_MN_CSE=false # HTTP Basic auth credentials for the CSE. Leave both empty if the CSE has # no authorization enabled (no Authorization header is sent). MEEP_CSE_USER= Loading
go-apps/meep-ipe/entrypoint.sh +10 −0 Changes for go-apps/meep-ipe/entrypoint.sh: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -117,6 +117,16 @@ if [ -z "${MEEP_AE_ID}" ]; then else AE_ID="${MEEP_AE_ID}" fi if [[ ! "${AE_ID}" =~ ^[A-Za-z0-9_-]+$ ]]; then echo "$0: MEEP_AE_ID '${AE_ID}' is invalid, only [A-Za-z0-9_-] is allowed" exit 1 fi # A standalone (outside sandbox) IPE must set its own base AE-ID; falling back to # the default would share node/subscription names with the in-sandbox IPE on the same CSE. if [ "${MEEP_STANDALONE}" == "true" ] && [ -z "${MEEP_AE_ID}" ]; then echo "$0: MEEP_STANDALONE=true requires MEEP_AE_ID to be set" exit 1 fi if [ -n "${MECPLATFORM}" ]; then AE_ID="${AE_ID}-${MECPLATFORM}" fi Loading
go-apps/meep-ipe/oneM2M/createAE.go +19 −13 Changes for go-apps/meep-ipe/oneM2M/createAE.go: 19 added lines, 13 removed lines. Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ import ( "fmt" "io" "log" "net/http" "meep-ipe/utils" ) Loading Loading @@ -49,15 +48,17 @@ type outgoingAE struct { // CreateAE creates an Application Entity (AE) on the oneM2M platform, // using rn/api extracted from the incoming notification body. func CreateAE(body []byte) (int, []byte, error) { // It returns the oneM2M Response Status Code (X-M2M-RSC), the CSE's HTTP status // and the CSE response body. RSC 2001, 4105 and 4117 are treated as success. func CreateAE(body []byte) (int, int, []byte, error) { log.Println("Creating Application Entity (AE)...") var incoming incomingAE if err := json.Unmarshal(body, &incoming); err != nil { return 0, nil, fmt.Errorf("failed to parse incoming AE body: %w", err) return 0, 0, nil, fmt.Errorf("failed to parse incoming AE body: %w", err) } if incoming.M2MAE.RN == "" || incoming.M2MAE.API == "" { return 0, nil, fmt.Errorf("incoming body missing rn/api: %s", string(body)) return 0, 0, nil, fmt.Errorf("incoming body missing rn/api: %s", string(body)) } var outgoing outgoingAE Loading @@ -71,7 +72,7 @@ func CreateAE(body []byte) (int, []byte, error) { log.Printf("Config[MEC App name]: %+v", config["mecAppName"]) reqBodyBytes, err := json.Marshal(outgoing) if err != nil { return 0, nil, fmt.Errorf("failed to build outgoing AE body: %w", err) return 0, 0, nil, fmt.Errorf("failed to build outgoing AE body: %w", err) } reqBody := string(reqBodyBytes) Loading @@ -82,20 +83,25 @@ func CreateAE(body []byte) (int, []byte, error) { resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 2, config["AE-ID"].(string)) if err != nil { return 0, nil, err return 0, 0, nil, err } defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) log.Printf("Response from CSE: status %d, body: %s", resp.StatusCode, string(respBody)) rsc, err := responseRSC(resp) if err != nil { return 0, resp.StatusCode, respBody, fmt.Errorf("failed to create AE: %v, body: %s", err, string(respBody)) } log.Printf("Response from CSE: RSC %d, body: %s", rsc, string(respBody)) if resp.StatusCode == http.StatusCreated { if isCreateSuccess(rsc) { if rsc == RscCreated { log.Println("✓ Application Entity (AE) created successfully") return resp.StatusCode, respBody, nil } else if resp.StatusCode == http.StatusConflict || resp.StatusCode == http.StatusForbidden { log.Println("⚠ AE already exists") return 0, nil, fmt.Errorf("AE already exists") } else { log.Printf("⚠ AE already exists (RSC %d)", rsc) } return rsc, resp.StatusCode, respBody, nil } return 0, nil, fmt.Errorf("failed to create AE: status %d, body: %s", resp.StatusCode, string(respBody)) return rsc, resp.StatusCode, respBody, fmt.Errorf("failed to create AE: RSC %d, body: %s", rsc, string(respBody)) }