Commit ce0c0e9d authored by supermikii's avatar supermikii
Browse files

feat demo 3 ams usecase starter + refactor app-enablement usecase

parent c6e481a3
Loading
Loading
Loading
Loading
+119 −101
Original line number Diff line number Diff line
openapi: 3.0.2
info:
  title: MEC Demo 3 API
  description: This section describes use case 3 - 5 that the user can accomplish
    using the MEC Sandbox APIs from a MEC application
  contact:
    name: InterDigital AdvantEDGE Support
    email: AdvantEDGE@InterDigital.com
  description: This section describes use case 3 - 5 that the user can accomplish using
    the MEC Sandbox APIs from a MEC application
  license:
    name: Apache 2.0
    url: https://github.com/InterDigitalInc/AdvantEDGE/blob/master/LICENSE
    url: http://www.apache.org/licenses/LICENSE-2.0
  version: 0.0.1
servers:
- url: http://10.190.115.162:8093
- url: http://10.190.115.162:8094
- url: 'http://10.190.115.162:8093'
- url: 'http://10.190.115.162:8094'
paths:
  /services/discover:
    post:
      tags:
      - frontend_mec_service
      description: This method retrieves information about a list of mec service resources
        & subscribes to service availability notification subscription
      description: This method retrieves information about a list of mec service resources & subscribes to service availability notification subscription
      responses:
        "200":
          description: OK
@@ -43,8 +39,7 @@ paths:
    delete:
      tags:
      - frontend_mec_service
      description: This method deletes a mecService resource. This method is typically
        used in the service deregistration procedure.
      description: This method deletes a mecService resource. This method is typically used in the service deregistration procedure.
      responses:
        "200":
          description: OK
@@ -52,20 +47,11 @@ paths:
          description: Bad request
        "404":
          description: Not found
  /services/callback/service-availability:
  /service/ams/create: 
    post: 
      tags:
      - frontend_notification
      summary: MEC011 service availability notification
      description: "."
      operationId: NotificationPOST
      requestBody:
        description: service availability notification details
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceAvailabilityNotification'
        required: true
      - frontend_mec_service
      description: Create a new application mobility service for the service requester.
      responses:
        "200":
          description: OK
@@ -73,20 +59,46 @@ paths:
          description: Bad request
        "404":
          description: Not found
  /application/termination:
  /services/callback/amsevent: 
    post: 
      tags:
      - frontend_notification
      summary: MEC011 app termination notification
      description: "."
      operationId: TerminateNotificatonPOST
      - frontend_mec_service
      description: Handle Application Mobility Service notifications.
      responses:
        "200":
          description: OK
        "400":
          description: Bad request
        "404":
          description: Not found
  /services/callback/service-availability:
    post:
      tags:
      - 'frontend_notification'
      summary: 'MEC011 service availability notification'
      description: '.'
      operationId: NotificationPOST
      responses:
        "200":
          description: OK
        "400":
          description: Bad request
        "404":
          description: Not found
      requestBody:
        description: app termination notification details
        description: 'service availability notification details'
        required: true
        content: 
          application/json:
            schema:
              $ref: '#/components/schemas/AppTerminationNotificationSubscription'
        required: true
              $ref: '#/components/schemas/ServiceAvailabilityNotification'
  /application/termination:
    post:
      tags:
      - 'frontend_notification'
      summary: 'MEC011 app termination notification'
      description: '.'
      operationId: TerminateNotificatonPOST
      responses:
        "200":
          description: OK
@@ -94,26 +106,62 @@ paths:
          description: Bad request
        "404":
          description: Not found
      requestBody:
        description: 'app termination notification details'
        required: true
        content: 
          application/json:
            schema: 
              $ref: '#/components/schemas/AppTerminationNotificationSubscription'
components: 
  schemas:
    ServiceAvailabilityNotification:
        description: >-
          This type represents the service availability information.
        type: object
        required: 
      - _links
          - notificationType
          - serviceReferences
      type: object
          - _links
        properties:
          notificationType: 
          type: string
            description: Shall be set to SerAvailabilityNotification
          example: SerAvailabilityNotification
            type: string
            example: "SerAvailabilityNotification"
          serviceReferences:
            type: array
            items: 
            $ref: '#/components/schemas/ServiceAvailabilityNotification_serviceReferences'
              description: List of links to services whose availability has changed.
              type: object
              required:
                - serName
                - serInstanceId
                - state
                - changeType
              properties:
                link: 
                  $ref: '#/components/schemas/LinkType'
                serName: 
                  $ref: '#/components/schemas/SerName'
                serInstanceId:
                  $ref: '#/components/schemas/SerInstanceId'
                state:
                  $ref: '#/components/schemas/ServiceState'
                changeType:
                  description: >-
                   Type of the change. Valid values:
                    ADDED: The service was newly added.
                     REMOVED: The service was removed.
                     STATE_CHANGED: Only the state of the service was changed. 
                     ATTRIBUTES_CHANGED: At least one attribute of the service other than state was changed. The change may or may not include changing the state.
                  type: string
                  enum:
                    - ADDED
                    - REMOVED
                    - STATE_CHANGED
                    - ATTRIBUTES_CHANGED
          _links:
            $ref: '#/components/schemas/Subscription'
      description: This type represents the service availability information.
    AppTerminationNotificationSubscription:
      required:
      - _links
@@ -158,83 +206,53 @@ components:
        self:
          href: http://example.com/aeiou
    LinkType:
      description: This type represents a type of link and may be referenced from data structures
      type: object
      properties:
        href: 
          type: string
          description: URI referring to a resource
          type: string
          format: uri
          example: /mecSerMgmtApi/example
      description: This type represents a type of link and may be referenced from
        data structures
          example: '/mecSerMgmtApi/example'
    SerName:
      type: string
      description: The name of the service. This is how the service producing MEC
      description: >-
        The name of the service. This is how the service producing MEC
        application identifies the service instance it produces.
      type: string
    SerInstanceId:
      description: >-
        Identifier of the service instance assigned by the MEC platform.
      type: string
      description: Identifier of the service instance assigned by the MEC platform.
      readOnly: true
    ServiceState:
      type: string
      description: This enumeration defines the possible states of a service.
      type: string
      enum:
        - ACTIVE
        - INACTIVE
    Subscription:
      description: A link to the related subscription
      type: object
      required:
        - subscription
      type: object
      properties:
        subscription:
          $ref: '#/components/schemas/LinkType'
      description: A link to the related subscription
    ServiceAvailabilityNotification_serviceReferences:
      required:
      - changeType
      - serInstanceId
      - serName
      - state
      type: object
      properties:
        link:
          $ref: '#/components/schemas/LinkType'
        serName:
          $ref: '#/components/schemas/SerName'
        serInstanceId:
          $ref: '#/components/schemas/SerInstanceId'
        state:
          $ref: '#/components/schemas/ServiceState'
        changeType:
          type: string
          description: "Type of the change. Valid values:\n ADDED: The service was\
            \ newly added.\n  REMOVED: The service was removed.\n  STATE_CHANGED:\
            \ Only the state of the service was changed. \n  ATTRIBUTES_CHANGED: At\
            \ least one attribute of the service other than state was changed. The\
            \ change may or may not include changing the state."
          enum:
          - ADDED
          - REMOVED
          - STATE_CHANGED
          - ATTRIBUTES_CHANGED
      description: List of links to services whose availability has changed.
  parameters: 
    Path.AppInstanceId:
      name: appInstanceId
      description: >-
        Represents a MEC application instance. Note that the
        appInstanceId is allocated by the MEC platform manager.
      in: path
      description: Represents a MEC application instance. Note that the appInstanceId
        is allocated by the MEC platform manager.
      required: true
      style: simple
      explode: false
      schema:
        type: string
    Path.ServiceId:
      name: serviceId
      in: path
      description: Represents a MEC service instance.
      in: path
      required: true
      style: simple
      explode: false
      schema:
        type: string
      
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ module github.com/InterDigitalInc/AdvantEDGE/example/demo3/src
go 1.15

require (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-ams-client v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0-20210505162607-cc887b7a0c0a
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client v0.0.0
@@ -12,6 +13,7 @@ require (
)

replace (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-ams-client => ../../../go-packages/meep-ams-client
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client => ../../../go-packages/meep-app-support-client
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client => ../../../go-packages/meep-sandbox-ctrl-client
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client => ../../../go-packages/meep-service-mgmt-client
+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ func main() {
		// Setup configuration for Demo 3 then initalize use-case service
		port, err := server.Init(envPath, envName)
		if err != nil {
			log.Info("Failed to initaliize Demo 3", err)
			log.Fatal("Failed to initaliize Demo 3 ", err)
		}

		// Start demo 3 client
+4 −0
Original line number Diff line number Diff line
@@ -38,3 +38,7 @@ func ServiceDeleteDelete(w http.ResponseWriter, r *http.Request) {
func ServicesDiscoverPost(w http.ResponseWriter, r *http.Request) {
	servicesSubscriptionPOST(w, r)
}

func AmsCreatePOST(w http.ResponseWriter, r *http.Request) {
	amsCreatePOST(w, r)
}
+86 −19
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import (
	"sync"

	"github.com/InterDigitalInc/AdvantEDGE/example/demo3/src/util"
	ams "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-ams-client"
	asc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client"
	log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
	smc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client"
@@ -25,7 +26,12 @@ import (
var mutex sync.Mutex

var srvMgmtClient *smc.APIClient
var srvMgmtClientPath string
var appSupportClient *asc.APIClient
var appSupportClientPath string

var amsClient *ams.APIClient
var amsClientPath string

var instanceName string
var mecUrl string
@@ -33,14 +39,15 @@ var localPort string
var subscriptionSent bool
var confirmReady bool
var appEnablementServiceId string
var subscriptionId string
var serviceSubscriptionId string
var registeredService bool
var appSupportClientPath string
var srvMgmtClientPath string
var terminationSubscriptionId string

var serviceName string = "user-app"
var scopeOfLocality string = defaultScopeOfLocality
var consumedLocalOnly bool = defaultConsumedLocalOnly
var terminationSubscription bool = false
var terminated bool = false

const serviceAppVersion = "2.1.1"
const local = "http://10.190.115.162"
@@ -90,6 +97,15 @@ func Init(envPath string, envName string) (port string, err error) {
		return "", errors.New("Failed to create App Enablement Service Management REST API client")
	}

	// Create application mobility suppport client
	amsClientcfg := ams.NewConfiguration()
	amsClientcfg.BasePath = mecUrl + "/amsi/v1"
	amsClient = ams.NewAPIClient(amsClientcfg)
	amsClientPath = amsClientcfg.BasePath
	if amsClient == nil {
		return "", errors.New("Failed to create Application Mobility Support REST API client")
	}

	return localPort, nil
}

@@ -120,7 +136,7 @@ func servicesSubscriptionPOST(w http.ResponseWriter, r *http.Request) {
}

// REST API
// Handle subscription callback notification
// Handle service subscription callback notification
func notificationPOST(w http.ResponseWriter, r *http.Request) {

	// Decode request body
@@ -202,10 +218,16 @@ func terminateNotificatonPOST(w http.ResponseWriter, r *http.Request) {
		return
	}
	log.Info("Received user-app termination notification")
	w.WriteHeader(http.StatusNoContent)
	w.WriteHeader(http.StatusOK)
	Terminate()
}

// Rest API
// Register MEC Application instances with AMS
func amsCreatePOST(w http.ResponseWriter, r *http.Request) {

}

// Client request to notify mec platform of mec app
func sendReadyConfirmation(appInstanceId string) error {
	log.Debug("Sending request to mec platform user-app confirm-ready api")
@@ -327,13 +349,22 @@ func subscribeAvailability(appInstanceId string, callbackReference string) error
	if idPosition == -1 {
		log.Error("Error parsing subscription id for subscription")
	}
	subscriptionId = hRefLink[idPosition+1:]
	serviceSubscriptionId = hRefLink[idPosition+1:]

	log.Info("Subscribed to service availibility notification on mec platform")

	return nil
}

// Client request to sent confirm terminate
func confirmTerminate(appInstanceId string, subscriptionId string) {
	resp, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionDELETE(context.TODO(), appInstanceId, subscriptionId)
	if err != nil {
		log.Error("Failed to send confirm termination ", resp.Status)
	}

}

// Client request to subscribe app-termination notifications
func subscribeAppTermination(appInstanceId string, callBackReference string) error {
	log.Debug("Sending request to mec platform confirm terminate subscription api")
@@ -341,11 +372,31 @@ func subscribeAppTermination(appInstanceId string, callBackReference string) err
	appTerminationBody.SubscriptionType = "AppTerminationNotificationSubscription"
	appTerminationBody.CallbackReference = callBackReference
	appTerminationBody.AppInstanceId = appInstanceId
	_, resp, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionsPOST(context.TODO(), appTerminationBody, appInstanceId)
	appTerminationResponse, resp, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionsPOST(context.TODO(), appTerminationBody, appInstanceId)
	if err != nil {
		log.Error("Failed to send termination subscription: ", resp.Status)
		return err
	}

	hRefLink := appTerminationResponse.Links.Self.Href

	// Find subscription id from response
	idPosition := strings.LastIndex(hRefLink, "/")
	if idPosition == -1 {
		log.Error("Error parsing subscription id for subscription")
	}
	terminationSubscriptionId = hRefLink[idPosition+1:]

	return nil
}

// Client request to delete app-termination subscriptions
func delAppTerminationSubscription(appInstanceId string, subscriptionId string) error {
	resp, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionDELETE(context.TODO(), appInstanceId, subscriptionId)
	if err != nil {
		log.Error("Failed to clear app termination subscription ", resp.Status)
		return err
	}
	return nil
}

@@ -353,7 +404,7 @@ func subscribeAppTermination(appInstanceId string, callBackReference string) err
func delsubscribeAvailability(appInstanceId string, subscriptionId string) error {
	resp, err := srvMgmtClient.MecServiceMgmtApi.ApplicationsSubscriptionDELETE(context.TODO(), appInstanceId, subscriptionId)
	if err != nil {
		log.Error("Failed to clear mec subscriptions: ", resp.Status)
		log.Error("Failed to clear service availability subscriptions: ", resp.Status)
		return err
	}
	return nil
@@ -374,8 +425,7 @@ func Run() {

	// Subscribe for App Termination notifications
	if !terminationSubscription {
		var callBackReference string
		callBackReference = local + localPort + "/application/termination"
		callBackReference := local + localPort + "/application/termination"
		err := subscribeAppTermination(instanceName, callBackReference)
		if err == nil {
			log.Info("Subscribed to app termination notification on mec platform")
@@ -385,20 +435,37 @@ func Run() {
}

// Terminate by deleting all resources allocated on MEC platform & mec app
// Delete service & app subscription & registered services
func Terminate() {
	// Delete subscription & registered services

	// 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)
		if err == nil {
			log.Info("Cleared app enablement subscription on mec platform")
		}

		//Send Confirm Terminate
		confirmTerminate(instanceName, terminationSubscriptionId)

		// Delete service subscriptions
		if subscriptionSent {
		err := delsubscribeAvailability(instanceName, subscriptionId)
			err := delsubscribeAvailability(instanceName, serviceSubscriptionId)
			if err == nil {
			log.Info("Cleared user-app subscription on mec platform")
				log.Info("Cleared service subscription on mec platform")
			}
		}

		// Delete service
		if registeredService {
			err := unregisterService(instanceName, appEnablementServiceId)
			if err == nil {
				log.Info("Cleared user-app services on mec platform")
			}
		}
		terminated = true
	}

}
Loading