Unverified Commit d32c652e authored by Kevin Di Lallo's avatar Kevin Di Lallo Committed by GitHub
Browse files

Merge pull request #304 from pastorsx/sp_dev_app_mobility_service_part2

Application Mobility Adjacent and Mobility procedure sub/notifications
parents 5b43965b 29fdd8aa
Loading
Loading
Loading
Loading
+64 −19
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ info:
  <p>[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)
  <p>**Micro-service**<br>[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)
  <p>**Type & Usage**<br>Edge Service used by edge applications that want to get information about application mobility in the network
  <p>**Note**<br>AdvantEDGE supports all of Application Mobility API endpoints (see below)."
  <p>**Note**<br>AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below)."
  license:
    name: "Apache 2.0"
    url: "https://github.com/InterDigitalInc/AdvantEDGE/blob/master/LICENSE"
@@ -21,6 +21,7 @@ servers:
  - url: 'https://localhost/sandboxname/amsi/v1'
tags:
  - name: amsi
  - name: unsupported
paths:
  /app_mobility_services:
    get:
@@ -94,6 +95,15 @@ paths:
          application/json:
            schema:
              $ref: '#/components/schemas/RegistrationInfo'    
            example:
              deviceInformation:
                - appMobilityServiceLevel: 1
                  associateId:
                    type: 1
                    value: '10.100.0.3'
                  contextTransferState: 0
              serviceConsumerId:
                appInstanceId: '9afdbca8-afac-405b-b220-4154828280b8'
      responses:
        '201':
          description: Successful response for application mobility service creation
@@ -158,6 +168,16 @@ paths:
          application/json:
            schema:
              $ref: '#/components/schemas/RegistrationInfo' 
            example:
              appMobilityServiceId: "appMobilityServiceId"
              deviceInformation:
                - appMobilityServiceLevel: 1
                  associateId:
                    type: 1
                    value: '10.100.0.3'
                  contextTransferState: 0
              serviceConsumerId:
                appInstanceId: '9afdbca8-afac-405b-b220-4154828280b8'
       responses:
        '200':
          description: 'Contains a data type describing the updated application mobility service.'
@@ -271,6 +291,16 @@ paths:
              oneOf:
               - $ref: '#/components/schemas/MobilityProcedureSubscription'
               - $ref: '#/components/schemas/AdjacentAppInfoSubscription'
            example:
              subscriptionType: MobilityProcedureSubscription
              callbackReference: 'http://my.callback.com/amsi-mobility-procedure/some-id'
              filterCriteria:
                appInstanceId: '9afdbca8-afac-405b-b220-4154828280b8'
                associateId:
                - type: 1
                  value: '10.100.0.3'
                - type: 1
                  value: '10.100.0.1'
      responses:
        '201':
          description: 'Created subscription is described using the appropriate data type'
@@ -366,6 +396,19 @@ paths:
              oneOf:
               - $ref: '#/components/schemas/MobilityProcedureSubscription'
               - $ref: '#/components/schemas/AdjacentAppInfoSubscription'    
            example:
              subscriptionType: MobilityProcedureSubscription
              callbackReference: 'http://my.callback.com/amsi-mobility-procedure/some-id'
              _links:
                self:
                  href: 'http://meAppServer.example.com/amsi/v1/subscriptions/sub123'
              filterCriteria:
                appInstanceId: '9afdbca8-afac-405b-b220-4154828280b8'
                associateId:
                - type: 1
                  value: '10.100.0.3'
                - type: 1
                  value: '10.100.0.1'
      responses:
        '200':
          description: ' a response body containing data type describing the updated subscription'
@@ -438,7 +481,7 @@ paths:
  /queries/adjacent_app_instances:
    get:
      tags:
      - 'amsi'
      - 'unsupported'
      summary: 'Retrieve information about this subscription.'
      description: 'Retrieve information about this subscription.'
      operationId: adj_app_instGET
@@ -916,6 +959,8 @@ components:
          x-etsi-mec-cardinality: '1'
          x-etsi-mec-origin-type: String
        adjacentAppInfo:
          items:
            type: object
            description: Identifiers to associate the information of target application instance.
            properties:
              appInstanceId:
@@ -923,16 +968,16 @@ components:
                type: string
                x-etsi-mec-cardinality: 0..1
                x-etsi-mec-origin-type: String
             
              commInterface:
                # description: If present, it specifies the communication interface of the application instance.
                # x-etsi-mec-cardinality: 0..1
                # x-etsi-mec-origin-type: CommunicationInterface
                $ref: '#/components/schemas/CommunicationInterface'
          type: object
          x-etsi-mec-cardinality: 0..1
            x-etsi-mec-cardinality: 0..N
            required:
              - appInstanceId
          minItems: 0
          type: array
        timeStamp:
          # description: Time stamp.
          # x-etsi-mec-cardinality: 0..1
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ go 1.12
require (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model v0.0.0 // indirect
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-cache v0.0.0 // indirect
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0
+293 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2019  InterDigital Communications, Inc
 *
 * 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.
 */

package sbi

import (
	"errors"
	"sync"

	dataModel "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model"
	log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
	mod "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model"
	mq "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq"
	sam "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-swagger-api-mgr"
)

type SbiCfg struct {
	ModuleName     string
	SandboxName    string
	MepName        string
	RedisAddr      string
	Locality       []string
	DeviceInfoCb   func(string, string, []string)
	ScenarioNameCb func(string)
	CleanUpCb      func()
}

type AmsSbi struct {
	moduleName           string
	sandboxName          string
	mepName              string
	localityEnabled      bool
	locality             map[string]bool
	mqLocal              *mq.MsgQueue
	handlerId            int
	apiMgr               *sam.SwaggerApiMgr
	activeModel          *mod.Model
	updateDeviceInfoCB   func(string, string, []string)
	updateScenarioNameCB func(string)
	cleanUpCB            func()
	mutex                sync.Mutex
}

var sbi *AmsSbi

// Init - AMS SBI initialization
func Init(cfg SbiCfg) (err error) {

	// Create new SBI instance
	sbi = new(AmsSbi)
	sbi.moduleName = cfg.ModuleName
	sbi.sandboxName = cfg.SandboxName
	sbi.mepName = cfg.MepName
	sbi.updateDeviceInfoCB = cfg.DeviceInfoCb
	sbi.updateScenarioNameCB = cfg.ScenarioNameCb
	sbi.cleanUpCB = cfg.CleanUpCb

	// Fill locality map
	if len(cfg.Locality) > 0 {
		sbi.locality = make(map[string]bool)
		for _, locality := range cfg.Locality {
			sbi.locality[locality] = true
		}
		sbi.localityEnabled = true
	} else {
		sbi.localityEnabled = false
	}

	// Create message queue
	sbi.mqLocal, err = mq.NewMsgQueue(mq.GetLocalName(sbi.sandboxName), sbi.moduleName, sbi.sandboxName, cfg.RedisAddr)
	if err != nil {
		log.Error("Failed to create Message Queue with error: ", err)
		return err
	}
	log.Info("Message Queue created")

	// Create Swagger API Manager
	sbi.apiMgr, err = sam.NewSwaggerApiMgr(sbi.moduleName, sbi.sandboxName, sbi.mepName, sbi.mqLocal)
	if err != nil {
		log.Error("Failed to create Swagger API Manager. Error: ", err)
		return err
	}
	log.Info("Swagger API Manager created")

	// Create new active scenario model
	modelCfg := mod.ModelCfg{
		Name:      "activeScenario",
		Namespace: sbi.sandboxName,
		Module:    sbi.moduleName,
		UpdateCb:  nil,
		DbAddr:    cfg.RedisAddr,
	}
	sbi.activeModel, err = mod.NewModel(modelCfg)
	if err != nil {
		log.Error("Failed to create model: ", err.Error())
		return err
	}
	log.Info("Active Scenario Model created")

	// Initialize service
	processActiveScenarioUpdate()

	return nil
}

// Run - MEEP Location Service execution
func Run() (err error) {

	// Start Swagger API Manager (provider)
	err = sbi.apiMgr.Start(true, false)
	if err != nil {
		log.Error("Failed to start Swagger API Manager with error: ", err.Error())
		return err
	}
	log.Info("Swagger API Manager started")

	// Add module Swagger APIs
	err = sbi.apiMgr.AddApis()
	if err != nil {
		log.Error("Failed to add Swagger APIs with error: ", err.Error())
		return err
	}
	log.Info("Swagger APIs successfully added")

	// Register Message Queue handler
	handler := mq.MsgHandler{Handler: msgHandler, UserData: nil}
	sbi.handlerId, err = sbi.mqLocal.RegisterHandler(handler)
	if err != nil {
		log.Error("Failed to register local Msg Queue listener: ", err.Error())
		return err
	}
	log.Info("Registered local Msg Queue listener")

	return nil
}

func Stop() (err error) {
	if sbi == nil {
		return
	}

	if sbi.mqLocal != nil {
		sbi.mqLocal.UnregisterHandler(sbi.handlerId)
	}

	if sbi.apiMgr != nil {
		// Remove APIs
		err = sbi.apiMgr.RemoveApis()
		if err != nil {
			log.Error("Failed to remove APIs with err: ", err.Error())
			return err
		}
	}

	return nil
}

// Message Queue handler
func msgHandler(msg *mq.Msg, userData interface{}) {
	switch msg.Message {
	case mq.MsgScenarioActivate:
		log.Debug("RX MSG: ", mq.PrintMsg(msg))
		processActiveScenarioUpdate()
	case mq.MsgScenarioUpdate:
		log.Debug("RX MSG: ", mq.PrintMsg(msg))
		processActiveScenarioUpdate()
	case mq.MsgScenarioTerminate:
		log.Debug("RX MSG: ", mq.PrintMsg(msg))
		processActiveScenarioTerminate()
	default:
		log.Trace("Ignoring unsupported message: ", mq.PrintMsg(msg))
	}
}

func processActiveScenarioTerminate() {
	log.Debug("processActiveScenarioTerminate")

	// Sync with active scenario store
	sbi.activeModel.UpdateScenario()

	sbi.cleanUpCB()
}

func processActiveScenarioUpdate() {

	sbi.mutex.Lock()
	defer sbi.mutex.Unlock()

	log.Debug("processActiveScenarioUpdate")

	// Get previous list of connected UEs
	prevUeNames := []string{}
	prevUeNameList := sbi.activeModel.GetNodeNames("UE")
	for _, name := range prevUeNameList {
		if isUeConnected(name) {
			prevUeNames = append(prevUeNames, name)
		}
	}

	// Sync with active scenario store
	sbi.activeModel.UpdateScenario()

	scenarioName := sbi.activeModel.GetScenarioName()
	sbi.updateScenarioNameCB(scenarioName)

	// Update UE info
	ueNames := []string{}
	ueNameList := sbi.activeModel.GetNodeNames("UE")
	for _, name := range ueNameList {
		// Ignore disconnected UEs
		if !isUeConnected(name) {
			continue
		}

		// Get UE locality
		procList := []string{}
		zone, procMap, err := getZoneProcMap(name)
		if err != nil {
			log.Error(err.Error())
			continue
		}
		for _, procName := range procMap {
			procList = append(procList, procName)
		}

		// Ignore UEs in zones outside locality
		if !isInLocality(zone) {
			continue
		}

		// Add UE to list of valid UEs
		ueNames = append(ueNames, name)
		sbi.updateDeviceInfoCB(name, zone, procList)
	}

	// Update UEs that were removed (no longer in locality)
	for _, prevUeName := range prevUeNames {
		found := false
		for _, ueName := range ueNames {
			if ueName == prevUeName {
				found = true
				break
			}
		}
		if !found {
			sbi.updateDeviceInfoCB(prevUeName, "", nil)
		}
	}
}

func getZoneProcMap(name string) (zone string, procMap map[string]string, err error) {
	ctx := sbi.activeModel.GetNodeContext(name)
	if ctx == nil {
		err = errors.New("Error getting context for: " + name)
		return
	}
	zone = ctx.Parents[mod.Zone]
	procMap = ctx.Children[mod.Proc]
	return zone, procMap, nil
}

func isUeConnected(name string) bool {
	node := sbi.activeModel.GetNode(name)
	if node != nil {
		pl := node.(*dataModel.PhysicalLocation)
		if pl.Connected {
			return true
		}
	}
	return false
}

func isInLocality(zone string) bool {
	if sbi.localityEnabled {
		if _, found := sbi.locality[zone]; !found {
			return false
		}
	}
	return true
}
+2 −2
Original line number Diff line number Diff line
# Go API Server for server

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.01.01_60/gs_MEC021v020101p.pdf) <p>[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt) <p>**Micro-service**<br>[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams) <p>**Type & Usage**<br>Edge Service used by edge applications that want to get information about application mobility in the network <p>**Note**<br>AdvantEDGE supports all of Application Mobility API endpoints (see below).
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.01.01_60/gs_MEC021v020101p.pdf) <p>[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt) <p>**Micro-service**<br>[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams) <p>**Type & Usage**<br>Edge Service used by edge applications that want to get information about application mobility in the network <p>**Note**<br>AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below).

## Overview
This server was generated by the [swagger-codegen]
@@ -13,7 +13,7 @@ To see how to make this your own, look here:
[README](https://github.com/swagger-api/swagger-codegen/blob/master/README.md)

- API version: 2.1.1
- Build date: 2021-09-14T17:37:11.354659-04:00[America/Toronto]
- Build date: 2021-09-15T21:36:29.173-04:00[America/New_York]


### Running the server
+387 −74

File changed.

Preview size limit exceeded, changes collapsed.

Loading