Loading examples/demo3/src/api/swagger.yaml +116 −2 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ paths: post: tags: - frontend_mec_service description: Create a new application mobility service for the service requester. description: Create a new application mobility service for the service requester & create subscription to ams. responses: "200": description: OK Loading @@ -62,8 +62,29 @@ paths: /services/callback/amsevent: post: tags: - frontend_mec_service - 'frontend_notification' summary: MEC021 ams notifcation description: Handle Application Mobility Service notifications. requestBody: description: Subscription notification content: application/json: schema: $ref: '#/components/schemas/MobilityProcedureNotification' required: true responses: "200": description: OK "400": description: Bad request "404": description: Not found /ams/subscriptions: post: tags: - frontend_mec_service description: 'Create a new subscription to Application Mobility Service notifications.' operationId: AmsSubscriptionPOST responses: "200": description: OK Loading Loading @@ -194,6 +215,99 @@ components: self: href: http://example.com/aeiou callbackReference: http://example.com/aeiou MobilityProcedureNotification: required: - mobilityStatus - notificationType type: object properties: associateId: minItems: 0 type: array description: 0 to N identifiers to associate the information for specific UE(s) and flow(s). items: $ref: '#/components/schemas/AssociateId' x-etsi-mec-cardinality: 0..N x-etsi-mec-origin-type: AssociateId mobilityStatus: type: integer description: 'Indicate the status of the UE mobility. Values are defined as following: 1 = INTERHOST_MOVEOUT_TRIGGERED. 2 = INTERHOST_MOVEOUT_COMPLETED. 3 = INTERHOST_MOVEOUT_FAILED. Other values are reserved.' x-etsi-mec-cardinality: "1" notificationType: type: string description: Shall be set to \"MobilityProcedureNotification\". x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: String targetAppInfo: $ref: '#/components/schemas/MobilityProcedureNotification_targetAppInfo' timeStamp: $ref: '#/components/schemas/TimeStamp' x-etsi-ref: 7.4.2 TimeStamp: required: - nanoSeconds - seconds type: object properties: nanoSeconds: type: integer description: The nanoseconds part of the time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC. format: int32 x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: Uint32 seconds: type: integer description: The seconds part of the time. Time is defined as Unixtime since January 1, 1970, 00:00:00 UTC. format: int32 x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: Uint32 MobilityProcedureNotification_targetAppInfo: type: object properties: appInstanceId: type: string example: '10.100.0.3' description: Identifiers of the target application instance. x-etsi-mec-cardinality: 0..1 x-etsi-mec-origin-type: String commInterface: $ref: '#/components/schemas/CommunicationInterface' description: Identifiers to associate the information of target application instance. CommunicationInterface: properties: ipAddresses: type: array items: $ref: '#/components/schemas/CommunicationInterface_ipAddresses' example: ipAddresses: - port: 0 host: host - port: 0 host: host AssociateId: properties: type: type: integer description: 'Numeric value (0-255) corresponding to specified type of identifier as following: <p>0 = reserved. <p>1 = UE_IPv4_ADDRESS. <p>2 = UE_IPV6_ADDRESS. <p>3 = NATED_IP_ADDRESS. <p>4 = GTP_TEID.' x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: Enum value: type: string description: Value for the identifier. x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: String example: type: 0 value: value AppTerminationNotificationSubscription__links: required: - self Loading examples/demo3/src/server/api_frontend_mec_service.go +4 −0 Original line number Diff line number Diff line Loading @@ -42,3 +42,7 @@ func ServicesDiscoverPost(w http.ResponseWriter, r *http.Request) { func AmsCreatePOST(w http.ResponseWriter, r *http.Request) { amsCreatePOST(w, r) } func AmsSubscriptionPOST(w http.ResponseWriter, r *http.Request) { amsSubscriptionPOST(w, r) } examples/demo3/src/server/api_frontend_notification.go +4 −0 Original line number Diff line number Diff line Loading @@ -34,3 +34,7 @@ func NotificationPOST(w http.ResponseWriter, r *http.Request) { func TerminateNotificatonPOST(w http.ResponseWriter, r *http.Request) { terminateNotificatonPOST(w, r) } func AmsNotificationPOST(w http.ResponseWriter, r *http.Request) { amsNotificationPOST(w, r) } examples/demo3/src/server/demo3_service.go +176 −14 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import ( "context" "encoding/json" "errors" "fmt" "net/http" "strings" "sync" Loading Loading @@ -42,12 +43,16 @@ var appEnablementServiceId string var serviceSubscriptionId string var registeredService bool var terminationSubscriptionId string var mep string var amsSubscriptionId string var serviceName string = "user-app" var scopeOfLocality string = defaultScopeOfLocality var consumedLocalOnly bool = defaultConsumedLocalOnly var terminationSubscription bool = false var terminated bool = false var terminateNotification bool = false var amsSubscriptionSent bool = false const serviceAppVersion = "2.1.1" const local = "http://10.190.115.162" Loading @@ -71,6 +76,14 @@ func Init(envPath string, envName string) (port string, err error) { // Retrieve sandbox url from config mecUrl = config.SandboxUrl // Parse mec platfor mep no. use for ams service resp := strings.LastIndex(mecUrl, "/") if resp == -1 { log.Fatal("Error parsing mep no. from config") } else { mep = mecUrl[resp+1:] } // Retreieve local url from config localPort = config.Port Loading Loading @@ -99,7 +112,10 @@ func Init(envPath string, envName string) (port string, err error) { // Create application mobility suppport client amsClientcfg := ams.NewConfiguration() amsClientcfg.BasePath = mecUrl + "/amsi/v1" // Replace amsUrl with mep1 to demonstrate use-case of ams api amsUrl := strings.Replace(mecUrl, "mep2", "mep1", 1) amsClientcfg.BasePath = amsUrl + "/amsi/v1" amsClient = ams.NewAPIClient(amsClientcfg) amsClientPath = amsClientcfg.BasePath if amsClient == nil { Loading Loading @@ -171,10 +187,10 @@ func notificationPOST(w http.ResponseWriter, r *http.Request) { } // Rest API // Create mec service // Create mec service only if none created func servicePOST(w http.ResponseWriter, r *http.Request) { // Lock registered service to prevent creating more than one mec service // Lock registered service to prevent creating more than one mec service from multiple client concurrently mutex.Lock() defer mutex.Unlock() if !registeredService { Loading @@ -185,10 +201,15 @@ func servicePOST(w http.ResponseWriter, r *http.Request) { } registeredService = true w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Sucessfully created a service") return } w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Service already created") } // Rest API - delete mec service // Rest API // Delete mec service only if present func serviceDELETE(w http.ResponseWriter, r *http.Request) { mutex.Lock() Loading @@ -203,7 +224,9 @@ func serviceDELETE(w http.ResponseWriter, r *http.Request) { registeredService = false log.Info(serviceName, " service deleted") w.WriteHeader(http.StatusOK) return } fmt.Fprintf(w, "Need to create a service first") } // Rest API Loading @@ -219,13 +242,137 @@ func terminateNotificatonPOST(w http.ResponseWriter, r *http.Request) { } log.Info("Received user-app termination notification") w.WriteHeader(http.StatusOK) terminateNotification = true Terminate() } // Rest API // Register MEC Application instances with AMS // Handle AMS notification func amsNotificationPOST(w http.ResponseWriter, r *http.Request) { var amsNotification ams.MobilityProcedureNotification decoder := json.NewDecoder(r.Body) err := decoder.Decode(&amsNotification) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Should put to AMS log.Info("AMS event received for ", amsNotification.AssociateId[0].Value, " to ", amsNotification.TargetAppInfo.AppInstanceId) w.WriteHeader(http.StatusOK) } // Rest API // Submit AMS subscription to mec platform func amsSubscriptionPOST(w http.ResponseWriter, r *http.Request) { err := amsSendSubscription(instanceName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } // Rest API // Register MEC Application instances with AMS & consume servicee func amsCreatePOST(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) err := amsSendService(instanceName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } // CLient request to create a new application mobility service func amsSendService(appInstanceId string) error { log.Debug("Sending request to mec platform create ams api") var bodyRegisterationInfo ams.RegistrationInfo bodyRegisterationInfo.ServiceConsumerId = &ams.RegistrationInfoServiceConsumerId{ AppInstanceId: appInstanceId, } // Provide device info only specific to mep1 platform if mep == "mep1" { var associateId ams.AssociateId associateId.Type_ = 1 associateId.Value = "10.100.0.10" bodyRegisterationInfo.DeviceInformation = append(bodyRegisterationInfo.DeviceInformation, ams.RegistrationInfoDeviceInformation{AssociateId: &associateId, AppMobilityServiceLevel: 3, ContextTransferState: 0, }) } _, _, err := amsClient.AmsiApi.AppMobilityServicePOST(context.TODO(), bodyRegisterationInfo) if err != nil { log.Error(err) return err } else { log.Info("Consumed AMS service sucessfully") } return nil } // CLient request to create a new application mobility service func amsSendSubscription(appInstanceId string) error { log.Debug("Sending request to mec platform add ams subscription api") var mobilityProcedureSubscription ams.MobilityProcedureSubscription // Add body param callback ref mobilityProcedureSubscription.CallbackReference = local + localPort + "/subscriptions" mobilityProcedureSubscription.SubscriptionType = "MobilityProcedureSubscription" // Default tracking ue set to 10.100.0.3 var associateId ams.AssociateId associateId.Type_ = 1 associateId.Value = "10.100.0.3" // Filter criteria var mobilityFiler ams.MobilityProcedureSubscriptionFilterCriteria mobilityFiler.AppInstanceId = appInstanceId mobilityFiler.AssociateId = append(mobilityFiler.AssociateId, associateId) mobilityProcedureSubscription.FilterCriteria = &mobilityFiler inlineSubscription := ams.ConvertMobilityProcedureSubscriptionToInlineSubscription(&mobilityProcedureSubscription) mobilitySubscription, resp, err := amsClient.AmsiApi.SubPOST(context.TODO(), *inlineSubscription) hRefLink := mobilitySubscription.Links.Self.Href // Find subscription id from response idPosition := strings.LastIndex(hRefLink, "/") if idPosition == -1 { log.Error("Error parsing subscription id for subscription") return err } amsSubscriptionId = hRefLink[idPosition+1:] if err != nil { log.Error(resp.Status) return err } else { amsSubscriptionSent = true log.Info("Successfully created ams subscription") } return nil } // Client request to delete ams subscription func deleteAmsSubscription(subscriptionId string) error { log.Debug("Sending request to mec platform delete ams susbcription api") if amsSubscriptionSent { resp, err := amsClient.AmsiApi.AppMobilityServiceByIdDELETE(context.TODO(), subscriptionId) if err != nil { log.Info("Failed to delete ams subcription ", resp.Status) return err } } return nil } // Client request to notify mec platform of mec app Loading @@ -244,7 +391,7 @@ func sendReadyConfirmation(appInstanceId string) error { // Client request to retrieve list of mec service resources on sandbox func getMecServices() error { appServicesPostResponse, resp, err := srvMgmtClient.MecServiceMgmtApi.ServicesGET(context.TODO(), nil) log.Debug("Sending request to mec platform get services api ") //srvMgmtClientPath log.Debug("Sending request to mec platform get services api ") if err != nil { log.Error("Failed to fetch services on mec platform ", resp.Status) return err Loading Loading @@ -331,7 +478,7 @@ func unregisterService(appInstanceId string, serviceId string) error { // Client request to subscribe service-availability notifications func subscribeAvailability(appInstanceId string, callbackReference string) error { log.Debug("Sending request to mec platform add subscription api") //srvMgmtClientPath log.Debug("Sending request to mec platform add subscription api") var filter smc.SerAvailabilityNotificationSubscriptionFilteringCriteria filter.SerNames = nil filter.IsLocal = true Loading @@ -357,10 +504,16 @@ func subscribeAvailability(appInstanceId string, callbackReference string) error } // Client request to sent confirm terminate func confirmTerminate(appInstanceId string, subscriptionId string) { resp, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionDELETE(context.TODO(), appInstanceId, subscriptionId) func confirmTerminate(appInstanceId string) { operationAction := asc.TERMINATING_OperationActionType var terminationBody asc.AppTerminationConfirmation terminationBody.OperationAction = &operationAction resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmTerminationPOST(context.TODO(), terminationBody, appInstanceId) if err != nil { log.Error("Failed to send confirm termination ", resp.Status) } else { log.Info("Confirm Terminated") } } Loading Loading @@ -435,11 +588,9 @@ func Run() { } // Terminate by deleting all resources allocated on MEC platform & mec app // Delete service & app subscription & registered services func Terminate() { // Only invoke graceful termination if terminated is false // One can trigger terminate by receiving a termination notification if !terminated { //Delete app subscriptions err := delAppTerminationSubscription(instanceName, terminationSubscriptionId) Loading @@ -447,9 +598,6 @@ func Terminate() { log.Info("Cleared app enablement subscription on mec platform") } //Send Confirm Terminate confirmTerminate(instanceName, terminationSubscriptionId) // Delete service subscriptions if subscriptionSent { err := delsubscribeAvailability(instanceName, serviceSubscriptionId) Loading @@ -465,6 +613,20 @@ func Terminate() { log.Info("Cleared user-app services on mec platform") } } // Delete ams subscriptions if amsSubscriptionSent { err := deleteAmsSubscription(amsSubscriptionId) if err == nil { log.Info("Cleared ams subcription on mec platform") } } //Send Confirm Terminate if received notification if terminateNotification { confirmTerminate(instanceName) } terminated = true } Loading examples/demo3/src/server/routers.go +13 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,19 @@ var routes = Routes{ Route{ "AmsCreatePOST", strings.ToUpper("post"), "/service/create/ams", "/service/ams/create", AmsCreatePOST, }, Route{ "AmsSubscriptionPOST", strings.ToUpper("post"), "/ams/subscriptions", AmsSubscriptionPOST, }, Route{ "AmsNotificationPOST", strings.ToUpper("post"), "/services/callback/amsevent", AmsNotificationPOST, }, } Loading
examples/demo3/src/api/swagger.yaml +116 −2 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ paths: post: tags: - frontend_mec_service description: Create a new application mobility service for the service requester. description: Create a new application mobility service for the service requester & create subscription to ams. responses: "200": description: OK Loading @@ -62,8 +62,29 @@ paths: /services/callback/amsevent: post: tags: - frontend_mec_service - 'frontend_notification' summary: MEC021 ams notifcation description: Handle Application Mobility Service notifications. requestBody: description: Subscription notification content: application/json: schema: $ref: '#/components/schemas/MobilityProcedureNotification' required: true responses: "200": description: OK "400": description: Bad request "404": description: Not found /ams/subscriptions: post: tags: - frontend_mec_service description: 'Create a new subscription to Application Mobility Service notifications.' operationId: AmsSubscriptionPOST responses: "200": description: OK Loading Loading @@ -194,6 +215,99 @@ components: self: href: http://example.com/aeiou callbackReference: http://example.com/aeiou MobilityProcedureNotification: required: - mobilityStatus - notificationType type: object properties: associateId: minItems: 0 type: array description: 0 to N identifiers to associate the information for specific UE(s) and flow(s). items: $ref: '#/components/schemas/AssociateId' x-etsi-mec-cardinality: 0..N x-etsi-mec-origin-type: AssociateId mobilityStatus: type: integer description: 'Indicate the status of the UE mobility. Values are defined as following: 1 = INTERHOST_MOVEOUT_TRIGGERED. 2 = INTERHOST_MOVEOUT_COMPLETED. 3 = INTERHOST_MOVEOUT_FAILED. Other values are reserved.' x-etsi-mec-cardinality: "1" notificationType: type: string description: Shall be set to \"MobilityProcedureNotification\". x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: String targetAppInfo: $ref: '#/components/schemas/MobilityProcedureNotification_targetAppInfo' timeStamp: $ref: '#/components/schemas/TimeStamp' x-etsi-ref: 7.4.2 TimeStamp: required: - nanoSeconds - seconds type: object properties: nanoSeconds: type: integer description: The nanoseconds part of the time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC. format: int32 x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: Uint32 seconds: type: integer description: The seconds part of the time. Time is defined as Unixtime since January 1, 1970, 00:00:00 UTC. format: int32 x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: Uint32 MobilityProcedureNotification_targetAppInfo: type: object properties: appInstanceId: type: string example: '10.100.0.3' description: Identifiers of the target application instance. x-etsi-mec-cardinality: 0..1 x-etsi-mec-origin-type: String commInterface: $ref: '#/components/schemas/CommunicationInterface' description: Identifiers to associate the information of target application instance. CommunicationInterface: properties: ipAddresses: type: array items: $ref: '#/components/schemas/CommunicationInterface_ipAddresses' example: ipAddresses: - port: 0 host: host - port: 0 host: host AssociateId: properties: type: type: integer description: 'Numeric value (0-255) corresponding to specified type of identifier as following: <p>0 = reserved. <p>1 = UE_IPv4_ADDRESS. <p>2 = UE_IPV6_ADDRESS. <p>3 = NATED_IP_ADDRESS. <p>4 = GTP_TEID.' x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: Enum value: type: string description: Value for the identifier. x-etsi-mec-cardinality: "1" x-etsi-mec-origin-type: String example: type: 0 value: value AppTerminationNotificationSubscription__links: required: - self Loading
examples/demo3/src/server/api_frontend_mec_service.go +4 −0 Original line number Diff line number Diff line Loading @@ -42,3 +42,7 @@ func ServicesDiscoverPost(w http.ResponseWriter, r *http.Request) { func AmsCreatePOST(w http.ResponseWriter, r *http.Request) { amsCreatePOST(w, r) } func AmsSubscriptionPOST(w http.ResponseWriter, r *http.Request) { amsSubscriptionPOST(w, r) }
examples/demo3/src/server/api_frontend_notification.go +4 −0 Original line number Diff line number Diff line Loading @@ -34,3 +34,7 @@ func NotificationPOST(w http.ResponseWriter, r *http.Request) { func TerminateNotificatonPOST(w http.ResponseWriter, r *http.Request) { terminateNotificatonPOST(w, r) } func AmsNotificationPOST(w http.ResponseWriter, r *http.Request) { amsNotificationPOST(w, r) }
examples/demo3/src/server/demo3_service.go +176 −14 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import ( "context" "encoding/json" "errors" "fmt" "net/http" "strings" "sync" Loading Loading @@ -42,12 +43,16 @@ var appEnablementServiceId string var serviceSubscriptionId string var registeredService bool var terminationSubscriptionId string var mep string var amsSubscriptionId string var serviceName string = "user-app" var scopeOfLocality string = defaultScopeOfLocality var consumedLocalOnly bool = defaultConsumedLocalOnly var terminationSubscription bool = false var terminated bool = false var terminateNotification bool = false var amsSubscriptionSent bool = false const serviceAppVersion = "2.1.1" const local = "http://10.190.115.162" Loading @@ -71,6 +76,14 @@ func Init(envPath string, envName string) (port string, err error) { // Retrieve sandbox url from config mecUrl = config.SandboxUrl // Parse mec platfor mep no. use for ams service resp := strings.LastIndex(mecUrl, "/") if resp == -1 { log.Fatal("Error parsing mep no. from config") } else { mep = mecUrl[resp+1:] } // Retreieve local url from config localPort = config.Port Loading Loading @@ -99,7 +112,10 @@ func Init(envPath string, envName string) (port string, err error) { // Create application mobility suppport client amsClientcfg := ams.NewConfiguration() amsClientcfg.BasePath = mecUrl + "/amsi/v1" // Replace amsUrl with mep1 to demonstrate use-case of ams api amsUrl := strings.Replace(mecUrl, "mep2", "mep1", 1) amsClientcfg.BasePath = amsUrl + "/amsi/v1" amsClient = ams.NewAPIClient(amsClientcfg) amsClientPath = amsClientcfg.BasePath if amsClient == nil { Loading Loading @@ -171,10 +187,10 @@ func notificationPOST(w http.ResponseWriter, r *http.Request) { } // Rest API // Create mec service // Create mec service only if none created func servicePOST(w http.ResponseWriter, r *http.Request) { // Lock registered service to prevent creating more than one mec service // Lock registered service to prevent creating more than one mec service from multiple client concurrently mutex.Lock() defer mutex.Unlock() if !registeredService { Loading @@ -185,10 +201,15 @@ func servicePOST(w http.ResponseWriter, r *http.Request) { } registeredService = true w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Sucessfully created a service") return } w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Service already created") } // Rest API - delete mec service // Rest API // Delete mec service only if present func serviceDELETE(w http.ResponseWriter, r *http.Request) { mutex.Lock() Loading @@ -203,7 +224,9 @@ func serviceDELETE(w http.ResponseWriter, r *http.Request) { registeredService = false log.Info(serviceName, " service deleted") w.WriteHeader(http.StatusOK) return } fmt.Fprintf(w, "Need to create a service first") } // Rest API Loading @@ -219,13 +242,137 @@ func terminateNotificatonPOST(w http.ResponseWriter, r *http.Request) { } log.Info("Received user-app termination notification") w.WriteHeader(http.StatusOK) terminateNotification = true Terminate() } // Rest API // Register MEC Application instances with AMS // Handle AMS notification func amsNotificationPOST(w http.ResponseWriter, r *http.Request) { var amsNotification ams.MobilityProcedureNotification decoder := json.NewDecoder(r.Body) err := decoder.Decode(&amsNotification) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Should put to AMS log.Info("AMS event received for ", amsNotification.AssociateId[0].Value, " to ", amsNotification.TargetAppInfo.AppInstanceId) w.WriteHeader(http.StatusOK) } // Rest API // Submit AMS subscription to mec platform func amsSubscriptionPOST(w http.ResponseWriter, r *http.Request) { err := amsSendSubscription(instanceName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } // Rest API // Register MEC Application instances with AMS & consume servicee func amsCreatePOST(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) err := amsSendService(instanceName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } // CLient request to create a new application mobility service func amsSendService(appInstanceId string) error { log.Debug("Sending request to mec platform create ams api") var bodyRegisterationInfo ams.RegistrationInfo bodyRegisterationInfo.ServiceConsumerId = &ams.RegistrationInfoServiceConsumerId{ AppInstanceId: appInstanceId, } // Provide device info only specific to mep1 platform if mep == "mep1" { var associateId ams.AssociateId associateId.Type_ = 1 associateId.Value = "10.100.0.10" bodyRegisterationInfo.DeviceInformation = append(bodyRegisterationInfo.DeviceInformation, ams.RegistrationInfoDeviceInformation{AssociateId: &associateId, AppMobilityServiceLevel: 3, ContextTransferState: 0, }) } _, _, err := amsClient.AmsiApi.AppMobilityServicePOST(context.TODO(), bodyRegisterationInfo) if err != nil { log.Error(err) return err } else { log.Info("Consumed AMS service sucessfully") } return nil } // CLient request to create a new application mobility service func amsSendSubscription(appInstanceId string) error { log.Debug("Sending request to mec platform add ams subscription api") var mobilityProcedureSubscription ams.MobilityProcedureSubscription // Add body param callback ref mobilityProcedureSubscription.CallbackReference = local + localPort + "/subscriptions" mobilityProcedureSubscription.SubscriptionType = "MobilityProcedureSubscription" // Default tracking ue set to 10.100.0.3 var associateId ams.AssociateId associateId.Type_ = 1 associateId.Value = "10.100.0.3" // Filter criteria var mobilityFiler ams.MobilityProcedureSubscriptionFilterCriteria mobilityFiler.AppInstanceId = appInstanceId mobilityFiler.AssociateId = append(mobilityFiler.AssociateId, associateId) mobilityProcedureSubscription.FilterCriteria = &mobilityFiler inlineSubscription := ams.ConvertMobilityProcedureSubscriptionToInlineSubscription(&mobilityProcedureSubscription) mobilitySubscription, resp, err := amsClient.AmsiApi.SubPOST(context.TODO(), *inlineSubscription) hRefLink := mobilitySubscription.Links.Self.Href // Find subscription id from response idPosition := strings.LastIndex(hRefLink, "/") if idPosition == -1 { log.Error("Error parsing subscription id for subscription") return err } amsSubscriptionId = hRefLink[idPosition+1:] if err != nil { log.Error(resp.Status) return err } else { amsSubscriptionSent = true log.Info("Successfully created ams subscription") } return nil } // Client request to delete ams subscription func deleteAmsSubscription(subscriptionId string) error { log.Debug("Sending request to mec platform delete ams susbcription api") if amsSubscriptionSent { resp, err := amsClient.AmsiApi.AppMobilityServiceByIdDELETE(context.TODO(), subscriptionId) if err != nil { log.Info("Failed to delete ams subcription ", resp.Status) return err } } return nil } // Client request to notify mec platform of mec app Loading @@ -244,7 +391,7 @@ func sendReadyConfirmation(appInstanceId string) error { // Client request to retrieve list of mec service resources on sandbox func getMecServices() error { appServicesPostResponse, resp, err := srvMgmtClient.MecServiceMgmtApi.ServicesGET(context.TODO(), nil) log.Debug("Sending request to mec platform get services api ") //srvMgmtClientPath log.Debug("Sending request to mec platform get services api ") if err != nil { log.Error("Failed to fetch services on mec platform ", resp.Status) return err Loading Loading @@ -331,7 +478,7 @@ func unregisterService(appInstanceId string, serviceId string) error { // Client request to subscribe service-availability notifications func subscribeAvailability(appInstanceId string, callbackReference string) error { log.Debug("Sending request to mec platform add subscription api") //srvMgmtClientPath log.Debug("Sending request to mec platform add subscription api") var filter smc.SerAvailabilityNotificationSubscriptionFilteringCriteria filter.SerNames = nil filter.IsLocal = true Loading @@ -357,10 +504,16 @@ func subscribeAvailability(appInstanceId string, callbackReference string) error } // Client request to sent confirm terminate func confirmTerminate(appInstanceId string, subscriptionId string) { resp, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionDELETE(context.TODO(), appInstanceId, subscriptionId) func confirmTerminate(appInstanceId string) { operationAction := asc.TERMINATING_OperationActionType var terminationBody asc.AppTerminationConfirmation terminationBody.OperationAction = &operationAction resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmTerminationPOST(context.TODO(), terminationBody, appInstanceId) if err != nil { log.Error("Failed to send confirm termination ", resp.Status) } else { log.Info("Confirm Terminated") } } Loading Loading @@ -435,11 +588,9 @@ func Run() { } // Terminate by deleting all resources allocated on MEC platform & mec app // Delete service & app subscription & registered services func Terminate() { // Only invoke graceful termination if terminated is false // One can trigger terminate by receiving a termination notification if !terminated { //Delete app subscriptions err := delAppTerminationSubscription(instanceName, terminationSubscriptionId) Loading @@ -447,9 +598,6 @@ func Terminate() { log.Info("Cleared app enablement subscription on mec platform") } //Send Confirm Terminate confirmTerminate(instanceName, terminationSubscriptionId) // Delete service subscriptions if subscriptionSent { err := delsubscribeAvailability(instanceName, serviceSubscriptionId) Loading @@ -465,6 +613,20 @@ func Terminate() { log.Info("Cleared user-app services on mec platform") } } // Delete ams subscriptions if amsSubscriptionSent { err := deleteAmsSubscription(amsSubscriptionId) if err == nil { log.Info("Cleared ams subcription on mec platform") } } //Send Confirm Terminate if received notification if terminateNotification { confirmTerminate(instanceName) } terminated = true } Loading
examples/demo3/src/server/routers.go +13 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,19 @@ var routes = Routes{ Route{ "AmsCreatePOST", strings.ToUpper("post"), "/service/create/ams", "/service/ams/create", AmsCreatePOST, }, Route{ "AmsSubscriptionPOST", strings.ToUpper("post"), "/ams/subscriptions", AmsSubscriptionPOST, }, Route{ "AmsNotificationPOST", strings.ToUpper("post"), "/services/callback/amsevent", AmsNotificationPOST, }, }