diff --git a/examples/demo10/MEC/Get_App_Instances.go b/examples/demo10/MEC/Get_App_Instances.go new file mode 100644 index 0000000000000000000000000000000000000000..5a3f7dc79d166ce9e287082e804dc77179cc1edf --- /dev/null +++ b/examples/demo10/MEC/Get_App_Instances.go @@ -0,0 +1,35 @@ +package mec + +import ( + "fmt" + "net/http" + model "estimed_demo/Model" + utils "estimed_demo/utils" + "io" + "encoding/json" +) + +// Get MEC APP instances +func GetAppInstances(url string) ([]model.AppInstanceID, error) { + resp, err := utils.SendMECRequest("GET", url, nil) + if err != nil { + return nil, fmt.Errorf("failed to get MEC app instances: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to get MEC App Instance ID: received status code %d", resp.StatusCode) + } + + // From the response body, extract all App Instance IDs + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %v", err) + } + //log.Println("Response body:", string(body)) + + var allAppInstances []model.AppInstanceID + if err := json.Unmarshal(body, &allAppInstances); err != nil { + return nil, fmt.Errorf("failed to unmarshal response body: %v", err) + } + return allAppInstances, nil +} \ No newline at end of file diff --git a/examples/demo10/MEC/ams.go b/examples/demo10/MEC/ams.go new file mode 100644 index 0000000000000000000000000000000000000000..d12de37a36d8af0b0298c57e500b10cdc0552145 --- /dev/null +++ b/examples/demo10/MEC/ams.go @@ -0,0 +1,337 @@ +package mec + +import ( + "encoding/json" + model "estimed_demo/Model" + utils "estimed_demo/utils" + "fmt" + "log" + "net/http" + "regexp" +) + +// Create MEC AMS service registration +func CreateAMSRegistration(url string, app_instance_id string, device_info *model.RegistrationInfoDeviceInformation) (*model.RegistrationInfo, error) { + payload := &model.RegistrationInfo{} + if device_info != nil { + payload = &model.RegistrationInfo{ + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: app_instance_id, + }, + DeviceInformation: []model.RegistrationInfoDeviceInformation{*device_info}, + } + } else { + payload = &model.RegistrationInfo{ + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: app_instance_id, + }, + } + } + resp, err := utils.SendMECRequest("POST", url, payload) + if err != nil { + return nil, fmt.Errorf("failed to create AMS registration: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusCreated { + return nil, fmt.Errorf("failed to create AMS registration: received status code %d", resp.StatusCode) + } + + var registrationInfo model.RegistrationInfo + if err := json.NewDecoder(resp.Body).Decode(®istrationInfo); err != nil { + return nil, fmt.Errorf("failed to decode AMS registration response: %v", err) + } + + return ®istrationInfo, nil +} + +// Create MEC AMS subscription + +func CreateAMSSubscription(url string, app_instance_id string, callbackURL string, associateId *model.AssociateId) (*model.InlineSubscription, error) { + payload := &model.InlineSubscription{} + if associateId != nil { + payload = &model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: app_instance_id, + AssociateId: []model.AssociateId{*associateId}, + }, + CallbackReference: callbackURL, + } + } else { + payload = &model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: app_instance_id, + }, + // TODO: Update callback reference URL as needed + CallbackReference: callbackURL, + } + } + + resp, err := utils.SendMECRequest("POST", url, payload) + if err != nil { + return nil, fmt.Errorf("failed to create AMS subscription: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusCreated { + return nil, fmt.Errorf("failed to create AMS subscription: received status code %d", resp.StatusCode) + } + + var subscriptionInfo model.InlineSubscription + if err := json.NewDecoder(resp.Body).Decode(&subscriptionInfo); err != nil { + return nil, fmt.Errorf("failed to decode AMS subscription response: %v", err) + } + + return &subscriptionInfo, nil +} + +// AMSNotificationHandler handles incoming AMS notifications +func AMSNotificationHandler(w http.ResponseWriter, r *http.Request) (string, error) { + if r.Method != http.MethodPost { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + return "", fmt.Errorf("invalid request method") + } + + var notification map[string]interface{} + err := json.NewDecoder(r.Body).Decode(¬ification) + if err != nil { + http.Error(w, "Failed to decode request body", http.StatusBadRequest) + return "", fmt.Errorf("failed to decode request body: %w", err) + } + log.Printf("Received AMS notification: %+v", notification) + w.WriteHeader(http.StatusNoContent) + // Extract target app instance ID from the notification + var targetAppInstanceID string + if targetAppInfo, ok := notification["targetAppInfo"].(map[string]interface{}); ok { + if appInstanceID, ok := targetAppInfo["appInstanceId"].(string); ok { + targetAppInstanceID = appInstanceID + log.Printf("Target App Instance ID: %s", targetAppInstanceID) + } + } + if targetAppInstanceID == "" { + log.Println("Target App Instance ID not found in notification") + } + return targetAppInstanceID, nil +} + +func RegistrationAndSubscriptionHandler(matchingAppInstances []model.AppInstanceID, platformURL string, + sandbox_name string, callbackURL string, currentAppInstanceId *string, + deviceInfo *model.RegistrationInfoDeviceInformation, associateId *model.AssociateId) ([]map[string]model.PlatformInfo, error) { + var platformDetails []map[string]model.PlatformInfo + + for i, appInstance := range matchingAppInstances { + log.Printf("Creating AMS registration for App Instance ID: %s, Name: %s", appInstance.ID, appInstance.Name) + amsURL := fmt.Sprintf("%s/%s/mep1/amsi/v1/app_mobility_services", platformURL, sandbox_name) + var resp *model.RegistrationInfo + var err error + if i == 0 { + *currentAppInstanceId = appInstance.ID + resp, err = CreateAMSRegistration(amsURL, appInstance.ID, deviceInfo) + if err != nil { + return nil, fmt.Errorf("failed to create AMS registration: %v", err) + } else { + log.Printf("AMS registration created successfully: %v", resp) + } + } else { + resp, err = CreateAMSRegistration(amsURL, appInstance.ID, nil) + if err != nil { + return nil, fmt.Errorf("failed to create AMS registration: %v", err) + } else { + log.Printf("AMS registration created successfully: %v", resp) + } + } + amsSubURL := fmt.Sprintf("%s/%s/mep1/amsi/v1/subscriptions", platformURL, sandbox_name) + sub_resp := &model.InlineSubscription{} + if i == 0 { + sub_resp, err = CreateAMSSubscription(amsSubURL, appInstance.ID, callbackURL, associateId) + if err != nil { + return nil, fmt.Errorf("failed to create AMS subscription: %v", err) + } else { + log.Printf("AMS subscription created successfully: %v", sub_resp) + } + } else { + sub_resp, err = CreateAMSSubscription(amsSubURL, appInstance.ID, callbackURL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create AMS subscription: %v", err) + } else { + log.Printf("AMS subscription created successfully: %v", sub_resp) + } + } + // Extract subscription ID from href using regex + subID := "" + if sub_resp.Links.Self.Href != "" { + re := regexp.MustCompile(`subscriptions/(.*)`) + matches := re.FindStringSubmatch(sub_resp.Links.Self.Href) + if len(matches) > 1 { + subID = matches[1] + } + } + platformInfo := model.PlatformInfo{ + AmsServiceID: resp.AppMobilityServiceId, + AppInstanceID: appInstance.ID, + AmsSubscriptionID: subID, + NodeName: appInstance.NodeName, + } + platformDetails = append(platformDetails, map[string]model.PlatformInfo{ + appInstance.ID: platformInfo, + }) + } + + return platformDetails, nil +} + +// TODO: Complete the function to update AMS registration info +func PutAMSRegistrationInfo(url string, targetappinstance string, platformDetails []map[string]model.PlatformInfo, + current_app_instance *string, associateID *model.AssociateId) error { + if len(platformDetails) == 0 { + return fmt.Errorf("platformDetails is empty") + } + if targetappinstance == "" { + log.Println("Initializing AMS registration info...") + } + + // Find the PlatformInfo for the current app instance by iterating through the slice + var currentPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[*current_app_instance]; exists { + currentPlatformInfo = &info + break // Found it, no need to continue + } + } + payload := model.RegistrationInfo{ + AppMobilityServiceId: currentPlatformInfo.AmsServiceID, + DeviceInformation: []model.RegistrationInfoDeviceInformation{ + { + AssociateId: associateID, + AppMobilityServiceLevel: &[]model.AppMobilityServiceLevel{"APP_MOBILITY_WITHOUT_CONFIRMATION"}[0], + ContextTransferState: &[]model.ContextTransferState{"USER_CONTEXT_TRANSFER_COMPLETED"}[0], + }, + }, + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: *current_app_instance, + }, + } + req_url := fmt.Sprintf("%s/%s", url, currentPlatformInfo.AmsServiceID) + resp, err := utils.SendMECRequest("PUT", req_url, payload) + if err != nil { + return fmt.Errorf("failed to update AMS registration info: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS registration info: received status code %d", resp.StatusCode) + } + log.Println("AMS registration info updated successfully") + + // find the PlatformInfo for the target app instance + var targetPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[targetappinstance]; exists { + targetPlatformInfo = &info + break // Found it, no need to continue + } + } + payload = model.RegistrationInfo{ + AppMobilityServiceId: targetPlatformInfo.AmsServiceID, + DeviceInformation: []model.RegistrationInfoDeviceInformation{ + { + AssociateId: associateID, + AppMobilityServiceLevel: &[]model.AppMobilityServiceLevel{"APP_MOBILITY_WITHOUT_CONFIRMATION"}[0], + ContextTransferState: &[]model.ContextTransferState{"NOT_TRANSFERRED"}[0], + }, + }, + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: targetappinstance, + }, + } + req_url = fmt.Sprintf("%s/%s", url, targetPlatformInfo.AmsServiceID) + resp, err = utils.SendMECRequest("PUT", req_url, payload) + if err != nil { + return fmt.Errorf("failed to update AMS registration info for target app instance: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS registration info for target app instance: received status code %d", resp.StatusCode) + } + + log.Println("AMS registration info for target app instance updated successfully") + + return nil +} + +func PUTAMSSubscriptionInfo(url string, targetappinstance string, platformDetails []map[string]model.PlatformInfo, + current_app_instance *string, call_back_url string, associateid *model.AssociateId) error { + if len(platformDetails) == 0 { + return fmt.Errorf("platformDetails is empty") + } + if targetappinstance == "" { + log.Println("Initializing AMS subscription info...") + } + + // Find the PlatformInfo for the current app instance by iterating through the slice + var currentPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[*current_app_instance]; exists { + currentPlatformInfo = &info + break // Found it, no need to continue + } + } + + payload := model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + Links: &model.MobilityProcedureSubscriptionLinks{ + Self: &model.LinkType{ + Href: fmt.Sprintf("%s/%s", url, currentPlatformInfo.AmsSubscriptionID), + }, + }, + CallbackReference: call_back_url, + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: *current_app_instance, + AssociateId: []model.AssociateId{*associateid}, + MobilityStatus: []model.MobilityStatus{"INTERHOST_MOVEOUT_COMPLETED"}, + }, + } + resp, err := utils.SendMECRequest("PUT", fmt.Sprintf("%s/%s", url, currentPlatformInfo.AmsSubscriptionID), payload) + if err != nil { + return fmt.Errorf("failed to update AMS subscription info: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS subscription info: received status code %d", resp.StatusCode) + } + log.Println("AMS subscription info updated successfully") + + // find the PlatformInfo for the target app instance + var targetPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[targetappinstance]; exists { + targetPlatformInfo = &info + break // Found it, no need to continue + } + } + + payload = model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + Links: &model.MobilityProcedureSubscriptionLinks{ + Self: &model.LinkType{ + Href: fmt.Sprintf("%s/%s", url, targetPlatformInfo.AmsSubscriptionID), + }, + }, + CallbackReference: call_back_url, + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: targetappinstance, + AssociateId: []model.AssociateId{*associateid}, + MobilityStatus: []model.MobilityStatus{"INTERHOST_MOVEOUT_TRIGGERED"}, + }, + } + resp, err = utils.SendMECRequest("PUT", fmt.Sprintf("%s/%s", url, targetPlatformInfo.AmsSubscriptionID), payload) + if err != nil { + return fmt.Errorf("failed to update AMS subscription info for target app instance: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS subscription info for target app instance: received status code %d", resp.StatusCode) + } + + log.Println("AMS subscription info for target app instance updated successfully") + return nil +} diff --git a/examples/demo10/MEC/iot_api.go b/examples/demo10/MEC/iot_api.go new file mode 100644 index 0000000000000000000000000000000000000000..f643a703b3ec16b8b8a5b46cb24cff1446eb80e7 --- /dev/null +++ b/examples/demo10/MEC/iot_api.go @@ -0,0 +1,26 @@ +package mec + +import ( + "encoding/json" + utils "estimed_demo/utils" + "fmt" + "net/http" +) + +// Fetch for platform info +func GETIotPlatformInfo(url string) ([]map[string]interface{}, error) { + resp, err := utils.SendMECRequest("GET", url, nil) + if err != nil { + return nil, fmt.Errorf("failed to get IoT platform info: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to get IoT platform info: received status code %d", resp.StatusCode) + } + + var platformInfo []map[string]interface{} + if err := json.NewDecoder(resp.Body).Decode(&platformInfo); err != nil { + return nil, fmt.Errorf("failed to decode IoT platform info: %v", err) + } + return platformInfo, nil +} \ No newline at end of file diff --git a/examples/demo10/MEC/match_for_target_app_instance.go b/examples/demo10/MEC/match_for_target_app_instance.go new file mode 100644 index 0000000000000000000000000000000000000000..76576432f721d817064aed876a63a3ace446db14 --- /dev/null +++ b/examples/demo10/MEC/match_for_target_app_instance.go @@ -0,0 +1,33 @@ +package mec + +import ( + model "estimed_demo/Model" + "fmt" + "regexp" +) + +// Match for target App Instance ID +func MatchForTargetAppInstance(allAppInstances []model.AppInstanceID, cse_name string) ([]model.AppInstanceID, error) { + // Compile regex for cse_name once + reCSE, err := regexp.Compile(cse_name) + if err != nil { + return nil, fmt.Errorf("invalid regex for cse_name: %v", err) + } + var matchingAppInstances []model.AppInstanceID + for _, appInstance := range allAppInstances { + // If name matches cse_name using compiled regex, store it in our array + if reCSE.MatchString(appInstance.Name) { + matchingAppInstance := model.AppInstanceID{ + ID: appInstance.ID, + Name: appInstance.Name, + NodeName: appInstance.NodeName, + } + matchingAppInstances = append(matchingAppInstances, matchingAppInstance) + } + } + + if len(matchingAppInstances) == 0 { + return nil, fmt.Errorf("MEC App Instance with name %s not found", cse_name) + } + return matchingAppInstances, nil +} diff --git a/examples/demo10/Model/app_instance_id.go b/examples/demo10/Model/app_instance_id.go new file mode 100644 index 0000000000000000000000000000000000000000..713464f213f0ce9b3f686ad73bc3190b585d0c2b --- /dev/null +++ b/examples/demo10/Model/app_instance_id.go @@ -0,0 +1,7 @@ +package model + +type AppInstanceID struct { + ID string `json:"id"` + Name string `json:"name"` + NodeName string `json:"nodeName"` +} \ No newline at end of file diff --git a/examples/demo10/Model/model_adjacent_app_info_notification.go b/examples/demo10/Model/model_adjacent_app_info_notification.go new file mode 100644 index 0000000000000000000000000000000000000000..2e50f57819883f614dba527285d6a1e1500517ad --- /dev/null +++ b/examples/demo10/Model/model_adjacent_app_info_notification.go @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type AdjacentAppInfoNotification struct {
+ // Shall be set to \"AdjacentAppInfoNotification\".
+ NotificationType string `json:"notificationType"`
+ TimeStamp *TimeStamp `json:"timeStamp,omitempty"`
+ // 1 to N identifiers to associate the information for specific
+ AssociateId []AssociateId `json:"associateId,omitempty"`
+ AdjacentAppInfo []AdjacentAppInfoNotificationAdjacentAppInfo `json:"adjacentAppInfo,omitempty"`
+ Links *Link `json:"_links"`
+}
diff --git a/examples/demo10/Model/model_adjacent_app_info_notification_adjacent_app_info.go b/examples/demo10/Model/model_adjacent_app_info_notification_adjacent_app_info.go
new file mode 100644
index 0000000000000000000000000000000000000000..c3e710bdddf2644cc78baebbcc26626066af6810
--- /dev/null
+++ b/examples/demo10/Model/model_adjacent_app_info_notification_adjacent_app_info.go
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type AdjacentAppInfoNotificationAdjacentAppInfo struct {
+ // Identifier of the adjacent application instance.
+ AppInstanceId string `json:"appInstanceId"`
+ // If present, it represents the communication interface(s) information of the application instance.
+ CommInterface []CommunicationInterface `json:"commInterface"`
+}
diff --git a/examples/demo10/Model/model_adjacent_app_info_subscription.go b/examples/demo10/Model/model_adjacent_app_info_subscription.go
new file mode 100644
index 0000000000000000000000000000000000000000..9c502c972ae637a825cdab3d11a7758d5cea0c09
--- /dev/null
+++ b/examples/demo10/Model/model_adjacent_app_info_subscription.go
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type AdjacentAppInfoSubscription struct {
+ Links *AdjacentAppInfoSubscriptionLinks `json:"_links,omitempty"`
+ // URI selected by the service consumer to receive notifications on the subscribed Application Mobility Service. This shall be included both in the request and in response.
+ CallbackReference string `json:"callbackReference"`
+ // Shall be set to TRUE by the service consumer to request a test notification via HTTP on the callbackReference URI, specified in ETSI GS MEC 009, as described in clause 6.12a.
+ RequestTestNotification bool `json:"requestTestNotification,omitempty"`
+ WebsockNotifConfig *WebsockNotifConfig `json:"websockNotifConfig,omitempty"`
+ ExpiryDeadline *TimeStamp `json:"expiryDeadline,omitempty"`
+ FilterCriteria *AdjacentAppInfoSubscriptionFilterCriteria `json:"filterCriteria"`
+ SubscriptionType *SubscriptionType `json:"subscriptionType"`
+}
diff --git a/examples/demo10/Model/model_adjacent_app_info_subscription_filter_criteria.go b/examples/demo10/Model/model_adjacent_app_info_subscription_filter_criteria.go
new file mode 100644
index 0000000000000000000000000000000000000000..63c6ff0906969180f9722fab38899c600c183e96
--- /dev/null
+++ b/examples/demo10/Model/model_adjacent_app_info_subscription_filter_criteria.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// List of filtering criteria for the subscription. Any filtering criteria from below, which is included in the request, shall also be included in the response.
+type AdjacentAppInfoSubscriptionFilterCriteria struct {
+ AppInstanceId string `json:"appInstanceId,omitempty"`
+}
diff --git a/examples/demo10/Model/model_adjacent_app_info_subscription_links.go b/examples/demo10/Model/model_adjacent_app_info_subscription_links.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c0a382969c2a83cb09b8f1d8dd645e1dff96b19
--- /dev/null
+++ b/examples/demo10/Model/model_adjacent_app_info_subscription_links.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// Hyperlink related to the resource. This shall be only included in the HTTP responses and in HTTP PUT requests.
+type AdjacentAppInfoSubscriptionLinks struct {
+ Self *LinkType `json:"self"`
+}
diff --git a/examples/demo10/Model/model_adjacent_app_instance_info.go b/examples/demo10/Model/model_adjacent_app_instance_info.go
new file mode 100644
index 0000000000000000000000000000000000000000..13366bad1f5d0d0280a2b7a763a3528ab888e3dc
--- /dev/null
+++ b/examples/demo10/Model/model_adjacent_app_instance_info.go
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type AdjacentAppInstanceInfo struct {
+ // Identifier of the application descriptor.
+ AppDId string `json:"appDId"`
+ // It specifies the communication interface of application instance.
+ AppInstanceCommLink []CommunicationInterface `json:"appInstanceCommLink"`
+ // Identifier of the application instance.
+ AppInstanceId string `json:"appInstanceId"`
+ MecHostInformation *MecHostInformation `json:"mecHostInformation,omitempty"`
+ // dentifier of the application instance that registers to the AMS, which is instantiated from the application descriptor identified by the attribute \"appDId\".
+ RegisteredInstanceId string `json:"registeredInstanceId,omitempty"`
+}
diff --git a/examples/demo10/Model/model_app_mobility_service_level.go b/examples/demo10/Model/model_app_mobility_service_level.go
new file mode 100644
index 0000000000000000000000000000000000000000..12e07a763acd017bb506886c44828854c8b2f352
--- /dev/null
+++ b/examples/demo10/Model/model_app_mobility_service_level.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// AppMobilityServiceLevel : This attribute provides an option for the application instance (server) to communicate with the application client before relocating this application instance to another MEC host.
+type AppMobilityServiceLevel string
+
+// List of AppMobilityServiceLevel
+const (
+ NOT_ALLOWED_AppMobilityServiceLevel AppMobilityServiceLevel = "APP_MOBILITY_NOT_ALLOWED"
+ WITH_CONFIRMATION_AppMobilityServiceLevel AppMobilityServiceLevel = "APP_MOBILITY_WITH_CONFIRMATION"
+ WITHOUT_CONFIRMATION_AppMobilityServiceLevel AppMobilityServiceLevel = "APP_MOBILITY_WITHOUT_CONFIRMATION"
+)
diff --git a/examples/demo10/Model/model_app_termination_notification.go b/examples/demo10/Model/model_app_termination_notification.go
new file mode 100644
index 0000000000000000000000000000000000000000..c6e436e10646bec60e6ee07000a2303071f020df
--- /dev/null
+++ b/examples/demo10/Model/model_app_termination_notification.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// This type represents the information that the MEC platform notifies the subscribed application instance about the corresponding application instance termination/stop.
+type AppTerminationNotification struct {
+ // Shall be set to AppTerminationNotification.
+ NotificationType string `json:"notificationType"`
+ OperationAction *OperationActionType `json:"operationAction"`
+ // Maximum timeout value in seconds for graceful termination or graceful stop of an application instance.
+ MaxGracefulTimeout int32 `json:"maxGracefulTimeout"`
+ Links *AppTerminationNotificationLinks `json:"_links"`
+}
diff --git a/examples/demo10/Model/model_app_termination_notification__links.go b/examples/demo10/Model/model_app_termination_notification__links.go
new file mode 100644
index 0000000000000000000000000000000000000000..74d1af76fdc39bf9ab6d9ca6fd570c342e160122
--- /dev/null
+++ b/examples/demo10/Model/model_app_termination_notification__links.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type AppTerminationNotificationLinks struct {
+ Subscription *LinkType `json:"subscription"`
+ ConfirmTermination *LinkType `json:"confirmTermination,omitempty"`
+}
diff --git a/examples/demo10/Model/model_associate_id.go b/examples/demo10/Model/model_associate_id.go
new file mode 100644
index 0000000000000000000000000000000000000000..cfa501c9477e85514e0449ade4cce762a8b2e2bc
--- /dev/null
+++ b/examples/demo10/Model/model_associate_id.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type AssociateId struct {
+ Type_ *AssociateIdType `json:"type,omitempty"`
+ // Value for the identifier.
+ Value string `json:"value,omitempty"`
+}
diff --git a/examples/demo10/Model/model_associate_id_type.go b/examples/demo10/Model/model_associate_id_type.go
new file mode 100644
index 0000000000000000000000000000000000000000..82d58b758444bce89b9a0ba121cc5e1de480a500
--- /dev/null
+++ b/examples/demo10/Model/model_associate_id_type.go
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// AssociateIdType : Numeric value (0-255) corresponding to specified type of identifier
+type AssociateIdType string
+
+// List of AssociateIdType
+const (
+ UE_I_PV4_ADDRESS_AssociateIdType AssociateIdType = "UE_IPv4_ADDRESS"
+ UE_IPV6_ADDRESS_AssociateIdType AssociateIdType = "UE_IPV6_ADDRESS"
+ NATED_IP_ADDRESS_AssociateIdType AssociateIdType = "NATED_IP_ADDRESS"
+ GTP_TEID_AssociateIdType AssociateIdType = "GTP_TEID"
+)
diff --git a/examples/demo10/Model/model_communication_interface.go b/examples/demo10/Model/model_communication_interface.go
new file mode 100644
index 0000000000000000000000000000000000000000..524da89f6cc8001fc98df34acd12aba7e95326b5
--- /dev/null
+++ b/examples/demo10/Model/model_communication_interface.go
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type CommunicationInterface struct {
+ IpAddresses []CommunicationInterfaceIpAddresses `json:"ipAddresses,omitempty"`
+}
diff --git a/examples/demo10/Model/model_communication_interface_ip_addresses.go b/examples/demo10/Model/model_communication_interface_ip_addresses.go
new file mode 100644
index 0000000000000000000000000000000000000000..cdde1a17999152cfc741dc8e374b9f29fc6a04d3
--- /dev/null
+++ b/examples/demo10/Model/model_communication_interface_ip_addresses.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type CommunicationInterfaceIpAddresses struct {
+ Host string `json:"host"`
+ Port int32 `json:"port"`
+}
diff --git a/examples/demo10/Model/model_context_transfer_state.go b/examples/demo10/Model/model_context_transfer_state.go
new file mode 100644
index 0000000000000000000000000000000000000000..8f0b7ccad373ce8a816865bff2206f4cdc15e889
--- /dev/null
+++ b/examples/demo10/Model/model_context_transfer_state.go
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// ContextTransferState : If present, it represents the state of transferring the user context to another application instance.
+type ContextTransferState string
+
+// List of ContextTransferState
+const (
+ NOT_TRANSFERRED_ContextTransferState ContextTransferState = "NOT_TRANSFERRED"
+ USER_CONTEXT_TRANSFER_COMPLETED_ContextTransferState ContextTransferState = "USER_CONTEXT_TRANSFER_COMPLETED"
+)
diff --git a/examples/demo10/Model/model_expiry_notification.go b/examples/demo10/Model/model_expiry_notification.go
new file mode 100644
index 0000000000000000000000000000000000000000..99d86842e6aa15131f86e58b1eb0604b603fd701
--- /dev/null
+++ b/examples/demo10/Model/model_expiry_notification.go
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type ExpiryNotification struct {
+ // Shall be set to \"ExpiryNotification\".
+ NotificationType string `json:"notificationType"`
+ TimeStamp *TimeStamp `json:"timeStamp,omitempty"`
+ Links *Link `json:"_links"`
+ ExpiryDeadline *TimeStamp `json:"expiryDeadline"`
+}
diff --git a/examples/demo10/Model/model_inline_notification.go b/examples/demo10/Model/model_inline_notification.go
new file mode 100644
index 0000000000000000000000000000000000000000..8c5b31de0c90a7daee11c80ebf73ab486972064c
--- /dev/null
+++ b/examples/demo10/Model/model_inline_notification.go
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type InlineNotification struct {
+ // Not used in client
+}
diff --git a/examples/demo10/Model/model_inline_subscription.go b/examples/demo10/Model/model_inline_subscription.go
new file mode 100644
index 0000000000000000000000000000000000000000..12296a6f08d61287935026afe4399ee08fc4d5fa
--- /dev/null
+++ b/examples/demo10/Model/model_inline_subscription.go
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type InlineSubscription struct {
+ /* Discriminator */
+ SubscriptionType string `json:"subscriptionType"`
+
+ /* Common */
+ Links *MobilityProcedureSubscriptionLinks `json:"_links,omitempty"`
+ CallbackReference string `json:"callbackReference"`
+ RequestTestNotification bool `json:"requestTestNotification,omitempty"`
+ WebsockNotifConfig *WebsockNotifConfig `json:"websockNotifConfig,omitempty"`
+ ExpiryDeadline *TimeStamp `json:"expiryDeadline,omitempty"`
+
+ /* MobilityProcedureSubscription */
+ FilterCriteria *MobilityProcedureSubscriptionFilterCriteria `json:"filterCriteria"`
+
+ /* AdjacentAppInfoSubscription */
+ // NOTE: to avoid json parameter conflict, use superset filterCriteria from MobilityProcedure
+ // FilterCriteria *AdjacentAppInfoSubscriptionFilterCriteria `json:"filterCriteria"`
+}
diff --git a/examples/demo10/Model/model_link.go b/examples/demo10/Model/model_link.go
new file mode 100644
index 0000000000000000000000000000000000000000..656146a5cd8284bd94d530ee711d774898d6b73f
--- /dev/null
+++ b/examples/demo10/Model/model_link.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// Object containing hyperlinks related to the resource.
+type Link struct {
+ Subscription *LinkType `json:"subscription"`
+}
diff --git a/examples/demo10/Model/model_link_type.go b/examples/demo10/Model/model_link_type.go
new file mode 100644
index 0000000000000000000000000000000000000000..d9471e2272e71c82d57a4e2b64a9c4fc91141209
--- /dev/null
+++ b/examples/demo10/Model/model_link_type.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// 'This data type represents a type of link'
+type LinkType struct {
+ // The URI referring to the subscription.
+ Href string `json:"href"`
+}
diff --git a/examples/demo10/Model/model_mec_host_information.go b/examples/demo10/Model/model_mec_host_information.go
new file mode 100644
index 0000000000000000000000000000000000000000..b36a4c43589c7c436ca6d576cf31b408c4686c58
--- /dev/null
+++ b/examples/demo10/Model/model_mec_host_information.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type MecHostInformation struct {
+ // Human-readable name of MEC host.
+ HostName string `json:"hostName,omitempty"`
+ HostId *map[string]interface{} `json:"hostId"`
+}
diff --git a/examples/demo10/Model/model_mobility_procedure_notification.go b/examples/demo10/Model/model_mobility_procedure_notification.go
new file mode 100644
index 0000000000000000000000000000000000000000..c2c4a247120b825c1b3b2b0260638c262202b3dd
--- /dev/null
+++ b/examples/demo10/Model/model_mobility_procedure_notification.go
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type MobilityProcedureNotification struct {
+ // Shall be set to \"MobilityProcedureNotification\".
+ NotificationType string `json:"notificationType"`
+ TimeStamp *TimeStamp `json:"timeStamp,omitempty"`
+ // 1 to N identifiers to associate the information for specific
+ AssociateId []AssociateId `json:"associateId"`
+ MobilityStatus *MobilityStatus `json:"mobilityStatus"`
+ TargetAppInfo *MobilityProcedureNotificationTargetAppInfo `json:"targetAppInfo,omitempty"`
+ Links *Link `json:"_links"`
+}
diff --git a/examples/demo10/Model/model_mobility_procedure_notification_target_app_info.go b/examples/demo10/Model/model_mobility_procedure_notification_target_app_info.go
new file mode 100644
index 0000000000000000000000000000000000000000..6630bfe1ccb02dad443769e6e09469678c968347
--- /dev/null
+++ b/examples/demo10/Model/model_mobility_procedure_notification_target_app_info.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type MobilityProcedureNotificationTargetAppInfo struct {
+ // Identifiers of the target application instance.
+ AppInstanceId string `json:"appInstanceId"`
+ CommInterface *CommunicationInterface `json:"commInterface,omitempty"`
+}
diff --git a/examples/demo10/Model/model_mobility_procedure_subscription.go b/examples/demo10/Model/model_mobility_procedure_subscription.go
new file mode 100644
index 0000000000000000000000000000000000000000..c36b0b3a6505555000b5a2c99a63d158b92892cb
--- /dev/null
+++ b/examples/demo10/Model/model_mobility_procedure_subscription.go
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type MobilityProcedureSubscription struct {
+ Links *MobilityProcedureSubscriptionLinks `json:"_links,omitempty"`
+ // URI selected by the service consumer to receive notifications on the subscribed Application Mobility Service. This shall be included both in the request and in response.
+ CallbackReference string `json:"callbackReference,omitempty"`
+ // Shall be set to TRUE by the service consumer to request a test notification via HTTP on the callbackReference URI, specified in ETSI GS MEC 009, as described in clause 6.12a.
+ RequestTestNotification bool `json:"requestTestNotification,omitempty"`
+ WebsockNotifConfig *WebsockNotifConfig `json:"websockNotifConfig,omitempty"`
+ ExpiryDeadline *TimeStamp `json:"expiryDeadline,omitempty"`
+ FilterCriteria *MobilityProcedureSubscriptionFilterCriteria `json:"filterCriteria"`
+ SubscriptionType *SubscriptionType `json:"subscriptionType"`
+}
diff --git a/examples/demo10/Model/model_mobility_procedure_subscription_filter_criteria.go b/examples/demo10/Model/model_mobility_procedure_subscription_filter_criteria.go
new file mode 100644
index 0000000000000000000000000000000000000000..16e7ce163ff401ab9f9f77aee0451358af5dc0a8
--- /dev/null
+++ b/examples/demo10/Model/model_mobility_procedure_subscription_filter_criteria.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// List of filtering criteria for the subscription. Any filtering criteria from below, which is included in the request, shall also be included in the response.
+type MobilityProcedureSubscriptionFilterCriteria struct {
+ // Identifier of the application instance that registers the Application Mobility Service.
+ AppInstanceId string `json:"appInstanceId,omitempty"`
+ // 0 to N identifiers to associate the information for specific UE(s) and flow(s).
+ AssociateId []AssociateId `json:"associateId,omitempty"`
+ // In case mobilityStatus is not included in the subscription request, the default value 1 = INTER_HOST_MOBILITY_TRIGGERED shall be used and included in the response.
+ MobilityStatus []MobilityStatus `json:"mobilityStatus,omitempty"`
+}
diff --git a/examples/demo10/Model/model_mobility_procedure_subscription_links.go b/examples/demo10/Model/model_mobility_procedure_subscription_links.go
new file mode 100644
index 0000000000000000000000000000000000000000..937f5450c3d67eff2f6a3d410cec7a6c9ac2296b
--- /dev/null
+++ b/examples/demo10/Model/model_mobility_procedure_subscription_links.go
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type MobilityProcedureSubscriptionLinks struct {
+ Self *LinkType `json:"self"`
+}
diff --git a/examples/demo10/Model/model_mobility_status.go b/examples/demo10/Model/model_mobility_status.go
new file mode 100644
index 0000000000000000000000000000000000000000..a8b628691f1148df9fc71d4ecd76ec3d9a65fc60
--- /dev/null
+++ b/examples/demo10/Model/model_mobility_status.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// MobilityStatus : Indicate the status of the UE mobility
+type MobilityStatus string
+
+// List of MobilityStatus
+const (
+ TRIGGERED_MobilityStatus MobilityStatus = "INTERHOST_MOVEOUT_TRIGGERED"
+ COMPLETED_MobilityStatus MobilityStatus = "INTERHOST_MOVEOUT_COMPLETED"
+ FAILED_MobilityStatus MobilityStatus = "INTERHOST_MOVEOUT_FAILED"
+)
diff --git a/examples/demo10/Model/model_one_of_inline_notification.go b/examples/demo10/Model/model_one_of_inline_notification.go
new file mode 100644
index 0000000000000000000000000000000000000000..49ae7e4f9cc210a647dcc4647863e803ee85ead8
--- /dev/null
+++ b/examples/demo10/Model/model_one_of_inline_notification.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type OneOfInlineNotification struct {
+ /* Discriminator */
+ NotificationType string `json:"notificationType"`
+}
diff --git a/examples/demo10/Model/model_one_of_inline_subscription.go b/examples/demo10/Model/model_one_of_inline_subscription.go
new file mode 100644
index 0000000000000000000000000000000000000000..2c68e86a9a7eb55c275cab2d5e9e92e9d56c2dda
--- /dev/null
+++ b/examples/demo10/Model/model_one_of_inline_subscription.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type OneOfInlineSubscription struct {
+ /* Discriminator */
+ SubscriptionType string `json:"subscriptionType"`
+}
diff --git a/examples/demo10/Model/model_operation_action_type.go b/examples/demo10/Model/model_operation_action_type.go
new file mode 100644
index 0000000000000000000000000000000000000000..d934d5fc4cabb4f53114d5274398d7aabceca97f
--- /dev/null
+++ b/examples/demo10/Model/model_operation_action_type.go
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// OperationActionType : Operation that is being performed on the MEC application instance.
+type OperationActionType string
+
+// List of OperationActionType
+const (
+ STOPPING_OperationActionType OperationActionType = "STOPPING"
+ TERMINATING_OperationActionType OperationActionType = "TERMINATING"
+)
diff --git a/examples/demo10/Model/model_problem_details.go b/examples/demo10/Model/model_problem_details.go
new file mode 100644
index 0000000000000000000000000000000000000000..7d55968705472d6f956e0ff53f83569550632356
--- /dev/null
+++ b/examples/demo10/Model/model_problem_details.go
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type ProblemDetails struct {
+ // A human-readable explanation specific to this occurrence of the problem
+ Detail string `json:"detail,omitempty"`
+ // A URI reference that identifies the specific occurrence of the problem
+ Instance string `json:"instance,omitempty"`
+ // The HTTP status code for this occurrence of the problem
+ Status int32 `json:"status,omitempty"`
+ // A short, human-readable summary of the problem type
+ Title string `json:"title,omitempty"`
+ // A URI reference according to IETF RFC 3986 that identifies the problem type
+ Type_ string `json:"type,omitempty"`
+}
diff --git a/examples/demo10/Model/model_registration_info.go b/examples/demo10/Model/model_registration_info.go
new file mode 100644
index 0000000000000000000000000000000000000000..ad45f4a52778dcd8c1f7343c055b3643fb6519cd
--- /dev/null
+++ b/examples/demo10/Model/model_registration_info.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type RegistrationInfo struct {
+ // The identifier of registered application mobility service. Shall be absent in POST requests, and present otherwise.
+ AppMobilityServiceId string `json:"appMobilityServiceId,omitempty"`
+ // If present, it specifies the device served by the application instance which is registering is registering the Application Mobility Service.
+ DeviceInformation []RegistrationInfoDeviceInformation `json:"deviceInformation,omitempty"`
+ // If present, it indicates the time of Application Mobility Service expiration from the time of registration accepted.The value \"0\" means infinite time, i.e. no expiration.The unit of expiry time is one second.
+ ExpiryTime int32 `json:"expiryTime,omitempty"`
+ ServiceConsumerId *RegistrationInfoServiceConsumerId `json:"serviceConsumerId"`
+}
diff --git a/examples/demo10/Model/model_registration_info_device_information.go b/examples/demo10/Model/model_registration_info_device_information.go
new file mode 100644
index 0000000000000000000000000000000000000000..9e3885bce482b21abd626ca6e6463e8a81b7b3cb
--- /dev/null
+++ b/examples/demo10/Model/model_registration_info_device_information.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type RegistrationInfoDeviceInformation struct {
+ AssociateId *AssociateId `json:"associateId"`
+ AppMobilityServiceLevel *AppMobilityServiceLevel `json:"appMobilityServiceLevel,omitempty"`
+ ContextTransferState *ContextTransferState `json:"contextTransferState,omitempty"`
+}
diff --git a/examples/demo10/Model/model_registration_info_service_consumer_id.go b/examples/demo10/Model/model_registration_info_service_consumer_id.go
new file mode 100644
index 0000000000000000000000000000000000000000..41437ba61968885cf06413758c31290a5f6795b1
--- /dev/null
+++ b/examples/demo10/Model/model_registration_info_service_consumer_id.go
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// The identifier of service consumer requesting the application mobility service, i.e. either the application instance ID or the MEC platform ID.
+type RegistrationInfoServiceConsumerId struct {
+ // If present, it represents the identifier of the application instance registering the Application Mobility Service.
+ AppInstanceId string `json:"appInstanceId,omitempty"`
+ // If present, it represents the identifier of the MEC platform registering the Application Mobility Service.
+ MepId string `json:"mepId,omitempty"`
+}
diff --git a/examples/demo10/Model/model_subscription_link_list.go b/examples/demo10/Model/model_subscription_link_list.go
new file mode 100644
index 0000000000000000000000000000000000000000..ae7493d3729867786ecc29e3433eebf379cfe2c0
--- /dev/null
+++ b/examples/demo10/Model/model_subscription_link_list.go
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type SubscriptionLinkList struct {
+ Links *SubscriptionLinkListLinks `json:"_links"`
+}
diff --git a/examples/demo10/Model/model_subscription_link_list_links.go b/examples/demo10/Model/model_subscription_link_list_links.go
new file mode 100644
index 0000000000000000000000000000000000000000..76b7813e259a2faf95a6cfdbc7544006ed223980
--- /dev/null
+++ b/examples/demo10/Model/model_subscription_link_list_links.go
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// List of hyperlinks related to the resource.
+type SubscriptionLinkListLinks struct {
+ Self *LinkType `json:"self"`
+ // The service consumer’s subscriptions.
+ Subscription []SubscriptionLinkListSubscription `json:"subscription,omitempty"`
+}
diff --git a/examples/demo10/Model/model_subscription_link_list_subscription.go b/examples/demo10/Model/model_subscription_link_list_subscription.go
new file mode 100644
index 0000000000000000000000000000000000000000..e23d56e8e37e81c47b4a0a93a79a1f28bf90f421
--- /dev/null
+++ b/examples/demo10/Model/model_subscription_link_list_subscription.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type SubscriptionLinkListSubscription struct {
+ // The URI referring to the subscription.
+ Href string `json:"href"`
+ SubscriptionType *SubscriptionType `json:"subscriptionType"`
+}
diff --git a/examples/demo10/Model/model_subscription_type.go b/examples/demo10/Model/model_subscription_type.go
new file mode 100644
index 0000000000000000000000000000000000000000..ca4da6f8c0902604ba517b31be7b4f27ae7f697f
--- /dev/null
+++ b/examples/demo10/Model/model_subscription_type.go
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type SubscriptionType string
+
+// List of SubscriptionType
+const (
+ MOBILITY_PROCEDURE_SUBSCRIPTION_SubscriptionType SubscriptionType = "MobilityProcedureSubscription"
+ ADJACENT_APP_INFO_SUBSCRIPTION_SubscriptionType SubscriptionType = "AdjacentAppInfoSubscription"
+)
diff --git a/examples/demo10/Model/model_test_notification.go b/examples/demo10/Model/model_test_notification.go
new file mode 100644
index 0000000000000000000000000000000000000000..c2cafc46dd63ba1f8788f6831a20c3b93b24d364
--- /dev/null
+++ b/examples/demo10/Model/model_test_notification.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type TestNotification struct {
+ // Shall be set to \"TestNotification\".
+ NotificationType string `json:"notificationType"`
+ Links *TestNotificationLinks `json:"_links"`
+}
diff --git a/examples/demo10/Model/model_test_notification__links.go b/examples/demo10/Model/model_test_notification__links.go
new file mode 100644
index 0000000000000000000000000000000000000000..e77f868bb9b534495ab29e0bcaf7d456945263b0
--- /dev/null
+++ b/examples/demo10/Model/model_test_notification__links.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// Hyperlink related to the resource.
+type TestNotificationLinks struct {
+ Subscription *LinkType `json:"subscription"`
+}
diff --git a/examples/demo10/Model/model_time_stamp.go b/examples/demo10/Model/model_time_stamp.go
new file mode 100644
index 0000000000000000000000000000000000000000..84e953c5c761f20245aac0e2fb12ddf9f1930cf8
--- /dev/null
+++ b/examples/demo10/Model/model_time_stamp.go
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+// 'This data type represents the time stamp as Unix-time since January 1, 1970, 00:00:00 UTC'
+type TimeStamp struct {
+ // 'The seconds part of the Time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC.'
+ Seconds int32 `json:"seconds"`
+ // 'The nanoseconds part of the Time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC.'
+ NanoSeconds int32 `json:"nanoSeconds"`
+}
diff --git a/examples/demo10/Model/model_websock_notif_config.go b/examples/demo10/Model/model_websock_notif_config.go
new file mode 100644
index 0000000000000000000000000000000000000000..8776daae6834738994da9460a08db1711a3812cf
--- /dev/null
+++ b/examples/demo10/Model/model_websock_notif_config.go
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 The AdvantEDGE Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * AdvantEDGE Application Mobility API
+ *
+ * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)
[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network
**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).
+ *
+ * API version: 2.2.1
+ * Contact: AdvantEDGE@InterDigital.com
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package model
+
+type WebsockNotifConfig struct {
+ // Set by AMS to indicate to the service consumer the Websocket URI to be used for delivering notifications.
+ WebsocketUri string `json:"websocketUri,omitempty"`
+ // Set to true by the service consumer to indicate that Websocket delivery is requested.
+ RequestWebsocketUri bool `json:"requestWebsocketUri,omitempty"`
+}
diff --git a/examples/demo10/Model/platform_info.go b/examples/demo10/Model/platform_info.go
new file mode 100644
index 0000000000000000000000000000000000000000..e35d52a2b458b5a696ff8898cdfeb195e7eb3bbf
--- /dev/null
+++ b/examples/demo10/Model/platform_info.go
@@ -0,0 +1,8 @@
+package model
+
+type PlatformInfo struct {
+ AmsServiceID string `json:"ams_service_id,omitempty"`
+ AppInstanceID string `json:"app_instance_id,omitempty"`
+ AmsSubscriptionID string `json:"ams_subscription_id,omitempty"`
+ NodeName string `json:"node_name,omitempty"`
+}
diff --git a/examples/demo10/go.mod b/examples/demo10/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..9196c4824139ea443d6443f966ab884f9308bae7
--- /dev/null
+++ b/examples/demo10/go.mod
@@ -0,0 +1,7 @@
+module estimed_demo
+
+go 1.17
+
+require (
+ github.com/google/uuid v1.6.0 // indirect
+)
diff --git a/examples/demo10/go.sum b/examples/demo10/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..40e65d629b6dea1b3ca51f5778cd7ca9d29cff27
--- /dev/null
+++ b/examples/demo10/go.sum
@@ -0,0 +1,2 @@
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
\ No newline at end of file
diff --git a/examples/demo10/main.go b/examples/demo10/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..8e4a870a361684be6091ecc4e618fbb73f2e0d37
--- /dev/null
+++ b/examples/demo10/main.go
@@ -0,0 +1,268 @@
+package main
+
+import (
+ mec "estimed_demo/MEC"
+ model "estimed_demo/Model"
+ onem2m "estimed_demo/oneM2M"
+ "fmt"
+ "log"
+ "math/rand"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+)
+
+// MN-CSE platform details
+var platformURL = ""
+var sandboxURL = "mec-platform2.etsi.org" // Site that hosts MEC Sandbox
+
+
+var cse_id = "" // CSE Structured ID
+var cse_name = "mep-cse-mn" // CSE Name (for some API calls)
+var AE_ID = "CSmartCar" // Application Entity ID
+var App_Name = "SmartCar" // Application Resource Name
+var App_Id = "N-Smart_Car_Application"
+var appVersion = "1.0.0"
+var containerName = "SmartCarContainer"
+var remote_cse_id = "/laboai-id-in"
+
+// MEC platform details
+var sandbox_name = "sbxt8mvfg1" // Namespace allocated to the user upon login
+var DeviceId = "10.100.0.1" // This is the IP of UE moving on map in Sandbox
+var ams_pltf = "mep1"
+
+// Endpoints for recieving notifications from MEC platform
+var server_port = "{Server_Port}" // Port to listen on for notifications
+var ams_notification_endpoint = "/ams/notify"
+var server_ip = "{Server_IP}" // IP address to listen on for notifications
+
+var notificationChan = make(chan string, 10)
+var currentAppInstanceId = ""
+var platformDetails = []map[string]model.PlatformInfo{}
+var associateId = &model.AssociateId{
+ Type_: &[]model.AssociateIdType{"UE_IPv4_ADDRESS"}[0],
+ Value: DeviceId,
+}
+var deviceInfo = &model.RegistrationInfoDeviceInformation{
+ AssociateId: associateId,
+ AppMobilityServiceLevel: &[]model.AppMobilityServiceLevel{"APP_MOBILITY_WITHOUT_CONFIRMATION"}[0],
+ ContextTransferState: &[]model.ContextTransferState{"NOT_TRANSFERRED"}[0],
+}
+
+// initApp initializes the application and connects to the oneM2M platform
+func initApp() error {
+ // Start HTTP server to listen for sensor connections
+ log.Println("Starting HTTP server on port 9876 to listen for sensor connections...")
+ server := &http.Server{Addr: fmt.Sprintf("%s:%s", server_ip, server_port)}
+ // Set up HTTP routes
+ http.HandleFunc(ams_notification_endpoint, func(w http.ResponseWriter, r *http.Request) {
+ id, err := mec.AMSNotificationHandler(w, r)
+ if err != nil {
+ log.Printf("Error handling AMS notification: %v", err)
+ } else if id != "" {
+ notificationChan <- id
+ }
+ })
+
+ // Start server in a goroutine so it doesn't block
+ go func() {
+ log.Println("Server goroutine starting...")
+ if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Printf("Server error: %v", err)
+ log.Printf("ERROR: Could not start server: %v", err)
+ }
+ }()
+
+ // Give the server a moment to start and check if it's running
+ time.Sleep(1 * time.Second)
+
+ // log.Println("✓ HTTP server started and listening on 0.0.0.0:9876")
+
+ log.Printf("Initializing %s (version %s)", App_Id, appVersion)
+ log.Println("Obtaining MEC App Instance ID of mn-cse")
+
+ // Fetch MEC App Instance ID to find the correct App Instance for mn-cse
+ // Construct MEC App Instance URL
+ url := fmt.Sprintf("%s/%s/sandbox-ctrl/v1/applications", sandboxURL, sandbox_name)
+
+ // Get all MEC App Instance ID
+ allAppInstances, err := mec.GetAppInstances(url)
+ if err != nil {
+ return fmt.Errorf("failed to get MEC App Instance IDs: %v", err)
+ }
+ log.Printf("Total MEC App Instances retrieved: %d", len(allAppInstances))
+ log.Printf("MEC App Instances: %+v", allAppInstances)
+
+ // Array to store matching app instances
+ matchingAppInstances, err := mec.MatchForTargetAppInstance(allAppInstances, cse_name)
+ if err != nil {
+ return fmt.Errorf("failed to match MEC App Instances: %v", err)
+ }
+
+ // Create AMS registration and subscription for each matching App Instance
+ callbackURL := fmt.Sprintf("http://%s:%s%s", server_ip, server_port, ams_notification_endpoint)
+ platformDetails, err = mec.RegistrationAndSubscriptionHandler(matchingAppInstances, sandboxURL,
+ sandbox_name, callbackURL, ¤tAppInstanceId, deviceInfo, associateId)
+ if err != nil {
+ return fmt.Errorf("failed to create AMS registration and subscription: %v", err)
+ }
+
+ // Request IoT API for IoT platform urls
+ log.Println("Fetching IoT platform information from MEC...")
+
+ // Current App Instance ID must be set from previous step
+ var current_pltf_details model.PlatformInfo
+ for _, pltf := range platformDetails {
+ if platformInfo, exists := pltf[currentAppInstanceId]; exists {
+ current_pltf_details = platformInfo
+ break
+ }
+ }
+ log.Printf("Current platform details: %v", current_pltf_details)
+
+ iot_url := fmt.Sprintf("%s/%s/%s/iots/v1/registered_iot_platforms", sandboxURL, sandbox_name, current_pltf_details.NodeName)
+ iot_platforms, err := mec.GETIotPlatformInfo(iot_url)
+ if err != nil {
+ return fmt.Errorf("failed to get IoT platform info: %v", err)
+ }
+
+ platformURL = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["endpoint"].(map[string]interface{})["uris"].([]interface{})[0].(string)
+ log.Printf("IoT platform URL: %s", platformURL)
+ cse_id = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["id"].(string)
+ log.Printf("CSE ID: %s", cse_id)
+ cse_name = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["name"].(string)
+ log.Printf("CSE Name: %s", cse_name)
+
+ // Initialize oneM2M application
+ err = onem2m.InitOneM2MApp(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, containerName, remote_cse_id)
+ if err != nil {
+ return fmt.Errorf("failed to initialize oneM2M application: %v", err)
+ }
+ // Create subscription for notification server
+ // err = onem2m.CreateSubscription(platformURL, cse_name, App_Name, containerName)
+ // if err != nil {
+ // return fmt.Errorf("failed to create oneM2M subscription: %v", err)
+ // }
+ return nil
+}
+
+func main() {
+ log.SetFlags(log.LstdFlags | log.Lshortfile)
+ // Handle graceful shutdown on system kill signals
+ sigs := make(chan os.Signal, 1)
+ signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
+ go func() {
+ <-sigs
+ latestData, err := onem2m.RetrieveLatestData(platformURL, cse_name, App_Name, AE_ID, containerName)
+ if err != nil {
+ log.Printf("Failed to retrieve latest data: %v", err)
+ } else {
+ log.Printf("Latest data: %s", latestData)
+ }
+ if err := onem2m.DeregisterAE(platformURL, cse_name, cse_id, App_Name, AE_ID); err != nil {
+ log.Printf("Failed to deregister AE: %v", err)
+ }
+ log.Println("\nReceived shutdown signal, exiting...")
+ os.Exit(0)
+ }()
+
+ // Initialize the application
+ if err := initApp(); err != nil {
+ log.Fatalf("Failed to initialize application: %v", err)
+ os.Exit(1)
+ }
+
+ // Start goroutine to handle received target app instance IDs
+ go func() {
+ for targetAppInstanceID := range notificationChan {
+ // Get platform details for the received ID
+ var targetPltfDetails model.PlatformInfo
+ for _, pltf := range platformDetails {
+ if platformInfo, exists := pltf[targetAppInstanceID]; exists {
+ targetPltfDetails = platformInfo
+ break
+ }
+ }
+ log.Printf("Target platform details: %v", targetPltfDetails)
+
+ // Connect to new IoT platform
+ iot_url := fmt.Sprintf("%s/%s/%s/iots/v1/registered_iot_platforms", sandboxURL, sandbox_name, targetPltfDetails.NodeName)
+ iot_platforms, err := mec.GETIotPlatformInfo(iot_url)
+ if err != nil {
+ log.Printf("Failed to get IoT platform info for target app instance %s: %v", targetAppInstanceID, err)
+ continue
+ }
+ // Temporarily store old platform URL
+ old_platformURL := platformURL
+ old_cse_id := cse_id
+ old_cse_name := cse_name
+
+ platformURL = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["endpoint"].(map[string]interface{})["uris"].([]interface{})[0].(string)
+ log.Printf("New IoT platform URL after mobility: %s", platformURL)
+
+ cse_name = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["name"].(string)
+ cse_id = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["id"].(string)
+
+ // Re-initialize oneM2M application on the new platform
+ err = onem2m.InitOneM2MApp(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, containerName, remote_cse_id)
+ if err != nil {
+ log.Printf("Failed to re-initialize oneM2M application after mobility: %v", err)
+ continue
+ } else {
+ log.Printf("Successfully re-initialized oneM2M application on new platform after mobility")
+ }
+
+ // Disconnect from previous platform
+ log.Printf("Disconnecting from previous platform: %s", old_platformURL)
+ if err := onem2m.DeregisterAE(old_platformURL, old_cse_name, old_cse_id, App_Name, AE_ID); err != nil {
+ log.Printf("Failed to deregister AE from old platform: %v", err)
+ } else {
+ log.Printf("Successfully deregistered AE from old platform")
+ }
+
+ // Update AMS registration to reflect new platform connection
+ log.Printf("Updating AMS registration to reflect new platform connection...")
+
+ // PUT request to AMS for currentAppInstanceId to switch
+ ams_url := fmt.Sprintf("%s/%s/%s/amsi/v1/app_mobility_services", sandboxURL, sandbox_name, ams_pltf)
+ err = mec.PutAMSRegistrationInfo(ams_url, targetAppInstanceID, platformDetails, ¤tAppInstanceId, associateId)
+ if err != nil {
+ log.Printf("Failed to update AMS registration info for target app instance %s: %v", targetAppInstanceID, err)
+ continue
+ } else {
+ log.Printf("Successfully updated AMS registration info for target app instance %s", targetAppInstanceID)
+ }
+
+ // Update AMS subscription to reflect new platform connection
+ log.Printf("Updating AMS subscription to reflect new platform connection...")
+ ams_url = fmt.Sprintf("%s/%s/%s/amsi/v1/subscriptions", sandboxURL, sandbox_name, ams_pltf)
+ err = mec.PUTAMSSubscriptionInfo(ams_url, targetAppInstanceID, platformDetails, ¤tAppInstanceId,
+ fmt.Sprintf("http://%s:%s%s", server_ip, server_port, ams_notification_endpoint), associateId)
+ if err != nil {
+ log.Printf("Failed to update AMS subscription info for target app instance %s: %v", targetAppInstanceID, err)
+ continue
+ } else {
+ log.Printf("Successfully updated AMS subscription info for target app instance %s", targetAppInstanceID)
+ }
+ currentAppInstanceId = targetAppInstanceID
+ }
+ }()
+
+ // Example: Send telemetry data
+ speed := []int{60, 62, 58, 65, 68}
+ temperature := []float64{25.5, 26.0, 24.8, 25.2, 25.9}
+ fuel := []int{75, 74, 73, 72, 71}
+ // For only terminates on system kill signal
+ for {
+ telemetryData := fmt.Sprintf(`{"temperature": %f, "speed": %d, "fuel": %d}`,
+ temperature[rand.Intn(len(temperature))],
+ speed[rand.Intn(len(speed))],
+ fuel[rand.Intn(len(fuel))])
+ if err := onem2m.CreateContentInstance(platformURL, cse_name, App_Name, AE_ID, containerName, remote_cse_id, telemetryData); err != nil {
+ log.Printf("Failed to send telemetry: %v", err)
+ }
+ time.Sleep(5 * time.Second)
+ }
+}
diff --git a/examples/demo10/oneM2M/createAE.go b/examples/demo10/oneM2M/createAE.go
new file mode 100644
index 0000000000000000000000000000000000000000..01904b9f82ebb17c47cecde083555f6bb2e16b85
--- /dev/null
+++ b/examples/demo10/oneM2M/createAE.go
@@ -0,0 +1,44 @@
+package onem2m
+import (
+ "estimed_demo/utils"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+)
+
+// CreateAE creates an Application Entity on the oneM2M platform
+func CreateAE(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, remote_cse_id string) error {
+ log.Println("Creating Application Entity (AE)...")
+
+ reqBody := fmt.Sprintf(`{
+ "m2m:ae": {
+ "rn": "%s",
+ "api": "%s",
+ "rr": true,
+ "lbl": ["Type/SmartCar", "Category/Vehicle"],
+ "srv": ["5"],
+ "at": ["%s"]
+ }
+ }`, App_Name, App_Id, remote_cse_id)
+
+ url := fmt.Sprintf("%s/~%s/%s", platformURL, cse_id, cse_name)
+ log.Println("url (Create AE):", url)
+ resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 2, AE_ID)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ body, _ := io.ReadAll(resp.Body)
+
+ if resp.StatusCode == http.StatusCreated {
+ log.Println("✓ Application Entity (AE) created successfully")
+ return nil
+ } else if resp.StatusCode == http.StatusConflict || resp.StatusCode == http.StatusForbidden {
+ log.Println("⚠ AE already exists")
+ return nil
+ }
+
+ return fmt.Errorf("failed to create AE: status %d, body: %s", resp.StatusCode, string(body))
+}
\ No newline at end of file
diff --git a/examples/demo10/oneM2M/createContentInstance.go b/examples/demo10/oneM2M/createContentInstance.go
new file mode 100644
index 0000000000000000000000000000000000000000..b072ad222089883fbb113ebe419c6432cd15d340
--- /dev/null
+++ b/examples/demo10/oneM2M/createContentInstance.go
@@ -0,0 +1,43 @@
+package onem2m
+import (
+ "estimed_demo/utils"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "strings"
+)
+
+// CreateContentInstance creates a ContentInstance (data) in the container
+func CreateContentInstance(platformURL, cse_name, App_Name, AE_ID, containerName, remote_cse_id, data string) error {
+ log.Printf("Creating ContentInstance with data: %s", data)
+
+ // Escape JSON quotes in the content field
+ escapedData := strings.ReplaceAll(data, `"`, `\"`)
+
+ reqBody := fmt.Sprintf(`{
+ "m2m:cin": {
+ "con": "%s",
+ "lbl": ["telemetry"],
+ "at": ["%s"],
+ "aa": ["lbl", "con"]
+ }
+ }`, escapedData, remote_cse_id)
+
+ url := fmt.Sprintf("%s/%s/%s/%s", platformURL, cse_name, App_Name, containerName)
+
+ resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 4, AE_ID)
+ if err != nil {
+ return fmt.Errorf("request error: %v", err)
+ }
+ defer resp.Body.Close()
+
+ body, _ := io.ReadAll(resp.Body)
+
+ if resp.StatusCode == http.StatusCreated {
+ log.Println("✓ ContentInstance created successfully")
+ return nil
+ }
+
+ return fmt.Errorf("failed to create content instance: status %d, body: %s", resp.StatusCode, string(body))
+}
\ No newline at end of file
diff --git a/examples/demo10/oneM2M/createSubscription.go b/examples/demo10/oneM2M/createSubscription.go
new file mode 100644
index 0000000000000000000000000000000000000000..51141de9bc66145c7de6433e7c6e5953b27a9385
--- /dev/null
+++ b/examples/demo10/oneM2M/createSubscription.go
@@ -0,0 +1,64 @@
+package onem2m
+
+import (
+ "bytes"
+ "crypto/tls"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+)
+
+// CreateSubscription creates a subscription on the specified container for the notification server endpoint
+func CreateSubscription(platformURL, cseName, appName, containerName string) error {
+ subscriptionURL := fmt.Sprintf("%s/%s/%s/%s", platformURL, cseName, appName, containerName)
+
+ target := subscriptionURL
+ // Subscription resource body
+ body := map[string]interface{}{
+ "m2m:sub": map[string]interface{}{
+ "rn": "DataSyncSub",
+ "nu": []string{"https://192.168.20.163:9999/notifications"},
+ "nct": 1,
+ "enc": map[string]interface{}{
+ "net": []int{3},
+ },
+ },
+ }
+ jsonBody, err := json.Marshal(body)
+ if err != nil {
+ return fmt.Errorf("failed to marshal subscription body: %v", err)
+ }
+
+ adminUser := "CAdmin"
+ adminSecret := "ikram123"
+ authString := fmt.Sprintf("%s:%s", adminUser, adminSecret)
+ authHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte(authString))
+
+ req, err := http.NewRequest("POST", target, bytes.NewBuffer(jsonBody))
+ if err != nil {
+ return fmt.Errorf("failed to create subscription request: %v", err)
+ }
+ req.Header.Set("X-M2M-Origin", adminUser)
+ req.Header.Set("X-M2M-RI", "req-admin")
+ req.Header.Set("Authorization", authHeader)
+ req.Header.Set("X-M2M-RVI", "5")
+ req.Header.Set("Content-Type", "application/json;ty=23")
+
+ // Skip TLS verification for development/testing
+ tr := &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ }
+ client := &http.Client{Transport: tr}
+ resp, err := client.Do(req)
+ if err != nil {
+ return fmt.Errorf("failed to send subscription request: %v", err)
+ }
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ if resp.StatusCode != 201 && resp.StatusCode != 409 { // 409: Already exists
+ return fmt.Errorf("subscription creation failed: %s", string(respBody))
+ }
+ return nil
+}
diff --git a/examples/demo10/oneM2M/createcontainer.go b/examples/demo10/oneM2M/createcontainer.go
new file mode 100644
index 0000000000000000000000000000000000000000..a3745f5222f21802795dc6c8126713dbe741e386
--- /dev/null
+++ b/examples/demo10/oneM2M/createcontainer.go
@@ -0,0 +1,44 @@
+package onem2m
+
+import (
+ "estimed_demo/utils"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+)
+
+// CreateContainer creates a container under the AE
+func CreateContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName, remote_cse_id string) error {
+ log.Println("Creating Container...")
+
+ reqBody := fmt.Sprintf(`{
+ "m2m:cnt": {
+ "rn": "%s",
+ "mni": 10,
+ "at": ["%s"],
+ "lbl": ["Data/Telemetry"],
+ "aa": ["lbl"]
+ }
+ }`, containerName, remote_cse_id)
+
+ url := fmt.Sprintf("%s/~/%s/%s/%s", platformURL, cse_id, cse_name, App_Name)
+ log.Println("url (Create Container):", url)
+ resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 3, AE_ID)
+ if err != nil {
+ return fmt.Errorf("request error: %v", err)
+ }
+ defer resp.Body.Close()
+
+ body, _ := io.ReadAll(resp.Body)
+
+ if resp.StatusCode == http.StatusCreated {
+ log.Println("✓ Container created successfully")
+ return nil
+ } else if resp.StatusCode == http.StatusConflict {
+ log.Println("⚠ Container already exists")
+ return nil
+ }
+
+ return fmt.Errorf("failed to create container: status %d, body: %s", resp.StatusCode, string(body))
+}
\ No newline at end of file
diff --git a/examples/demo10/oneM2M/deregister.go b/examples/demo10/oneM2M/deregister.go
new file mode 100644
index 0000000000000000000000000000000000000000..ac04d09171dfdd4e08a6dfcf298adb2f34987c66
--- /dev/null
+++ b/examples/demo10/oneM2M/deregister.go
@@ -0,0 +1,27 @@
+package onem2m
+
+import (
+ "estimed_demo/utils"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+)
+
+// DeregisterAE deregisters the AE from the oneM2M platform
+func DeregisterAE(platformURL, cseName, cse_id, appName, aeID string) error {
+ aeResource := fmt.Sprintf("%s/~%s/%s/%s", platformURL, cse_id, cseName, appName)
+ resp, err := utils.MakeOneM2MRequest("DELETE", aeResource, "", 2, aeID)
+ if err != nil {
+ return fmt.Errorf("failed to deregister AE: %v", err)
+ }
+ defer resp.Body.Close()
+
+ body, _ := io.ReadAll(resp.Body)
+ if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
+ return fmt.Errorf("failed to deregister AE, status: %s, response: %s", resp.Status, string(body))
+ }
+
+ log.Printf("✓ AE deregistered successfully, response: %s", string(body))
+ return nil
+}
diff --git a/examples/demo10/oneM2M/oneM2m_init.go b/examples/demo10/oneM2M/oneM2m_init.go
new file mode 100644
index 0000000000000000000000000000000000000000..3f9b92204e03622240b77da92075d7dabe443f4a
--- /dev/null
+++ b/examples/demo10/oneM2M/oneM2m_init.go
@@ -0,0 +1,31 @@
+package onem2m
+
+import (
+ "log"
+ "time"
+)
+
+// Initialize oneM2M application
+func InitOneM2MApp(platformURL, cse_name, cse_id, App_Name,
+ App_Id, AE_ID, containerName, remote_cse_id string) error {
+ log.Printf("Connecting to MN-CSE: %s", platformURL)
+ // Create AE
+ if err := CreateAE(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, remote_cse_id); err != nil {
+ return err
+ }
+ // Wait briefly to ensure AE is registered
+ time.Sleep(2 * time.Second)
+
+ // Create Container
+ if err := CreateContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName, remote_cse_id); err != nil {
+ return err
+ }
+
+ // Verify container
+ if err := RetrieveContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName); err != nil {
+ log.Printf("Warning: Could not verify container: %v", err)
+ }
+
+ log.Println("✓ Application initialized successfully")
+ return nil
+}
diff --git a/examples/demo10/oneM2M/retrieveContainer.go b/examples/demo10/oneM2M/retrieveContainer.go
new file mode 100644
index 0000000000000000000000000000000000000000..a6d4dc211f531ae2dc1a172a5c276fe5d89aa362
--- /dev/null
+++ b/examples/demo10/oneM2M/retrieveContainer.go
@@ -0,0 +1,28 @@
+package onem2m
+import (
+ "estimed_demo/utils"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+)
+
+// RetrieveContainer retrieves container details
+func RetrieveContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName string) error {
+ url := fmt.Sprintf("%s/~%s/%s/%s/%s", platformURL, cse_id, cse_name, App_Name, containerName)
+
+ resp, err := utils.MakeOneM2MRequest("GET", url, "", 0, AE_ID)
+ if err != nil {
+ return fmt.Errorf("error retrieving container: %v", err)
+ }
+ defer resp.Body.Close()
+
+ body, _ := io.ReadAll(resp.Body)
+
+ if resp.StatusCode == http.StatusOK {
+ log.Println("✓ Container exists and is accessible")
+ return nil
+ }
+
+ return fmt.Errorf("container not found: status %d, body: %s", resp.StatusCode, string(body))
+}
\ No newline at end of file
diff --git a/examples/demo10/oneM2M/retrieveLatestData.go b/examples/demo10/oneM2M/retrieveLatestData.go
new file mode 100644
index 0000000000000000000000000000000000000000..9208f581272644956e6e9c077a68a103fb5f1656
--- /dev/null
+++ b/examples/demo10/oneM2M/retrieveLatestData.go
@@ -0,0 +1,30 @@
+package onem2m
+import (
+ "estimed_demo/utils"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+)
+
+// RetrieveLatestData retrieves the latest ContentInstance from the container
+func RetrieveLatestData(platformURL, cse_name, App_Name, AE_ID, containerName string) (string, error) {
+ // Use 'la' (latest) to get the most recent ContentInstance
+ // ToDo: Fix variable name cse_id to cse_name // check this file
+ url := fmt.Sprintf("%s/%s/%s/%s/la", platformURL, cse_name, App_Name, containerName)
+
+ resp, err := utils.MakeOneM2MRequest("GET", url, "", 0, AE_ID)
+ if err != nil {
+ return "", fmt.Errorf("error retrieving data: %v", err)
+ }
+ defer resp.Body.Close()
+
+ body, _ := io.ReadAll(resp.Body)
+
+ if resp.StatusCode == http.StatusOK {
+ log.Println("✓ Latest data retrieved successfully")
+ return string(body), nil
+ }
+
+ return "", fmt.Errorf("failed to retrieve data: status %d", resp.StatusCode)
+}
\ No newline at end of file
diff --git a/examples/demo10/utils/mec_req.go b/examples/demo10/utils/mec_req.go
new file mode 100644
index 0000000000000000000000000000000000000000..f4f32e155c24910333d6899e0f9d3743ceeeba94
--- /dev/null
+++ b/examples/demo10/utils/mec_req.go
@@ -0,0 +1,50 @@
+package utils
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "log"
+ "net/http"
+ "time"
+)
+
+func SendMECRequest(method, url string, payload interface{}) (*http.Response, error) {
+ client := &http.Client{
+ Timeout: 10 * time.Second,
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ }
+
+ var req *http.Request
+ var err error
+
+ // Handle GET requests with no payload
+ if method == "GET" && payload == nil {
+ req, err = http.NewRequestWithContext(context.Background(), method, url, nil)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create request: %v", err)
+ }
+ } else {
+ // Handle requests with payload
+ reqBody, err := json.Marshal(payload)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal payload: %v", err)
+ }
+ log.Println("Request body:", string(reqBody))
+
+ req, err = http.NewRequestWithContext(context.Background(), method, url, bytes.NewBuffer(reqBody))
+ if err != nil {
+ return nil, fmt.Errorf("failed to create request: %v", err)
+ }
+ req.Header.Set("Content-Type", "application/json")
+ }
+
+ req.Header.Set("Accept", "application/json")
+ req.Header.Set("User-Agent", "Go-http-client/1.1")
+
+ return client.Do(req)
+}
diff --git a/examples/demo10/utils/onem2m_req.go b/examples/demo10/utils/onem2m_req.go
new file mode 100644
index 0000000000000000000000000000000000000000..7295ebcd0fa9c8d3152f01d1c6f450972d3f6472
--- /dev/null
+++ b/examples/demo10/utils/onem2m_req.go
@@ -0,0 +1,53 @@
+package utils
+
+import (
+ "crypto/tls"
+ "encoding/base64"
+ "fmt"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/google/uuid"
+)
+
+// MakeOneM2MRequest creates and sends a oneM2M HTTP request
+func MakeOneM2MRequest(method, url, body string, ty int, originator string) (*http.Response, error) {
+ client := &http.Client{Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ Timeout: 10 * time.Second}
+ reqID := uuid.New().String()
+
+ // if originator == "" {
+ // originator = AE_ID
+ // }
+
+ headers := map[string]string{
+ "X-M2M-Origin": originator,
+ "X-M2M-RI": reqID,
+ "X-M2M-RVI": "5",
+ "Accept": "application/json",
+ "Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("CAdmin:ikram123")),
+ }
+
+ if method == "POST" {
+ headers["Content-Type"] = fmt.Sprintf("application/json;ty=%d", ty)
+ }
+
+ req, err := http.NewRequest(method, url, strings.NewReader(body))
+ if err != nil {
+ return nil, fmt.Errorf("failed to create request: %v", err)
+ }
+
+ for key, value := range headers {
+ req.Header.Set(key, value)
+ }
+
+ resp, err := client.Do(req)
+ if err != nil {
+ return nil, fmt.Errorf("failed to send request: %v", err)
+ }
+
+ return resp, nil
+}
diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile b/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile
index 608b06b800c50b79f9201e653ace6fa65b787512..1eab6208e3b4d24ce74ea80a388a305479161f8b 100644
--- a/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile
+++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile
@@ -1,4 +1,5 @@
-FROM ubuntu:22.04
+FROM ubuntu:24.04
+
ENV MQTT_ENABLE=""
ENV MQTT_HOST=""
ENV MQTT_PORT=""
@@ -16,38 +17,17 @@ ENV MEC_SANDBOX_SERVER=""
RUN echo "meep-acme-in-cse" > /etc/hostname \
&& DEBIAN_FRONTEND=noninteractive apt-get update \
- && DEBIAN_FRONTEND=noninteractive apt-get install -y \
- autoconf \
- bison \
- build-essential \
- cmake \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
- dos2unix \
- doxygen \
- emacs \
- expect \
- flex \
- g++ \
- gcc \
gettext \
git \
gnutls-bin \
iputils-ping \
jq \
libedit2 \
- libedit-dev \
libffi-dev \
libglib2.0-dev \
- libgcrypt-dev \
- libjsoncpp-dev \
- libncurses5-dev \
- libpcap-dev \
libssl-dev \
- libtool-bin \
- libtool \
- libxml2-dev \
- libxml2-utils \
- libyaml-dev \
lsof \
ntp \
pkg-config \
@@ -55,24 +35,21 @@ RUN echo "meep-acme-in-cse" > /etc/hostname \
python3-pip \
python3-setuptools \
sudo \
- sshpass \
- tcpdump \
tzdata \
&& DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -y \
&& DEBIAN_FRONTEND=noninteractive apt-get autoclean \
&& DEBIAN_FRONTEND=noninteractive apt-get clean \
- && pip3 install --no-cache-dir --upgrade pip
+ && rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
-#RUN git clone --branch development https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE
-RUN git clone https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE
+RUN git clone --branch development https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE
WORKDIR /usr/src/app/ACME-oneM2M-CSE
COPY ./data /usr/src/app/ACME-oneM2M-CSE
RUN chmod +x entrypoint.sh \
- && pip3 install --no-cache-dir -r requirements.txt
+ && pip3 install --no-cache-dir -r requirements.txt --break-system-packages
-ENTRYPOINT ["./entrypoint.sh"]
+ENTRYPOINT ["./entrypoint.sh"]
\ No newline at end of file
diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in
index a2dbd1964b9b25f8151724de71331798b8306097..c434ab0ce34cba19317fb734e968d9554849a5bd 100644
--- a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in
+++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in
@@ -29,6 +29,9 @@ databaseType=memory
logLevel=debug
consoleTheme=dark
+[cse]
+poa=https://$SERVER_IP:443/$SVC_PATH
+
[mqtt]
enable=$MQTT_ENABLE
address=$MQTT_HOST
@@ -37,12 +40,17 @@ keepalive=45
[mqtt.websocket]
enable=$MQTT_ENABLE
port=$MQTT_PORT
-transport=websockets
+;transport=websockets
path=$WEBSOCK_ETPATH
+[mqtt.security]
+useTLS=true
+
[cse.registration]
; Edit this to add more allowed originators.
-allowedCSROriginators=/$CSE_BASE_RI,/acme-mep-id-mn-cse,/id-in,/id-mn,/id-asn
+;allowedCSROriginators=/$CSE_BASE_RI,/acme-mep-id-mn-cse,/id-in,/id-mn,/id-asn,/mep-id-mn-cse
+allowedCSROriginators=/*
+;address=https://${basic.config:registrarCseHost}:${basic.config:registrarCsePort}
[textui]
startWithTUI=false
@@ -53,11 +61,17 @@ enable=true
[http]
enableUpperTesterEndpoint=true
enableStructureEndpoint=true
+root=/
+address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:externalRoot}
+externalRoot=/$SVC_PATH/
+
+[webui]
+root=/webui
[coap]
enable=$ENABLE_COAP
port=5683
[websocket]
-enable=$ENABLE_WS
+enable=false
port=8180
diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh
index 8bdd260bfaf01bbd9d9629bd6a00abfc803bceef..b6a40717113b0a5105fc31a1346c30c33e38fc94 100755
--- a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh
+++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh
@@ -2,7 +2,9 @@
set -e
echo "MEEP_HOST_URL: ${MEEP_HOST_URL}"
-SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}"
+# SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}"
+SERVER_IP="${MEEP_HOST_URL#http://}"
+SERVER_IP="${SERVER_IP#https://}"
echo "MEC_PLATFORM=$MEC_PLATFORM"
echo "MEEP_SANDBOX_NAME=$MEEP_SANDBOX_NAME"
@@ -21,21 +23,21 @@ echo "MQTT_USERNAME: ${MQTT_USERNAME}"
echo "MQTT_PASSWORD: ${MQTT_PASSWORD}"
# Retrieve the internal meep-mosquitto IP address
-SERVICE_NAME="meep-cloud-mosquitto"
+SERVICE_NAME="monaco-telecom-meep-cloud-mosquitto"
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
-MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.clusterIP')
-echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS"
-
-# Retrieve the internal meep-mosquitto port id
-MOSQUITTO_NODE_PORT=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.ports[0].targetPort')
-echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT"
+# MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.clusterIP')
+# echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS"
+
+# # Retrieve the internal meep-mosquitto port id
+# MOSQUITTO_NODE_PORT=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.ports[0].targetPort')
+# echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT"
if [[ ! -z "${MEEP_MEP_NAME}" ]]; then
svcPath="${MEEP_SANDBOX_NAME}/${MEEP_MEP_NAME}"
@@ -51,6 +53,8 @@ fi
sleep 5 # Wait for ETSI MEC Platform up and stable
+SVC_PATH="${svcPath}/meep-acme-in-cse"
+
SERVER_IP=`echo $SERVER_IP | sed -e "s/https:\/\///g"` # Remove https://
SERVER_PORT=${SERVER_PORT:-3003}
MEC_SANDBOX_ID=${MEEP_SANDBOX_NAME:-"meep-sandbox"}
@@ -62,12 +66,12 @@ ENABLE_WS=${ENABLE_WS:-false}
# MQTT Configuration
MQTT_ENABLE=${MQTT_ENABLE:-true}
-MQTT_HOST=${MOSQUITTO_NODE_IP_ADDRESS:-"meep-cloud-mosquito"}
+MQTT_HOST=${SERVER_IP:-"monaco-telecom-meep-cloud-mosquitto"}
MQTT_PORT=${MOSQUITTO_NODE_PORT:-443}
MQTT_USERNAME=${MQTT_USERNAME:-"acme-mn-cse"}
MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"}
-WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-cloud-mosquitto"}
+WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-mosquitto"}
echo "Environment variables set:"
echo "SERVER_TYPE: ${SERVER_TYPE}"
@@ -83,6 +87,7 @@ echo "MQTT_PORT: ${MQTT_PORT}"
echo "MQTT_USERNAME: ${MQTT_USERNAME}"
echo "MQTT_PASSWORD: ${MQTT_PASSWORD}"
echo "WEBSOCK_ETPATH: ${WEBSOCK_ETPATH}"
+echo "SVC_PATH: ${SVC_PATH}"
export SERVER_TYPE
export SERVER_IP
@@ -100,6 +105,8 @@ export MQTT_USERNAME
export MQTT_PASSWORD
export WEBSOCK_ETPATH
+export SVC_PATH
+
workdir="/usr/src/app/ACME-oneM2M-CSE"
cd "$workdir" || { echo "Directory $workdir not found"; exit 1; }
envsubst < acme.ini.in > acme.ini
diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile b/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile
index f7ad8e980425a754efde91a37ced8adfa6af1ab1..7ef8c3035259cd6c5ce584ccf0ec79b740b8be06 100644
--- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile
+++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:22.04
+FROM ubuntu:24.04
ENV SERVER_TYPE=""
ENV SERVER_IP=""
@@ -24,40 +24,17 @@ ENV ACME_IN_SERVICE_NAME=""
RUN echo "meep-acme-mn-cse" > /etc/hostname \
&& DEBIAN_FRONTEND=noninteractive apt-get update \
- && DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y \
- && DEBIAN_FRONTEND=noninteractive apt-get update \
- && DEBIAN_FRONTEND=noninteractive apt-get install -y \
- autoconf \
- bison \
- build-essential \
- cmake \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
- dos2unix \
- doxygen \
- emacs \
- expect \
- flex \
- g++ \
- gcc \
gettext \
git \
gnutls-bin \
iputils-ping \
jq \
libedit2 \
- libedit-dev \
libffi-dev \
libglib2.0-dev \
- libgcrypt-dev \
- libjsoncpp-dev \
- libncurses5-dev \
- libpcap-dev \
libssl-dev \
- libtool-bin \
- libtool \
- libxml2-dev \
- libxml2-utils \
- libyaml-dev \
lsof \
ntp \
pkg-config \
@@ -65,13 +42,11 @@ RUN echo "meep-acme-mn-cse" > /etc/hostname \
python3-pip \
python3-setuptools \
sudo \
- sshpass \
- tcpdump \
tzdata \
&& DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -y \
&& DEBIAN_FRONTEND=noninteractive apt-get autoclean \
&& DEBIAN_FRONTEND=noninteractive apt-get clean \
- && pip3 install --no-cache-dir --upgrade pip
+ && rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
@@ -82,7 +57,7 @@ WORKDIR /usr/src/app/ACME-oneM2M-CSE
COPY ./data /usr/src/app/ACME-oneM2M-CSE
RUN chmod +x entrypoint.sh \
- && pip3 install --no-cache-dir -r requirements.txt
+ && pip3 install --no-cache-dir -r requirements.txt --break-system-packages
ENTRYPOINT ["./entrypoint.sh"]
diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in
index 5ef1483a8b4e864fc0d7239215ba50e37507c344..5115ca606092868df3160696a892e44ebb3669b2 100644
--- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in
+++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in
@@ -34,12 +34,18 @@ databaseType=memory
logLevel=debug
consoleTheme=dark
+[cse]
+poa=https://$SERVER_IP:443/$SVC_PATH
+
[cse.registration]
; Edit this to add more allowed originators.
-allowedCSROriginators=/id-in,/id-mn,/id-asn
+;allowedCSROriginators=/$REMOTE_CSE_ID,/laboai-id-in,/laboai-cse-in,/acme-mep-id-mn-cse,/id-in,/id-mn,/id-asn,/mep-id-mn-cse
+allowedCSROriginators=/*
[cse.registrar]
INCSEcseID=/$REMOTE_CSE_ID
+address=https://${basic.config:registrarCseHost}:${basic.config:registrarCsePort}/
+root=$REMOTE_SVC_PATH
[textui]
startWithTUI=false
@@ -48,8 +54,14 @@ startWithTUI=false
enable=true
[http]
-enableUpperTesterEndpoint=true
-enableStructureEndpoint=true
+enableUpperTesterEndpoint = true
+enableStructureEndpoint = true
+root=/
+address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:externalRoot}
+externalRoot=/$SVC_PATH/
+
+[webui]
+root=/webui
[mqtt]
enable=$MQTT_ENABLE
@@ -59,17 +71,23 @@ keepalive=45
[mqtt.websocket]
enable=$MQTT_ENABLE
port=$MQTT_PORT
-transport=websockets
+;transport=websockets
path=$WEBSOCK_ETPATH
+[mqtt.security]
+useTLS=true
+
[coap]
enable=$ENABLE_COAP
port=5683
[websocket]
-enable=$ENABLE_WS
+enable=false
port=8180
+[logging]
+enableBindingsLogging = false
+
[etsi_mec]
mec_enable=$MEC_ENABLE
mec_host=$MEC_HOST_URL
@@ -79,3 +97,5 @@ mec_platform=$MEC_PLATFORM
mec_sandbox_id=$MEC_SANDBOX_ID
cse_external_ip=$CSE_EXTERNAL_IP
cse_external_port=$CSE_EXTERNAL_PORT
+fullAddress=$MN_CSE_FULL_ADDRESS
+mec_app_instance_id=$MEC_APP_INSTANCE_ID
\ No newline at end of file
diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py
index 1eb8126344de7d50030dc798dfd4909c930350ab..08008b05350a1525738147c9644b086f4c16118c 100644
--- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py
+++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py
@@ -48,7 +48,9 @@ class MECClient(object):
'mqtt_port',
'wss_path',
'cse_resourceID',
+ 'fullAddress',
'isStopped',
+ 'mec_app_instance_id',
'mecConnection',
'mecConnections',
'isInfo',
@@ -59,7 +61,9 @@ class MECClient(object):
# TODO move config handling to event handler
- def __init__(self, p_http_address: str, p_http_port: str, p_cse_resourceID: str, p_cse_external_ip: str, p_cse_external_port: str, p_use_wss: bool, p_mqtt_address: str, p_mqtt_port: str, p_wss_path: str = "") -> None:
+ def __init__(self, p_http_address: str, p_http_port: str, p_cse_resourceID: str,
+ p_cse_external_ip: str, p_cse_external_port: str, p_use_wss: bool, p_mqtt_address: str,
+ p_mqtt_port: str, p_fullAddress: str, p_mec_app_instance_id: str , p_wss_path: str = "") -> None:
""" Initialize the MEC client.
"""
self.http_address = p_http_address
@@ -73,6 +77,8 @@ class MECClient(object):
self.mqtt_address = p_mqtt_address
self.mqtt_port = p_mqtt_port
self.wss_path = p_wss_path
+ self.fullAddress = p_fullAddress
+ self.mec_app_instance_id = p_mec_app_instance_id
self.isStopped = False
""" Flag to indicate whether the MEC client is stopped. """
@@ -213,7 +219,7 @@ class MECClient(object):
userTransportInfoList = []
userTransportInfo = {}
userTransportInfo['id'] = str(uuid.uuid4())
- userTransportInfo['name'] = self.cse_resourceID
+ userTransportInfo['name'] = Configuration.cse_cseID
userTransportInfo['type'] = 'MB_TOPIC_BASED'
if self.use_wss:
userTransportInfo['description'] = 'MQTT over WS-Secured'
@@ -223,37 +229,42 @@ class MECClient(object):
userTransportInfo['protocol'] = 'MQTT'
userTransportInfo['version'] = '2'
userTransportInfo['endpoint'] = {}
+ # userTransportInfo['endpoint']['addresses'] = []
+ # The MEC API expects an array of URIs for the endpoint 'uris' field.
+ # Previously this was set to a single string which caused the server
+ # to return: "cannot unmarshal string into Go struct field ... uris of type []string".
if self.use_wss:
userTransportInfo['endpoint']['uris'] = []
userTransportInfo['endpoint']['uris'].append('wss://' + self.mqtt_address + ':' + str(self.mqtt_port) + self.wss_path)
- address = {}
- address['host'] = self.mqtt_address
- address['port'] = self.mqtt_port
- userTransportInfo['endpoint']['addresses'].append(address)
else:
userTransportInfo['endpoint']['addresses'] = []
address = {}
address['host'] = self.mqtt_address
address['port'] = self.mqtt_port
userTransportInfo['endpoint']['addresses'].append(address)
+ # userTransportInfo['endpoint']['uris'] = [ self.fullAddress ]
+ # address = {}
+ # address['host'] = self.mqtt_address
+ # address['port'] = self.mqtt_port
+ # userTransportInfo['endpoint']['addresses'].append(address)
userTransportInfo['security'] = {}
userTransportInfo['implSpecificInfo'] = {}
userTransportInfoList.append(userTransportInfo)
body_json['userTransportInfo'] = userTransportInfoList
customServicesTransportInfoList = []
customServicesTransportInfo = {}
- customServicesTransportInfo['id'] = str(uuid.uuid4())
- customServicesTransportInfo['name'] = self.cse_resourceID
- customServicesTransportInfo['description'] = 'ACME oneM2M CSE'
+ # customServicesTransportInfo['id'] = str(uuid.uuid4())
+ customServicesTransportInfo['id'] = Configuration.cse_cseID
+ customServicesTransportInfo['name'] = Configuration.cse_resourceName
+ customServicesTransportInfo['description'] = 'ACME oneM2M CSE ID'
customServicesTransportInfo['type'] = 'REST_HTTP'
customServicesTransportInfo['protocol'] = 'REST_HTTP'
customServicesTransportInfo['version'] = '4'
customServicesTransportInfo['endpoint'] = {}
- customServicesTransportInfo['endpoint']['addresses'] = []
- address = {}
- address['host'] = self.cse_external_ip
- address['port'] = int(self.http_port) #int(self.cse_external_port)
- customServicesTransportInfo['endpoint']['addresses'].append(address)
+ if self.fullAddress == '':
+ customServicesTransportInfo['endpoint']['uris'] = [ 'https://' + self.cse_external_ip + ':' + str(self.http_port) ]
+ else:
+ customServicesTransportInfo['endpoint']['uris'] = [ self.fullAddress ]
customServicesTransportInfo['security'] = {}
customServicesTransportInfoList.append(customServicesTransportInfo)
body_json['customServicesTransportInfo'] = customServicesTransportInfoList
@@ -262,7 +273,7 @@ class MECClient(object):
tries = 0
while tries < 5:
- response = requests.post(url, headers=self.headers, json=body_json)
+ response = requests.post(url, headers=self.headers, json=body_json, verify=False)
L.isInfo and L.log(f'MECClient.registerToMec: response.content: ' + str(response.content))
if response.status_code == 201:
self.register = Result()
@@ -292,7 +303,7 @@ class MECClient(object):
'/' + Configuration.mec_sandbox_id + \
'/' + Configuration.mec_platform + \
'/iots/v1/registered_iot_platforms/' + json_dict['iotPlatformId']
- response = requests.delete(url, headers=self.headers)
+ response = requests.delete(url, headers=self.headers, verify=False)
self.register = None
return Result(rsc = response.status_code)
except Exception as e:
@@ -300,3 +311,78 @@ class MECClient(object):
self.register = None
return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC Deregistration failure')
+
+ def confirm_readyToMec(self) -> Result:
+ """ Confirm readiness to MEC platform.
+ """
+ if self.isStopped:
+ return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC client is not running')
+
+ try:
+ req_body = {
+ "indication": "READY"
+ }
+ url = \
+ Configuration.mec_protocol + '://' +Configuration.mec_host + ':' + str(Configuration.mec_port) + \
+ '/' + Configuration.mec_sandbox_id + \
+ '/' + Configuration.mec_platform + \
+ '/mec_app_support/v2/applications/' + self.mec_app_instance_id + '/confirm_ready'
+ L.log('MECClient.confirm_readyToMec: ' + str(req_body))
+ L.log('MECClient.confirm_readyToMec: ' + str(url))
+ response = requests.post(url, headers=self.headers, json=req_body, verify=False)
+ return Result(rsc = response.status_code)
+ except Exception as e:
+ L.logErr(f'MECClient.confirm_readyToMec: ' + str(e))
+ return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC Confirm readiness failure')
+
+ def post_mec_service(self) -> Result:
+ """
+ Declare MEC service to MEC platform.
+ This function declares MN-CSE as MEC service to the MEC platform.
+ """
+ if self.isStopped:
+ return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC client is not running')
+
+ try:
+ req_body = {
+ "serName": Configuration.cse_resourceName,
+ "serCategory": {
+ "href": "catalogueHref",
+ "id": Configuration.cse_cseID,
+ "name": Configuration.cse_resourceName,
+ "version": "v1"
+ },
+ "version": "v1.0.0",
+ "state": "ACTIVE",
+ "transportInfo": {
+ "id": "acme-mn-cse-transport",
+ "name": "REST",
+ "type": "REST_HTTP",
+ "protocol": "HTTPS",
+ "version": "4.0",
+ "endpoint": {
+ "uris": [
+ self.fullAddress
+ ],
+ "fqdn": None,
+ "addresses": None,
+ "alternative": None
+ },
+ "security": None
+ },
+ "serializer": "JSON",
+ "scopeOfLocality": "MEC_SYSTEM",
+ "consumedLocalOnly": True
+ }
+ url = \
+ Configuration.mec_protocol + '://' + Configuration.mec_host + ':' + str(Configuration.mec_port) + \
+ '/' + Configuration.mec_sandbox_id + \
+ '/' + Configuration.mec_platform + \
+ '/mec_service_mgmt/v1/applications/' + self.mec_app_instance_id + '/services'
+ L.log('MECClient.POST_mec_service: ' + str(req_body))
+ L.log('MECClient.POST_mec_service: ' + str(url))
+ response = requests.post(url, headers=self.headers, json=req_body, verify=False)
+ return Result(rsc = response.status_code)
+ except Exception as e:
+ L.logErr(f'MECClient.POST_mec_service: ' + str(e))
+ return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC Declare MEC service failure')
\ No newline at end of file
diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py
index d4311f7a7334e1cfb2c3d33daca71bdd90af6ff3..b1b0ad0185f048ab9933e64f0b3f2fe75842746a 100644
--- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py
+++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py
@@ -37,6 +37,7 @@ from ..services.GroupManager import GroupManager
from ..runtime.Importer import Importer
from ..services.LocationManager import LocationManager
from ..services.NotificationManager import NotificationManager
+from ..runtime.PluginManager import PluginManager
from ..services.RegistrationManager import RegistrationManager
from ..services.RemoteCSEManager import RemoteCSEManager
from ..runtime.ScriptManager import ScriptManager
@@ -97,6 +98,9 @@ mqttClient:MQTTClient = None
notification:NotificationManager = None
""" Runtime instance of the `NotificationManager`. """
+pluginManager:PluginManager = None
+""" Runtime instance of the `PluginManager`. """
+
registration:RegistrationManager = None
""" Runtime instance of the `RegistrationManager`. """
@@ -159,7 +163,7 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool:
False if the CSE couldn't initialized and started.
"""
global action, announce, coapServer, console, dispatcher, event, groupResource, httpServer, importer, location, mqttClient, mecClient
- global notification, registration, remote, request, script, security, semantic, statistics, storage, textUI, time
+ global notification, pluginManager, registration, remote, request, script, security, semantic, statistics, storage, textUI, time
global timeSeries, validator, webSocketServer
# Set status
@@ -228,14 +232,12 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool:
if Configuration.mec_enable:
L.log('Initializing MEC client')
-
- # Initialize the MEC client
if Configuration.mqtt_websocket_enable:
- mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_websocket_port, Configuration.mec_platform+"/"+Configuration.mec_sandbox_id+"/"+)
+ mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_websocket_port, Configuration.fullAddress, Configuration.mec_app_instance_id, Configuration.mqtt_websocket_path)
else:
- mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_port)
+ mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_port, Configuration.fullAddress, Configuration.mec_app_instance_id)
if mecClient is None:
- Configuration.mec_enable = False
+ Configuration.mec_enable = False
# → Experimental late loading
#
@@ -256,6 +258,11 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool:
RC.cseStatus = CSEStatus.STOPPED
return False
+ # Initialize the plugin manager
+ # This loads, configures and runs the plugins as well
+ pluginManager = PluginManager()
+
+
# Start the HTTP server
if not httpServer.run(): # This does return (!)
L.logErr('Terminating', showStackTrace = False)
@@ -284,8 +291,13 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool:
L.logErr(f'Error during startup: {e.dbg}')
RC.cseStatus = CSEStatus.STOPPED
return False
+ except KeyError as e:
+ L.logErr(f'Error during startup: {e}')
+ RC.cseStatus = CSEStatus.STOPPED
+ return False
+
except Exception as e:
- L.logErr(f'Error during startup: {e}', exc = e)
+ L.logErr(f'Error during startup: {e}', exc=e)
RC.cseStatus = CSEStatus.STOPPED
return False
@@ -311,7 +323,7 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool:
def shutdown() -> None:
- """ Gracefully shutdown the CSE programmatically. This will end the mail console loop
+ """ Gracefully shutdown the CSE programmatically. This will end the main console loop
to terminate.
The actual shutdown happens in the _shutdown() method.
@@ -351,6 +363,7 @@ def _shutdown() -> None:
event.cseShutdown() # type: ignore
# shutdown the services
+ pluginManager and pluginManager.shutdown()
textUI and textUI.shutdown()
console and console.shutdown()
time and time.shutdown()
@@ -453,7 +466,7 @@ def resetCSE() -> None:
# Enable log queuing again
L.queueOn()
- # Send restart event
+ # Send restarted event
event.cseRestarted() # type: ignore [attr-defined]
RC.cseStatus = CSEStatus.RUNNING
@@ -481,9 +494,11 @@ def run() -> None:
L.logDebug(f'MEC enable: {Configuration.mec_enable}')
if Configuration.mec_enable:
+ mecClient.confirm_readyToMec()
+ mecClient.post_mec_service()
mecClient.registerToMec()
- if waitFor(C.cseStartupDelay * 3, lambda: RC.cseStatus == CSEStatus.RUNNING):
+ if waitFor(C.cseStartupDelay * 3, lambda: RC.cseStatus==CSEStatus.RUNNING):
console.run()
else:
raise TimeoutError(L.logErr(f'CSE did not start within {C.cseStartupDelay * 3} seconds'))
diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py
index a44cf2b7b3e42d39b0ba28fa8d8bd77b96fbedfb..36b6132148e3959261f0d716247ebe3791280397 100644
--- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py
+++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py
@@ -16,6 +16,7 @@ from typing import Any, Dict, Tuple, Optional, cast, Set
import configparser, argparse, os, os.path, pathlib
from copy import deepcopy
from inspect import getmembers
+from dotenv import load_dotenv, find_dotenv
from rich.console import Console
@@ -53,6 +54,9 @@ class Configuration(object):
"""
+ configParser:ACMEConfiguration = None
+ """ The ACMEConfiguration instance holding the configuration values. """
+
coap_enable:bool
""" Enable or disable the CoAP server. """
@@ -200,6 +204,14 @@ class Configuration(object):
""" The size of the operation requests. """
+ cse_operation_plugins_disabledPlugins:list[str]
+ """ A list of disabled plugins. """
+
+ cse_operation_plugins_replace:bool
+ """ Replace existing plugins with the same name. """
+
+
+
cse_registrars:dict[str, CSERegistrar] = {}
""" A dictionary of CSE or service provider CSEs registrars. The keys are the CSE IDs, the values are dictionaries with the registrar information. """
@@ -265,6 +277,8 @@ class Configuration(object):
database_postgresql_schema:str
""" The schema of the PostgreSQL database. """
+ fullAddress:str
+ """ The full address of the MN-CSE. """
http_address:str
""" The address to listen on for HTTP the http server. """
@@ -290,6 +304,9 @@ class Configuration(object):
http_root:str
""" The root of the HTTP path. """
+ http_externalRoot:str
+ """ The non-local root path of the HTTP path. This is used when the CSE is accessed from non-local addresses, e.g. in a Kubernetes cluster. """
+
http_timeout:float
""" The timeout for HTTP requests. """
@@ -375,6 +392,8 @@ class Configuration(object):
logging_enableUTCTimezone:bool
""" Enable or disable UTC timezone. """
+ mec_app_instance_id:str
+ """ MEC application instance id. """
mqtt_address:str
""" The address to listen on for the MQTT server. """
@@ -856,7 +875,7 @@ class Configuration(object):
zk.disconnect()
# Read and parse the configuration file
- config = ACMEConfiguration()
+ Configuration.configParser = ACMEConfiguration()
# Construct the default values that are used for interpolation
_defaults = { 'basic.config': {
@@ -877,35 +896,45 @@ class Configuration(object):
'secret' : os.getenv('ACME_SECURITY_SECRET', 'acme'), # The main secret key for the CSE.
}
}
+ # Load environment variables from .env file from the base directory, if it exists
+ load_dotenv(dotenv_path=f'{Configuration.baseDirectory}{os.path.sep}.env')
+
# Add environment variables to the defaults
_defaults.update({ 'DEFAULT': {k: v.replace('$', '$$') for k,v in os.environ.items()} })
# Add (empty) default for supported environment variables to the defaults dictionary for the interpolation during reading the configuration file
_envVariables = { e: os.getenv(e, '') if e not in _defaults else _defaults[e]
for e in (
- 'ACME_MQTT_SECURITY_PASSWORD', 'ACME_MQTT_SECURITY_USERNAME',
+ 'ACME_MQTT_SECURITY_PASSWORD',
+ 'ACME_MQTT_SECURITY_USERNAME',
'ACME_DATABASE_POSTGRESQL_PASSWORD',
- 'ACME_CSE_REGISTRAR_SECURITY_HTTPUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_HTTPPASSWORD', 'ACME_CSE_REGISTRAR_SECURITY_HTTPBEARERTOKEN',
- 'ACME_CSE_REGISTRAR_SECURITY_WSUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_WSPASSWORD', 'ACME_CSE_REGISTRAR_SECURITY_WSBEARERTOKEN',
- 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPPASSWORD',
- 'ACME_CSE_REGISTRAR_SECURITY_SELFWSUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_SELFWSPASSWORD',
+ 'ACME_CSE_REGISTRAR_SECURITY_HTTPUSERNAME',
+ 'ACME_CSE_REGISTRAR_SECURITY_HTTPPASSWORD',
+ 'ACME_CSE_REGISTRAR_SECURITY_HTTPBEARERTOKEN',
+ 'ACME_CSE_REGISTRAR_SECURITY_WSUSERNAME',
+ 'ACME_CSE_REGISTRAR_SECURITY_WSPASSWORD',
+ 'ACME_CSE_REGISTRAR_SECURITY_WSBEARERTOKEN',
+ 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPUSERNAME',
+ 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPPASSWORD',
+ 'ACME_CSE_REGISTRAR_SECURITY_SELFWSUSERNAME',
+ 'ACME_CSE_REGISTRAR_SECURITY_SELFWSPASSWORD',
)
}
_defaults['DEFAULT'].update(_envVariables)
# Set the defaults
- config.read_dict(_defaults)
+ Configuration.configParser.read_dict(_defaults)
try:
# Read the configuration files
# if len(config.read( [Configuration._defaultConfigFile, Configuration.configfile])) == 0 and Configuration._args_configfile != C.defaultUserConfigFile: # Allow
- if len(config.read(configurationFiles)) == 0 and Configuration._args_configfile != C.defaultUserConfigFile: # Allow
+ if len(Configuration.configParser.read(configurationFiles)) == 0 and Configuration._args_configfile != C.defaultUserConfigFile: # Allow
Configuration._print(f'[red]Configuration file missing or not readable: {Configuration._args_configfile}')
return False
# Read the extra configuration strings (e.g. from Zookeeper)
for cs in configurationStrings:
- config.read_string(cs)
+ Configuration.configParser.read_string(cs)
except configparser.Error as e:
Configuration._print('[red]Error in configuration file')
@@ -916,7 +945,7 @@ class Configuration(object):
# Look for deprecated and renamed sections and print an error message
if _deprecatedSections:
for o, n in _deprecatedSections:
- if config.has_section(o):
+ if Configuration.configParser.has_section(o):
Configuration._print(fr'[red]Found old section name in configuration file. Please rename "\[{o}]" to "\[{n}]".')
return False
@@ -928,7 +957,7 @@ class Configuration(object):
# and to set the respective attributes in the Configuration class.
# Validations are done later below.
for m in _moduleConfigs:
- m.readConfiguration(config, Configuration) # type:ignore [arg-type]
+ m.readConfiguration(Configuration.configParser, Configuration) # type:ignore [arg-type]
except configparser.InterpolationMissingOptionError as e:
Configuration._print(f'[red]Error in configuration file: {Configuration.configfile}\n{str(e)}')
@@ -979,8 +1008,8 @@ class Configuration(object):
attr = getattr(Configuration, k)
match attr:
case pathlib.Path():
- # Convert pathlib.Path to string
- attr = str(attr)
+ # Don't change the original dict, so make a copy
+ attr = deepcopy(attr)
case dict():
# Convert dict elements to instances dict, if necessary
for k2,v2 in attr.items():
@@ -990,8 +1019,7 @@ class Configuration(object):
# Replace underscores with dots in the key names
result[k.replace('_', '.')] = attr
- result = deepcopy(result) # make sure that the result is a deep copy of the configuration
- return result
+ return deepcopy(result) # make sure that the result is a deep copy of the configuration
@staticmethod
diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py
index be6bf4a1ed8adc9ca5424fd017b9e0f73d0c4233..c94fb6bbeaef92e8503f2000ffbea467b20baafe 100644
--- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py
+++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py
@@ -35,6 +35,8 @@ class MECClientConfiguration(ModuleConfiguration):
config.mec_protocol = parser.get('etsi_mec', 'mec_protocol', fallback = 'https')
config.mec_platform = parser.get('etsi_mec', 'mec_platform', fallback = 'mep1')
config.mec_sandbox_id = parser.get('etsi_mec', 'mec_sandbox_id', fallback = 'mec_sandbox_id')
+ config.fullAddress = parser.get('etsi_mec', 'fullAddress', fallback = None)
+ config.mec_app_instance_id = parser.get('etsi_mec', 'mec_app_instance_id', fallback = None)
def validateConfiguration(self, config:Configuration, initial:Optional[bool] = False) -> None:
""" Validate the configuration.
@@ -61,5 +63,9 @@ class MECClientConfiguration(ModuleConfiguration):
Configuration.cse_external_ip = Configuration._cse_external_ip
if Configuration._cse_external_port is not None:
Configuration.cse_external_port = Configuration._cse_external_port
+ if Configuration.fullAddress is not None:
+ Configuration.fullAddress = Configuration.fullAddress
+ if Configuration.mec_app_instance_id is not None:
+ Configuration.mec_app_instance_id = Configuration.mec_app_instance_id
config.mec_host = normalizeURL(config.mec_host)
diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh
index c1fce9fb1bddc1fb79fc633375fcb5e848109cef..feba66c5143b1c5c8c6597146b4de8309b77f325 100755
--- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh
+++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh
@@ -2,9 +2,12 @@
set -e
echo "MEEP_HOST_URL: ${MEEP_HOST_URL}"
-SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}"
+# SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}"
+SERVER_IP="${MEEP_HOST_URL#http://}"
+SERVER_IP="${SERVER_IP#https://}"
-echo "MEC_PLATFORM=$MEC_PLATFORM"
+echo "MEEP_HOST_URL: ${MEEP_HOST_URL}"
+echo "MEC_PLATFORM=$MEEP_MEP_NAME"
echo "MEEP_SANDBOX_NAME=$MEEP_SANDBOX_NAME"
# Other environment variables
@@ -19,6 +22,7 @@ echo "MQTT_HOST: ${MQTT_HOST}"
echo "MQTT_PORT: ${MQTT_PORT}"
echo "MQTT_USERNAME: ${MQTT_USERNAME}"
echo "MQTT_PASSWORD: ${MQTT_PASSWORD}"
+echo "APP_INSTANCE_ID: ${MEEP_INSTANCE_ID}"
sleep 10 # Wait for the MEC platform to stablize and acme in cse to be ready
@@ -26,62 +30,62 @@ sleep 10 # Wait for the MEC platform to stablize and acme in cse to be ready
SERVICE_NAME="meep-mosquitto"
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
-MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.clusterIP')
-echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS"
-
-# Retrieve the internal meep-mosquitto port id
-MOSQUITTO_NODE_PORT=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.ports[0].targetPort')
-echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT"
-
-# Retrieve the internal meep-acme-in-cse IP address
-SERVICE_NAME="meep-acme-in-cse"
-REMOTE_CSE_IP_ADDRESS=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.clusterIP')
-echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $REMOTE_CSE_IP_ADDRESS"
-
-# Retrieve the internal meep-acme-in-cse port id
-SERVICE_NAME="meep-acme-in-cse"
-NODE_PORT_IN_CSE=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.ports[0].targetPort')
-echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT_IN_CSE"
-
-SERVICE_NAME="meep-acme-mn-cse"
-NODE_IP=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.clusterIP')
-echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_IP"
-NODE_PORT=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
- | jq -r '.spec.ports[0].nodePort')
-echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT"
+# MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.clusterIP')
+# echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS"
+
+# # Retrieve the internal meep-mosquitto port id
+# MOSQUITTO_NODE_PORT=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.ports[0].targetPort')
+# echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT"
+
+# # Retrieve the internal meep-acme-in-cse IP address
+# SERVICE_NAME="meep-acme-in-cse"
+# REMOTE_CSE_IP_ADDRESS=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.clusterIP')
+# echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $REMOTE_CSE_IP_ADDRESS"
+
+# # Retrieve the internal meep-acme-in-cse port id
+# SERVICE_NAME="meep-acme-in-cse"
+# NODE_PORT_IN_CSE=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.ports[0].targetPort')
+# echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT_IN_CSE"
+
+# SERVICE_NAME="meep-acme-mn-cse"
+# NODE_IP=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.clusterIP')
+# echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_IP"
+# NODE_PORT=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \
+# | jq -r '.spec.ports[0].nodePort')
+# echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT"
# The following name is the one name used to represent its block in scenario at endpoint /alt
-ACME_IN_SERVICE_NAME=${ACME_IN_SERVICE_NAME:-"om2m-acme-in-cse"}
-# Fetch pod name acme in cse
-POD_NAME=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods \
- | jq -r --arg svc "$ACME_IN_SERVICE_NAME" '.items[] | select(.metadata.labels.app == $svc) | .metadata.name' | head -n 1)
-echo "Pod name for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $POD_NAME"
-
-# Step 2: Get the MEEP_MEP_NAME of ACME IN CSE environment variable from the pod
-ACME_MEEP_MEP_NAME=$(curl -sSk \
- -H "Authorization: Bearer $TOKEN" \
- https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods/$POD_NAME \
- | jq -r '.spec.containers[0].env[] | select(.name=="MEEP_MEP_NAME") | .value')
-echo "MEEP_MEP_NAME for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $ACME_MEEP_MEP_NAME"
+# ACME_IN_SERVICE_NAME=${ACME_IN_SERVICE_NAME:-"monaco-telecom-meep-acme-in-cse"}
+# # Fetch pod name acme in cse
+# POD_NAME=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods \
+# | jq -r --arg svc "$ACME_IN_SERVICE_NAME" '.items[] | select(.metadata.labels.app == $svc) | .metadata.name' | head -n 1)
+# echo "Pod name for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $POD_NAME"
+
+# # Step 2: Get the MEEP_MEP_NAME of ACME IN CSE environment variable from the pod
+# ACME_MEEP_MEP_NAME=$(curl -sSk \
+# -H "Authorization: Bearer $TOKEN" \
+# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods/$POD_NAME \
+# | jq -r '.spec.containers[0].env[] | select(.name=="MEEP_MEP_NAME") | .value')
+# echo "MEEP_MEP_NAME for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $ACME_MEEP_MEP_NAME"
if [[ ! -z "${MEEP_MEP_NAME}" ]]; then
svcPath="${MEEP_SANDBOX_NAME}/${MEEP_MEP_NAME}"
@@ -99,34 +103,42 @@ SERVER_IP=`echo $SERVER_IP | sed -e "s/https:\/\///g"` # Remove https://
SERVER_TYPE=${SERVER_TYPE:-"MN"}
SERVER_PORT=${SERVER_PORT:-3004}
+# MN-CSE Address
+
CSE_BASE_NAME=${CSE_BASE_NAME:-"mep-cse-mn"}
CSE_BASE_RI=${CSE_BASE_RI:-"acme-mep-id-mn-cse"}
+MN_CSE_FULL_ADDRESS="https://${SERVER_IP}/${svcPath}/meep-acme-mn-cse"
# REMOTE_CSE_HOST="${REMOTE_CSE_IP_ADDRESS:-"meep-acme-in-cse"}"
# REMOTE_CSE_PORT=${NODE_PORT_IN_CSE:-3003}
REMOTE_CSE_HOST=${SERVER_IP:-"meep-acme-in-cse"}
-REMOTE_CSE_PORT=80/${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"mep1"}/meep-acme-in-cse
+# REMOTE_CSE_PORT=443/${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"monaco-telecom"}/meep-acme-in-cse
+REMOTE_CSE_PORT=443
+REMOTE_SVC_PATH=${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"monaco-telecom"}/meep-acme-in-cse
REMOTE_CSE_ID=${REMOTE_CSE_ID:-"laboai-id-in"}
REMOTE_CSE_NAME=${REMOTE_CSE_NAME:-"laboai-cse-in"}
ENABLE_COAP=${ENABLE_COAP:-false}
ENABLE_WS=${ENABLE_WS:-false}
-CSE_EXTERNAL_IP=${NODE_IP}
-CSE_EXTERNAL_PORT=${NODE_PORT}
+CSE_EXTERNAL_IP=${SERVER_IP}
+CSE_EXTERNAL_PORT=${NODE_PORT:-443}
# MEC Configuration
MEC_ENABLE=${MEC_ENABLE:-true}
MEC_HOST_URL=${SERVER_IP}
-MEC_PLATFORM=${MEC_PLATFORM:-"mep1"}
+MEC_PLATFORM=${MEEP_MEP_NAME:-"mep1"}
MEC_SANDBOX_ID=${MEEP_SANDBOX_NAME:-"meep-sandbox"}
+MEC_APP_INSTANCE_ID=${MEEP_INSTANCE_ID:-"meep-acme-mn-cse-instance"}
# MQTT Configuration
MQTT_ENABLE=${MQTT_ENABLE:-true}
-MQTT_HOST=${MOSQUITTO_NODE_IP_ADDRESS:-"meep-mosquito"}
-MQTT_PORT=${MOSQUITTO_NODE_PORT:-443}
+MQTT_HOST=${SERVER_IP:-"meep-mosquito"}
+MQTT_PORT=443
MQTT_USERNAME=${MQTT_USERNAME:-"acme-mn-cse"}
MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"}
-WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-cloud-mosquitto"}
+WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-mosquitto"}
+
+SVC_PATH="${svcPath}/meep-acme-mn-cse"
echo "Environment variables set:"
echo "SERVER_TYPE: ${SERVER_TYPE}"
@@ -147,15 +159,21 @@ echo "MQTT_USERNAME: ${MQTT_USERNAME}"
echo "MQTT_PASSWORD: ${MQTT_PASSWORD}"
echo "MEC_ENABLE: ${MEC_ENABLE}"
echo "MEC_HOST_URL: ${MEC_HOST_URL}"
-echo "MEC_PLATFORM: ${MEC_PLATFORM}"
+echo "MEC_PLATFORM: ${MEEP_MEP_NAME}"
echo "MEC_SANDBOX_ID: ${MEC_SANDBOX_ID}"
echo "ENABLE_COAP: ${ENABLE_COAP}"
echo "ENABLE_WS: ${ENABLE_WS}"
echo "WEBSOCK_ETPATH: ${WEBSOCK_ETPATH}"
+echo "MN_CSE_FULL_ADDRESS: ${MN_CSE_FULL_ADDRESS}"
+echo "MEC_APP_INSTANCE_ID: ${MEC_APP_INSTANCE_ID}"
+echo "SVC_PATH: ${SVC_PATH}"
+echo "REMOTE_SVC_PATH: ${REMOTE_SVC_PATH}"
export SERVER_TYPE
export SERVER_IP
export SERVER_PORT
+export MN_CSE_FULL_ADDRESS
+export MEC_APP_INSTANCE_ID
export CSE_BASE_NAME
export CSE_BASE_RI
@@ -163,6 +181,7 @@ export REMOTE_CSE_ID
export REMOTE_CSE_NAME
export REMOTE_CSE_HOST
export REMOTE_CSE_PORT
+export REMOTE_SVC_PATH
export CSE_EXTERNAL_IP
export CSE_EXTERNAL_PORT
export ENABLE_COAP
@@ -180,6 +199,8 @@ export MEC_HOST_URL
export MEC_PLATFORM
export MEC_SANDBOX_ID
+export SVC_PATH
+
workdir="/usr/src/app/ACME-oneM2M-CSE"
cd "$workdir" || { echo "Directory $workdir not found"; exit 1; }
envsubst < acme.ini.in > acme.ini
diff --git a/go-apps/meep-iot/server/meep-iot.go b/go-apps/meep-iot/server/meep-iot.go
index cb1c1f27c7473a3cec915a6b3bd258558a4c6903..9ebf3a1ee412ddf25ccbb88acc06b9b336d2db4e 100644
--- a/go-apps/meep-iot/server/meep-iot.go
+++ b/go-apps/meep-iot/server/meep-iot.go
@@ -755,9 +755,9 @@ func registerediotplatformsPOST(w http.ResponseWriter, r *http.Request) {
errHandlerProblemDetails(w, "Mandatory attribute Type_ shall be set to MB_TOPIC_BASED in the request body.", http.StatusBadRequest)
return
}
- if v.Protocol != "MQTT" && v.Protocol != "AMQP" {
- log.Error("Mandatory Protocol parameter shall be set to MQTT or AMQP")
- errHandlerProblemDetails(w, "Mandatory attribute Protocol shall be set to MQTT or AMQP in the request body.", http.StatusBadRequest)
+ if v.Protocol != "MQTT" && v.Protocol != "MQTT+WSS" && v.Protocol != "AMQP" {
+ log.Error("Mandatory Protocol parameter shall be set to MQTT, MQTT+WSS or AMQP")
+ errHandlerProblemDetails(w, "Mandatory attribute Protocol shall be set to MQTT, MQTT+WSS or AMQP in the request body.", http.StatusBadRequest)
return
}
if v.Version == "" {
diff --git a/go-apps/meep-sandbox-ctrl/server/app-ctrl.go b/go-apps/meep-sandbox-ctrl/server/app-ctrl.go
index a798cd5133979a01a1885a83206bb5a789ca7a41..0e9cdc8944351221def4f8d0dc08e8fa56bdd266 100644
--- a/go-apps/meep-sandbox-ctrl/server/app-ctrl.go
+++ b/go-apps/meep-sandbox-ctrl/server/app-ctrl.go
@@ -250,18 +250,23 @@ func getScenarioAppInstanceList(activeModel *mod.Model) ([]*apps.Application, er
var appList []*apps.Application
if activeModel != nil {
- // Get active scenario node names
- appNames := activeModel.GetNodeNames(mod.NodeTypeEdgeApp)
- for _, appName := range appNames {
- // Get scenario Process & context
- proc, ctx, err := getScenarioProcess(appName, activeModel)
- if err != nil {
- log.Error(err.Error())
+ // Get all processes
+ processes := activeModel.GetProcesses(nil)
+ for _, proc := range processes.Processes {
+ // Only handle EDGE-APP for duplicates
+ if proc.Type_ != mod.NodeTypeEdgeApp {
+ continue
+ }
+
+ // Get context by ID
+ ctx := activeModel.GetNodeContextById(proc.Id)
+ if ctx == nil {
+ log.Error("Failed to get context for process ID: " + proc.Id)
continue
}
// Create app instance
- app, err := createAppInstance(proc, ctx)
+ app, err := createAppInstance(&proc, ctx)
if err != nil {
log.Error(err.Error())
continue
diff --git a/go-apps/meep-virt-engine/go.mod b/go-apps/meep-virt-engine/go.mod
index e80bab8085c2f5bf1bc07a30ecdb4de07a40452b..88c118c8771a07900990da8ddd83f8633488554c 100644
--- a/go-apps/meep-virt-engine/go.mod
+++ b/go-apps/meep-virt-engine/go.mod
@@ -8,6 +8,7 @@ require (
github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model v0.0.0
github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq v0.0.0
github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-watchdog v0.0.0
+ github.com/google/uuid v1.2.0 // indirect
)
replace (
diff --git a/go-apps/meep-virt-engine/server/chart-template.go b/go-apps/meep-virt-engine/server/chart-template.go
index 7681a997098647f13d48f945809733cbc0f0ba81..a8763b5db9af6fcc29bd5887969e07f470f8a617 100644
--- a/go-apps/meep-virt-engine/server/chart-template.go
+++ b/go-apps/meep-virt-engine/server/chart-template.go
@@ -182,29 +182,22 @@ func getAppEnablement(mepName string, model *mod.Model) string {
func generateScenarioCharts(sandboxName string, procName string, model *mod.Model) (charts []helm.Chart, err error) {
serviceMap := map[string]string{}
- procNames := model.GetNodeNames("CLOUD-APP")
- procNames = append(procNames, model.GetNodeNames("EDGE-APP")...)
- procNames = append(procNames, model.GetNodeNames("UE-APP")...)
- for _, name := range procNames {
+ processes := model.GetProcesses(nil)
+ for _, proc := range processes.Processes {
// Check if single process is being added
- if procName != "" && name != procName {
+ if procName != "" && proc.Name != procName {
continue
}
// Retrieve node process information from model
- node := model.GetNode(name)
+ node := model.GetNodeById(proc.Id)
if node == nil {
- err = errors.New("Error finding process: " + name)
- return nil, err
- }
- proc, ok := node.(*dataModel.Process)
- if !ok {
- err = errors.New("Error casting process: " + name)
+ err = errors.New("Error finding process: " + proc.Name + " with ID: " + proc.Id)
return nil, err
}
- ctx := model.GetNodeContext(name)
+ ctx := model.GetNodeContextById(proc.Id)
if ctx == nil {
- err = errors.New("Error finding context for process: " + name)
+ err = errors.New("Error finding context for process: " + proc.Name + " with ID: " + proc.Id)
return nil, err
}
@@ -256,12 +249,13 @@ func generateScenarioCharts(sandboxName string, procName string, model *mod.Mode
}
}
}
- } else if mepService := getMepService(proc); mepService != "" {
+ } else if mepService := getMepService(&proc); mepService != "" {
log.Debug("Processing MEP Service chart for element[", proc.Name, "]")
// Get MEP Name
mepName := ctx.Parents[mod.PhyLoc]
+ // Important part of code.
// Create Sandbox template
var sandboxTemplate SandboxTemplate
sandboxTemplate.InstanceId = proc.Id
@@ -291,7 +285,10 @@ func generateScenarioCharts(sandboxName string, procName string, model *mod.Mode
}
// Create chart
- chartName := proc.Name
+ chartName := mepName + "-" + proc.Name
+ if len(chartName) > 53 {
+ chartName = chartName[:53]
+ }
chartLocation, _, err := createChart(chartName, sandboxName, scenarioName, mepService, sandboxTemplate)
if err != nil {
log.Debug("yaml creation file process: ", err)
@@ -572,6 +569,11 @@ func newChart(chartName string, sandboxName string, scenarioName string, chartLo
chart.ReleaseName = "meep-" + scenarioName + "-" + chartName
}
+ // Truncate release name to 53 characters to comply with Helm requirements
+ if len(chart.ReleaseName) > 53 {
+ chart.ReleaseName = chart.ReleaseName[:53]
+ }
+
chart.Name = chartName
chart.Namespace = sandboxName
chart.Location = chartLocation
diff --git a/go-packages/meep-model/model.go b/go-packages/meep-model/model.go
index 97c1030be84c2507fb1e7dd3b0971a8bd86de5be..b22a9cd8a98e66a664c46309973befbbb17435a7 100644
--- a/go-packages/meep-model/model.go
+++ b/go-packages/meep-model/model.go
@@ -240,6 +240,7 @@ func (m *Model) SetScenario(j []byte) (err error) {
m.scenario = scenario
err = m.parseNodes()
+ // No Prob in Parsing Nodes
if err != nil {
log.Error(err.Error())
return err
@@ -368,7 +369,7 @@ func (m *Model) GetServiceMaps() *[]dataModel.NodeServiceMaps {
return &m.svcMap
}
-//UpdateNetChar - Update network characteristics for a node
+// UpdateNetChar - Update network characteristics for a node
func (m *Model) UpdateNetChar(nc *dataModel.EventNetworkCharacteristicsUpdate, userData interface{}) (err error) {
m.lock.Lock()
defer m.lock.Unlock()
@@ -550,12 +551,6 @@ func (m *Model) addPhyLoc(node *dataModel.ScenarioNode, parentNode *Node) (err e
return err
}
- // Make sure node Name is unique
- n := m.nodeMap.FindByName(pl.Name)
- if n != nil {
- return errors.New("Element " + pl.Name + " already exists in scenario " + m.name)
- }
-
// Ignore any configured processes
pl.Processes = make([]dataModel.Process, 0)
@@ -581,12 +576,6 @@ func (m *Model) addProcess(node *dataModel.ScenarioNode, parentNode *Node) (err
return err
}
- // Make sure node Name is unique
- n := m.nodeMap.FindByName(proc.Name)
- if n != nil {
- return errors.New("Element " + proc.Name + " already exists in scenario " + m.name)
- }
-
// Add Proc to parent PhyLoc
pl.Processes = append(pl.Processes, *proc)
@@ -838,7 +827,7 @@ func (m *Model) removeProcess(node *dataModel.ScenarioNode) (err error) {
return nil
}
-//GetScenarioName - Get the scenario name
+// GetScenarioName - Get the scenario name
func (m *Model) GetScenarioName() string {
m.lock.RLock()
defer m.lock.RUnlock()
@@ -850,7 +839,7 @@ func (m *Model) GetScenarioName() string {
return ""
}
-//GetNodeNames - Get the list of nodes of a certain type; "" or "ANY" returns all
+// GetNodeNames - Get the list of nodes of a certain type; "" or "ANY" returns all
func (m *Model) GetNodeNames(typ ...string) []string {
m.lock.RLock()
defer m.lock.RUnlock()
@@ -858,11 +847,15 @@ func (m *Model) GetNodeNames(typ ...string) []string {
nm := make(map[string]*Node)
for _, t := range typ {
if t == "" || t == "ANY" {
- nm = m.nodeMap.nameMap
+ for name, nodes := range m.nodeMap.nameMap {
+ if len(nodes) > 0 {
+ nm[name] = nodes[0]
+ }
+ }
break
}
- for k, v := range m.nodeMap.typeMap[t] {
- nm[k] = v
+ for name, node := range m.nodeMap.FindAllByType(t) {
+ nm[name] = node
}
}
@@ -873,41 +866,46 @@ func (m *Model) GetNodeNames(typ ...string) []string {
return list
}
-//GetEdges - Get a map of node edges for the current scenario
+// GetEdges - Get a map of node edges for the current scenario
func (m *Model) GetEdges() (edgeMap map[string]string) {
m.lock.RLock()
defer m.lock.RUnlock()
edgeMap = make(map[string]string)
- for k, node := range m.nodeMap.nameMap {
- p := reflect.ValueOf(node.parent)
- pName := reflect.Indirect(p).FieldByName("Name")
- if pName.IsValid() {
- edgeMap[k] = pName.String()
- // fmt.Printf("%s (%T) \t\t %s(%T)\n", k, node.object, pName, node.parent)
+ for k, nodes := range m.nodeMap.nameMap {
+ if len(nodes) > 0 {
+ node := nodes[0]
+ p := reflect.ValueOf(node.parent)
+ pName := reflect.Indirect(p).FieldByName("Name")
+ if pName.IsValid() {
+ edgeMap[k] = pName.String()
+ // fmt.Printf("%s (%T) \t\t %s(%T)\n", k, node.object, pName, node.parent)
+ }
}
}
return edgeMap
}
// GetNode - Get a node by its name
-// Returned value is of type interface{}
-// Good practice: returned node should be type asserted with val,ok := node.(someType) to prevent panic
+//
+// Returned value is of type interface{}
+// Good practice: returned node should be type asserted with val,ok := node.(someType) to prevent panic
func (m *Model) GetNode(name string) (node interface{}) {
m.lock.RLock()
defer m.lock.RUnlock()
node = nil
n := m.nodeMap.nameMap[name]
- if n != nil {
- node = n.object
+ if len(n) > 0 {
+ node = n[0].object
}
return node
}
// GetNodeById - Get a node by its id
-// Returned value is of type interface{}
-// Returned node may be nil
+//
+// Returned value is of type interface{}
+// Returned node may be nil
func (m *Model) GetNodeById(id string) (node interface{}) {
m.lock.RLock()
defer m.lock.RUnlock()
@@ -927,8 +925,8 @@ func (m *Model) GetNodeId(name string) (id string) {
id = ""
n := m.nodeMap.nameMap[name]
- if n != nil {
- id = n.id
+ if len(n) > 0 {
+ id = n[0].id
}
return id
}
@@ -940,8 +938,8 @@ func (m *Model) GetNodeType(name string) (typ string) {
typ = ""
n := m.nodeMap.nameMap[name]
- if n != nil {
- typ = n.nodeType
+ if len(n) > 0 {
+ typ = n[0].nodeType
}
return typ
}
@@ -953,8 +951,8 @@ func (m *Model) GetNodeParent(name string) (parent interface{}) {
parent = nil
n := m.nodeMap.nameMap[name]
- if n != nil {
- parent = n.parent
+ if len(n) > 0 {
+ parent = n[0].parent
}
return parent
}
@@ -966,8 +964,8 @@ func (m *Model) GetNodeChild(name string) (child interface{}) {
child = nil
n := m.nodeMap.nameMap[name]
- if n != nil {
- child = n.child
+ if len(n) > 0 {
+ child = n[0].child
}
return child
}
@@ -979,11 +977,29 @@ func (m *Model) GetNodeContext(name string) (ctx *NodeContext) {
ctx = nil
n := m.nodeMap.nameMap[name]
+ if len(n) > 0 {
+ nodeCtx := n[0].context
+ var ok bool
+ if ctx, ok = nodeCtx.(*NodeContext); !ok {
+ log.Error("Error casting node context for node: " + name)
+ return nil
+ }
+ }
+ return ctx
+}
+
+// GetNodeContextById - Get a node context by ID
+func (m *Model) GetNodeContextById(id string) (ctx *NodeContext) {
+ m.lock.RLock()
+ defer m.lock.RUnlock()
+
+ ctx = nil
+ n := m.nodeMap.idMap[id]
if n != nil {
nodeCtx := n.context
var ok bool
if ctx, ok = nodeCtx.(*NodeContext); !ok {
- log.Error("Error casting node context for node: " + name)
+ log.Error("Error casting node context for node ID: " + id)
return nil
}
}
@@ -1221,21 +1237,20 @@ func (m *Model) GetProcesses(filter *NodeFilter) dataModel.Processes {
m.lock.RLock()
defer m.lock.RUnlock()
- // Get process nodes
- nMap := make(map[string]*Node)
- m.mergeNodeMap(nMap, m.nodeMap.FindAllByType(NodeTypeUEApp))
- m.mergeNodeMap(nMap, m.nodeMap.FindAllByType(NodeTypeEdgeApp))
- m.mergeNodeMap(nMap, m.nodeMap.FindAllByType(NodeTypeCloudApp))
-
// Find nodes that match filter criteria
var processes dataModel.Processes
processes.Processes = []dataModel.Process{}
- for _, node := range nMap {
- if m.filterNode(node, Proc, filter) {
- process := *(node.object.(*dataModel.Process))
-
- // Append process to list
- processes.Processes = append(processes.Processes, process)
+ types := []string{NodeTypeUEApp, NodeTypeEdgeApp, NodeTypeCloudApp}
+ for _, typ := range types {
+ for _, nodes := range m.nodeMap.typeMap[typ] {
+ for _, node := range nodes {
+ if m.filterNode(node, Proc, filter) {
+ process := *(node.object.(*dataModel.Process))
+
+ // Append process to list
+ processes.Processes = append(processes.Processes, process)
+ }
+ }
}
}
return processes
@@ -1316,7 +1331,6 @@ func (m *Model) parseNodes() (err error) {
procCtx := NewNodeContext(m.scenario.Name, domain.Name, zone.Name, nl.Name, pl.Name)
m.nodeMap.AddNode(NewNode(proc.Id, proc.Name, proc.Type_, proc, nil, pl, procCtx))
m.networkGraph.AddNode(proc.Name, pl.Name, false)
-
// Update service map for external processes
if proc.IsExternal {
var nodeServiceMaps dataModel.NodeServiceMaps
diff --git a/go-packages/meep-model/nodeMap.go b/go-packages/meep-model/nodeMap.go
index 298fbb302cddb2dc12997a84c6f53cd76b98196e..f8c897400a59095e2e35b1a25425d24e24de4497 100644
--- a/go-packages/meep-model/nodeMap.go
+++ b/go-packages/meep-model/nodeMap.go
@@ -30,16 +30,16 @@ type Node struct {
// NodeMap - Model node map
type NodeMap struct {
idMap map[string]*Node
- nameMap map[string]*Node
- typeMap map[string]map[string]*Node
+ nameMap map[string][]*Node
+ typeMap map[string]map[string][]*Node
}
// NewNodeMap - allocate a blank NodeMap
func NewNodeMap() (nm *NodeMap) {
nm = new(NodeMap)
nm.idMap = make(map[string]*Node)
- nm.nameMap = make(map[string]*Node)
- nm.typeMap = make(map[string]map[string]*Node)
+ nm.nameMap = make(map[string][]*Node)
+ nm.typeMap = make(map[string]map[string][]*Node)
return nm
}
@@ -59,11 +59,14 @@ func NewNode(id string, name string, nodeType string, object interface{}, child
// AddNode - Add a node to the NodeMap
func (nm *NodeMap) AddNode(n *Node) {
nm.idMap[n.id] = n
- nm.nameMap[n.name] = n
+ nm.nameMap[n.name] = []*Node{n}
if nm.typeMap[n.nodeType] == nil {
- nm.typeMap[n.nodeType] = make(map[string]*Node)
+ nm.typeMap[n.nodeType] = make(map[string][]*Node)
}
- nm.typeMap[n.nodeType][n.name] = n
+ if nm.typeMap[n.nodeType][n.name] == nil {
+ nm.typeMap[n.nodeType][n.name] = []*Node{}
+ }
+ nm.typeMap[n.nodeType][n.name] = append(nm.typeMap[n.nodeType][n.name], n)
}
// FindById - find a node using its name
@@ -73,15 +76,25 @@ func (nm *NodeMap) FindById(id string) (n *Node) {
// FindByName - find a node using its name
func (nm *NodeMap) FindByName(name string) (n *Node) {
- return nm.nameMap[name]
+ nodes := nm.nameMap[name]
+ if len(nodes) > 0 {
+ return nodes[0]
+ }
+ return nil
}
// FindByType - find a node using its type - NOT SURE WE NEED THIS
-func (nm *NodeMap) FindByType(name string, nodeType string) (n *Node) {
+func (nm *NodeMap) FindByType(name string, nodeType string) []*Node {
return nm.typeMap[nodeType][name]
}
// FindAllByType - find a list of nodes using a type
func (nm *NodeMap) FindAllByType(nodeType string) map[string]*Node {
- return nm.typeMap[nodeType]
+ result := make(map[string]*Node)
+ for name, nodes := range nm.typeMap[nodeType] {
+ if len(nodes) > 0 {
+ result[name] = nodes[0]
+ }
+ }
+ return result
}
diff --git a/go-packages/meep-model/validator.go b/go-packages/meep-model/validator.go
index a102fd46565a6af11d835fc827048101c308378e..67fdfeee47abf97862bc9764bc4097843d076fa0 100644
--- a/go-packages/meep-model/validator.go
+++ b/go-packages/meep-model/validator.go
@@ -502,6 +502,9 @@ func validateScenario(scenario *dataModel.Scenario) error {
return err
}
+ // Name map for elements within this domain
+ domainNameMap := make(map[string]bool)
+
// Validate zones
for zoneIndex := range domain.Zones {
zone := &domain.Zones[zoneIndex]
@@ -509,7 +512,7 @@ func validateScenario(scenario *dataModel.Scenario) error {
if err := validateUniqueId(zone.Id, idMap); err != nil {
return err
}
- if err := validateUniqueName(zone.Name, nameMap); err != nil {
+ if err := validateUniqueName(zone.Name, domainNameMap); err != nil {
return err
}
@@ -520,7 +523,7 @@ func validateScenario(scenario *dataModel.Scenario) error {
if err := validateUniqueId(nl.Id, idMap); err != nil {
return err
}
- if err := validateUniqueName(nl.Name, nameMap); err != nil {
+ if err := validateUniqueName(nl.Name, domainNameMap); err != nil {
return err
}
@@ -533,7 +536,7 @@ func validateScenario(scenario *dataModel.Scenario) error {
if err := validateUniqueId(pl.Id, idMap); err != nil {
return err
}
- if err := validateUniqueName(pl.Name, nameMap); err != nil {
+ if err := validateUniqueName(pl.Name, domainNameMap); err != nil {
return err
}
@@ -546,9 +549,6 @@ func validateScenario(scenario *dataModel.Scenario) error {
if err := validateUniqueId(proc.Id, idMap); err != nil {
return err
}
- if err := validateUniqueName(proc.Name, nameMap); err != nil {
- return err
- }
}
}
}
diff --git a/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js b/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js
index 5ae54fdc25199f6d2d0a4cde50619731efad067f..4ed7e1f3d5058b8ae62292af66132d8a8d5b2b65 100644
--- a/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js
+++ b/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js
@@ -1363,33 +1363,41 @@ const TypeRelatedFormFields = ({ onUpdate, onEditLocation, onEditPath, element }
const cfgElementTypes = [
{
label: 'Logical Domain',
- options: [ELEMENT_TYPE_OPERATOR_GENERIC, ELEMENT_TYPE_OPERATOR_CELL]
+ options: [
+ { label: 'Generic', value: ELEMENT_TYPE_OPERATOR_GENERIC },
+ { label: 'Cellular', value: ELEMENT_TYPE_OPERATOR_CELL }
+ ]
},
{
label: 'Logical Zone',
- options: [ELEMENT_TYPE_ZONE]
+ options: [{ label: 'Zone', value: ELEMENT_TYPE_ZONE }]
},
{
label: 'Network Location',
- options: [ELEMENT_TYPE_POA_GENERIC, ELEMENT_TYPE_POA_4G, ELEMENT_TYPE_POA_5G, ELEMENT_TYPE_POA_WIFI]
+ options: [
+ { label: 'Generic', value: ELEMENT_TYPE_POA_GENERIC },
+ { label: '4G', value: ELEMENT_TYPE_POA_4G },
+ { label: '5G', value: ELEMENT_TYPE_POA_5G },
+ { label: 'WiFi', value: ELEMENT_TYPE_POA_WIFI }
+ ]
},
{
label: 'Physical Location',
options: [
- ELEMENT_TYPE_UE,
- ELEMENT_TYPE_FOG,
- ELEMENT_TYPE_EDGE,
- ELEMENT_TYPE_DC
- // ELEMENT_TYPE_CN
+ { label: 'Terminal', value: ELEMENT_TYPE_UE },
+ { label: 'Fog', value: ELEMENT_TYPE_FOG },
+ { label: 'Edge', value: ELEMENT_TYPE_EDGE },
+ { label: 'Distant Cloud', value: ELEMENT_TYPE_DC }
+ // { label: 'Core Network', value: ELEMENT_TYPE_CN }
]
},
{
label: 'Process',
options: [
- ELEMENT_TYPE_UE_APP,
- // ELEMENT_TYPE_MECSVC,
- ELEMENT_TYPE_EDGE_APP,
- ELEMENT_TYPE_CLOUD_APP
+ { label: 'Terminal Application', value: ELEMENT_TYPE_UE_APP },
+ // { label: 'MEC Service', value: ELEMENT_TYPE_MECSVC },
+ { label: 'Edge Application', value: ELEMENT_TYPE_EDGE_APP },
+ { label: 'Cloud Application', value: ELEMENT_TYPE_CLOUD_APP }
]
}
];
@@ -1398,9 +1406,9 @@ const execElementTypes = [
{
label: 'Process',
options: [
- ELEMENT_TYPE_UE_APP,
- ELEMENT_TYPE_EDGE_APP,
- ELEMENT_TYPE_CLOUD_APP
+ { label: 'Terminal Application', value: ELEMENT_TYPE_UE_APP },
+ { label: 'Edge Application', value: ELEMENT_TYPE_EDGE_APP },
+ { label: 'Cloud Application', value: ELEMENT_TYPE_CLOUD_APP }
]
}
];
diff --git a/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js b/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js
index 30a19d518d49443025f8f3067855849d7a7bab45..7e4e1b9bca3cbc6ffd50b604482945cb198c0851 100644
--- a/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js
+++ b/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js
@@ -68,7 +68,19 @@ import {
IDC_DIALOG_EXPORT_SCENARIO,
ELEMENT_TYPE_POA_4G,
ELEMENT_TYPE_POA_5G,
- ELEMENT_TYPE_POA_WIFI
+ ELEMENT_TYPE_POA_WIFI,
+ ELEMENT_TYPE_UE,
+ ELEMENT_TYPE_FOG,
+ ELEMENT_TYPE_EDGE,
+ ELEMENT_TYPE_DC,
+ ELEMENT_TYPE_CN,
+ ELEMENT_TYPE_UE_APP,
+ ELEMENT_TYPE_EDGE_APP,
+ ELEMENT_TYPE_CLOUD_APP,
+ ELEMENT_TYPE_OPERATOR,
+ ELEMENT_TYPE_OPERATOR_CELL,
+ ELEMENT_TYPE_ZONE,
+ ELEMENT_TYPE_POA
} from '../../meep-constants';
import {
@@ -89,6 +101,7 @@ import {
FIELD_MEMORY_MIN,
FIELD_MEMORY_MAX
} from '../../util/elem-utils';
+import { getElementFromScenario, updateElementInScenario } from '../../util/scenario-utils';
import { pipe, filter } from '../../util/functional';
@@ -137,6 +150,30 @@ export const validateNetworkElement = (element, entries, elemSetErrMsg) => {
return false;
}
+ // Check if type is valid
+ const validTypes = [
+ ELEMENT_TYPE_SCENARIO,
+ ELEMENT_TYPE_OPERATOR,
+ ELEMENT_TYPE_OPERATOR_CELL,
+ ELEMENT_TYPE_ZONE,
+ ELEMENT_TYPE_POA,
+ ELEMENT_TYPE_POA_4G,
+ ELEMENT_TYPE_POA_5G,
+ ELEMENT_TYPE_POA_WIFI,
+ ELEMENT_TYPE_UE,
+ ELEMENT_TYPE_FOG,
+ ELEMENT_TYPE_EDGE,
+ ELEMENT_TYPE_DC,
+ ELEMENT_TYPE_CN,
+ ELEMENT_TYPE_UE_APP,
+ ELEMENT_TYPE_EDGE_APP,
+ ELEMENT_TYPE_CLOUD_APP
+ ];
+ if (!validTypes.includes(type)) {
+ elemSetErrMsg('Invalid element type: ' + type);
+ return false;
+ }
+
// Check for valid & unique network element name (except if editing)
var name = getElemFieldVal(element, FIELD_NAME);
if (name === null || name === '') {
@@ -144,10 +181,10 @@ export const validateNetworkElement = (element, entries, elemSetErrMsg) => {
return false;
}
- if (data[name] && data[name].id !== element.id) {
- elemSetErrMsg('Element name already exists');
- return false;
- }
+ // if (data[name] && data[name].id !== element.id) {
+ // elemSetErrMsg('Element name already exists');
+ // return false;
+ // }
// Nothing else to validate for Scenario element
if (type === ELEMENT_TYPE_SCENARIO) {
@@ -155,9 +192,16 @@ export const validateNetworkElement = (element, entries, elemSetErrMsg) => {
}
// Make sure parent exists
- if (!data[getElemFieldVal(element, FIELD_PARENT)]) {
- elemSetErrMsg('Parent does not exist');
- return false;
+ var parentName = getElemFieldVal(element, FIELD_PARENT);
+ if (parentName) {
+ parentName = parentName.trim();
+ if (!Object.values(data).some(e => {
+ const eName = getElemFieldVal(e, FIELD_NAME);
+ return eName && eName.trim() === parentName;
+ })) {
+ elemSetErrMsg('Parent does not exist');
+ return false;
+ }
}
// If GPU requested, make sure type is set
@@ -245,16 +289,16 @@ class CfgPageContainer extends Component {
}
// EDIT
- onEditElement(element) {
- if (element !== null) {
- if (!this.props.configuredElement || (element.id !== this.props.configuredElement.id)) {
- resetElem(element);
+ onEditElement(element) {
+ if (element !== null) {
+ // Always fetch the full element from the scenario by ID
+ // let element = getElementFromScenario(this.props.cfg.scenario, element.id);
+ //resetElem(element);
this.props.cfgElemEdit(element);
+ } else {
+ this.props.cfgElemClear();
}
- } else {
- this.props.cfgElemClear();
}
- }
// SAVE
onSaveElement(element) {
@@ -270,6 +314,11 @@ class CfgPageContainer extends Component {
this.props.updateScenarioElem(element);
}
+ // Update scenario for canvas reflection
+ // let updatedScenario = JSON.parse(JSON.stringify(this.props.cfg.scenario));
+ // updateElementInScenario(updatedScenario, element);
+ // this.props.changeScenario(updatedScenario);
+
// Reset Element configuration pane
this.props.cfgElemClear();
}
@@ -288,8 +337,10 @@ class CfgPageContainer extends Component {
this.props.cloneScenarioElem(element);
- //force update on the visual aspect of the scenario
- //this.props.updateScenario();
+ // Update scenario for canvas reflection
+ const updatedScenario = JSON.parse(JSON.stringify(this.props.cfg.scenario));
+ updateElementInScenario(updatedScenario, element);
+ this.props.changeScenario(updatedScenario);
this.props.cfgElemClear();
}
@@ -467,6 +518,11 @@ class CfgPageContainer extends Component {
const scenarioCopy = JSON.parse(JSON.stringify(cfg.scenario));
scenarioCopy.name = scenarioName;
+ // Update scenario with configured elements
+ Object.values(cfg.table.entries).forEach(element => {
+ updateElementInScenario(scenarioCopy, element);
+ });
+
// Create new scenario if scenario is new
if (cfg.state === CFG_STATE_NEW || scenarioName !== cfg.scenario.name) {
this.props.api.createScenario(
@@ -737,7 +793,7 @@ class CfgPageContainer extends Component {
type={TYPE_CFG}
onNewElement={() => this.onNewElement()}
onEditElement={elem => this.onEditElement(elem)}
- onDeleteElement={() => this.onDeleteElement()}
+ onDeleteElement={elem => this.onDeleteElement(elem)}
onApplyCloneElement={elem => this.onApplyCloneElement(elem)}
/>
diff --git a/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js b/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js
index 6ebb5f1ac96c5eb3a42c14879a402f83391caf28..f000768bf643f65aa6f0973c0d48542faf29d40d 100644
--- a/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js
+++ b/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js
@@ -95,10 +95,15 @@ class CfgTable extends Component {
this.props.changeTable(table);
}
- onClick(/*event, name*/) {
- // var table = updateObject({}, this.props.table);
- // handleClick(table, event, name);
- // this.props.changeTable(table);
+ onClick(event, elem) {
+ // Select by unique id
+ var table = updateObject({}, this.props.table);
+ table.selected = [elem.id];
+ this.props.changeTable(table);
+ // Call parent handler to open config panel for this element
+ if (this.props.onEditElement) {
+ this.props.onEditElement(elem);
+ }
}
onChangePage(event, page) {
@@ -198,15 +203,16 @@ class CfgTable extends Component {
const name = getElemFieldVal(elem, FIELD_NAME);
const type = getElemFieldVal(elem, FIELD_TYPE);
const parent = getElemFieldVal(elem, FIELD_PARENT);
- const isSelected = isRowSelected(table, name);
+ const id = elem.id;
+ const isSelected = table.selected && table.selected[0] === id;
return (