Commit 13cb010c authored by Kevin Di Lallo's avatar Kevin Di Lallo
Browse files

meep-ams updates to allow only registered apps as valid targets

parent 451abf89
Loading
Loading
Loading
Loading
+142 −52
Original line number Diff line number Diff line
@@ -90,7 +90,6 @@ const (
	FieldCtxTransferState string = "contextTransferState"
	FieldMobilitySvcId    string = "mobilityServiceId"
	FieldAppInstanceId    string = "appInstanceId"
	FieldSvcId            string = "svcId"
	FieldCtxOwner         string = "contextOwner"
)

@@ -150,6 +149,9 @@ var svcMgmtClient *smc.APIClient
var sbxCtrlClient *scc.APIClient
var registrationTicker *time.Ticker

// AMS Resource map
var regInfoMap map[string]*RegistrationInfo

// k = appInstanceId
var appInfoMap map[string]AppInfo

@@ -168,6 +170,7 @@ func notImplemented(w http.ResponseWriter, r *http.Request) {
func Init() (err error) {

	// Initialize variables
	regInfoMap = make(map[string]*RegistrationInfo)
	appInfoMap = make(map[string]AppInfo)
	devInfoMap = make(map[string]*DevInfo)
	trackedDevInfoMap = make(map[string]map[string]TrackedDevInfo)
@@ -420,12 +423,13 @@ func msgHandler(msg *mq.Msg, userData interface{}) {
			log.Error(err.Error())
			break
		}
		appName := appInfo[fieldName]

		// Refresh tracked device context owner
		refreshTrackedDevCtxOwner(appInfo[fieldName])
		refreshTrackedDevCtxOwner(appName)

		// Check for adjacent app notif subscriptions
		sendAdjAppInfoNotifications(appInfo[fieldName])
		sendAdjAppInfoNotifications(appName)

	case mq.MsgAppRemove:
		mutex.Lock()
@@ -444,14 +448,14 @@ func msgHandler(msg *mq.Msg, userData interface{}) {
		appName := appInfo[fieldName]

		// Terminate app
		err = terminateApp(appId)
		err = delAppInfo(appId)
		if err != nil {
			log.Error(err.Error())
			break
		}

		// Refresh tracked device context owner
		refreshTrackedDevCtxOwner(appInfo[fieldName])
		refreshTrackedDevCtxOwner(appName)

		// Check for adjacent app notif subscriptions
		sendAdjAppInfoNotifications(appName)
@@ -1336,7 +1340,7 @@ func appMobilityServicePOST(w http.ResponseWriter, r *http.Request) {
	regInfo.AppMobilityServiceId = svcId

	// Create new AMS resource
	err = createService(appId, svcId, &regInfo)
	err = createService(appId, &regInfo)
	if err != nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -1357,14 +1361,14 @@ func appMobilityServiceByIdGET(w http.ResponseWriter, r *http.Request) {
	svcId := vars["appMobilityServiceId"]

	// Get AMS resource by ID
	key := baseKey + "svc:" + svcId + ":info"
	jsonData, _ := rc.JSONGetEntry(key, ".")
	if jsonData == "" {
	regInfo, err := getRegInfo(svcId)
	if err != nil || regInfo == nil {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, string(jsonData))
	fmt.Fprintf(w, convertRegistrationInfoToJson(regInfo))
}

func appMobilityServiceByIdPUT(w http.ResponseWriter, r *http.Request) {
@@ -1423,7 +1427,7 @@ func appMobilityServiceByIdPUT(w http.ResponseWriter, r *http.Request) {
	}

	// Create new AMS resource
	err = createService(appId, svcId, &regInfo)
	err = createService(appId, &regInfo)
	if err != nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -1446,7 +1450,26 @@ func appMobilityServiceByIdDELETE(w http.ResponseWriter, r *http.Request) {
	mutex.Lock()
	defer mutex.Unlock()

	// Delete previous service & devices
	// Get AMS Registration Info
	regInfo, err := getRegInfo(svcId)
	if err != nil || regInfo == nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}

	// Get impacted App name
	appName := ""
	appId := regInfo.ServiceConsumerId.AppInstanceId
	if appId == "" {
		appId = regInfo.ServiceConsumerId.MepId
	}
	appInfo, err := getApp(appId)
	if err == nil && appInfo != nil {
		appName = appInfo[fieldName]
	}

	// Delete AMS resource & its tracked devices
	statusCode, err := deleteServiceById(svcId)
	if err != nil {
		log.Error(err.Error())
@@ -1454,6 +1477,9 @@ func appMobilityServiceByIdDELETE(w http.ResponseWriter, r *http.Request) {
		return
	}

	// Refresh tracked device context owner
	refreshTrackedDevCtxOwner(appName)

	// Send successful response
	w.WriteHeader(http.StatusNoContent)
}
@@ -1461,7 +1487,7 @@ func appMobilityServiceByIdDELETE(w http.ResponseWriter, r *http.Request) {
func appMobilityServiceGET(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

	// Get all AMS resources
	// Get all AMS Registration Info
	regInfoList := make([]RegistrationInfo, 0)
	key := baseKey + "svc:*:info"
	err := rc.ForEachJSONEntry(key, populateRegInfoList, &regInfoList)
@@ -1478,6 +1504,7 @@ func appMobilityServiceGET(w http.ResponseWriter, r *http.Request) {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, string(jsonResponse))
}
@@ -1547,10 +1574,9 @@ func setStoreName(storeName string) {
	}
}

func createService(appId string, svcId string, regInfo *RegistrationInfo) error {
	// Store new AMS resource
	key := baseKey + "svc:" + svcId + ":info"
	err := rc.JSONSetEntry(key, ".", convertRegistrationInfoToJson(regInfo))
func createService(appId string, regInfo *RegistrationInfo) error {
	// Store new AMS Registration Info resource
	err := setRegInfo(regInfo)
	if err != nil {
		return err
	}
@@ -1561,9 +1587,8 @@ func createService(appId string, svcId string, regInfo *RegistrationInfo) error
		dev[FieldAssociateId] = devInfo.AssociateId.Value
		dev[FieldServiceLevel] = strconv.Itoa(int(devInfo.AppMobilityServiceLevel))
		dev[FieldCtxTransferState] = strconv.Itoa(int(devInfo.ContextTransferState))
		dev[FieldMobilitySvcId] = svcId
		dev[FieldMobilitySvcId] = regInfo.AppMobilityServiceId
		dev[FieldAppInstanceId] = appId
		dev[FieldSvcId] = svcId
		dev[FieldCtxOwner] = ""
		err = setTrackedDevInfo(dev)
		if err != nil {
@@ -1574,25 +1599,23 @@ func createService(appId string, svcId string, regInfo *RegistrationInfo) error
}

func deleteServiceById(svcId string) (int, error) {
	// Get AMS resource by ID
	key := baseKey + "svc:" + svcId + ":info"
	jsonData, _ := rc.JSONGetEntry(key, ".")
	if jsonData == "" {
	// Get AMS Registration Info
	regInfo, err := getRegInfo(svcId)
	if err != nil || regInfo == nil {
		return http.StatusNotFound, errors.New("Service not found")
	}
	regInfo := convertJsonToRegistrationInfo(jsonData)

	// Delete AMS resource
	err := rc.JSONDelEntry(key, ".")
	if err != nil {
		return http.StatusInternalServerError, err
	}

	// Delete devices
	// Delete AMS devices
	for _, devInfo := range regInfo.DeviceInformation {
		address := devInfo.AssociateId.Value
		_ = delTrackedDevInfo(svcId, address)
	}

	// Delete AMS resource
	err = delRegInfo(svcId)
	if err != nil {
		log.Error(err.Error())
	}
	return http.StatusOK, nil
}

@@ -1790,14 +1813,23 @@ func getTargetApps(appName string, address string) ([]string, error) {
	targetAppIds := []string{}
	for _, nodeList := range devInfo.PreferredNodes {
		for _, node := range nodeList {
			// Check all App instances for a matching app name & edge node
			// NOTE: no app instance state verification is made to make sure service is ready
			for appId, appInfo := range appInfoMap {
			// Search all AMS Registration Info for a matching App instance & Node
			for _, regInfo := range regInfoMap {
				// Get App Id
				appId := regInfo.ServiceConsumerId.AppInstanceId
				if appId == "" {
					appId = regInfo.ServiceConsumerId.MepId
				}

				// Get app info
				appInfo, err := getApp(appId)
				if err == nil && appInfo != nil {
					if appInfo[fieldName] == appName && appInfo[fieldNode] == node {
						targetAppIds = append(targetAppIds, appId)
					}
				}
			}
		}

		// Return if at least 1 valid target is found
		if len(targetAppIds) > 0 {
@@ -1953,12 +1985,39 @@ func setAppInfo(appInfo map[string]string) error {
}

func delAppInfo(appId string) error {
	// Get App info
	_, found := appInfoMap[appId]
	if !found {
		return errors.New("App info not found for: " + appId)
	}

	// Delete app support subscriptions
	err := subMgr.DeleteFilteredSubscriptions(appId, "")
	if err != nil {
		log.Error(err.Error())
	}

	// Get list of impacted AMS Registration info
	var regInfoToDeleteList []string
	for _, regInfo := range regInfoMap {
		regInfoAppId := regInfo.ServiceConsumerId.AppInstanceId
		if regInfoAppId == "" {
			regInfoAppId = regInfo.ServiceConsumerId.MepId
		}
		if regInfoAppId == appId {
			regInfoToDeleteList = append(regInfoToDeleteList, regInfo.AppMobilityServiceId)
		}
	}

	// Delete AMS Registration Info & Devices
	for _, svcId := range regInfoToDeleteList {
		// Delete  service & devices
		_, err := deleteServiceById(svcId)
		if err != nil {
			log.Error(err.Error())
		}
	}

	// Remove from cache
	delete(appInfoMap, appId)

@@ -2067,21 +2126,6 @@ func updateApp(appId string) (map[string]string, error) {
	return appInfo, nil
}

func terminateApp(appId string) error {
	// Get App info
	appInfo, found := appInfoMap[appId]
	if !found {
		return errors.New("App info not found for: " + appId)
	}

	// Delete app info
	err := delAppInfo(appInfo[fieldAppId])
	if err != nil {
		log.Error(err.Error())
	}
	return nil
}

func flushApps(persist bool) error {
	// Delete App instances
	for _, appInfo := range appInfoMap {
@@ -2105,6 +2149,52 @@ func flushApps(persist bool) error {
	return nil
}

func getRegInfo(svcId string) (*RegistrationInfo, error) {
	regInfo, found := regInfoMap[svcId]
	if !found {
		return nil, errors.New("AMS Registration Info not found")
	}
	return regInfo, nil
}

// func getDevInfo(address string) (*DevInfo, error) {
// 	key := baseKey + "dev:" + address
// 	jsonData, _ := rc.JSONGetEntry(key, ".")
// 	if jsonData == "" {
// 		return nil, errors.New("Device not found")
// 	}
// 	return convertJsonToDevInfo(jsonData), nil
// }

func setRegInfo(regInfo *RegistrationInfo) error {
	if regInfo == nil {
		return errors.New("regInfo == nil")
	}

	// Store AMS Registration Info
	key := baseKey + "svc:" + regInfo.AppMobilityServiceId + ":info"
	err := rc.JSONSetEntry(key, ".", convertRegistrationInfoToJson(regInfo))
	if err != nil {
		return err
	}

	// Cache entry
	regInfoMap[regInfo.AppMobilityServiceId] = regInfo

	return nil
}

func delRegInfo(svcId string) error {
	// Remove from cache
	delete(regInfoMap, svcId)

	// Flush AMS Registration Info data
	key := baseKey + "svc:" + svcId + ":info"
	_ = rc.DBFlush(key)

	return nil
}

func getDev(address string) (*DevInfo, error) {
	devInfo, found := devInfoMap[address]
	if !found {
@@ -2189,7 +2279,7 @@ func delDevInfo(address string) error {
// }

func setTrackedDevInfo(trackedDevInfo TrackedDevInfo) error {
	svcId, found := trackedDevInfo[FieldSvcId]
	svcId, found := trackedDevInfo[FieldMobilitySvcId]
	if !found || svcId == "" {
		return errors.New("Missing AM service id")
	}
+9 −9
Original line number Diff line number Diff line
@@ -78,15 +78,15 @@ func convertAdjacentAppInfoNotificationToJson(obj *AdjacentAppInfoNotification)
	return string(jsonInfo)
}

func convertJsonToRegistrationInfo(jsonInfo string) *RegistrationInfo {
	var obj RegistrationInfo
	err := json.Unmarshal([]byte(jsonInfo), &obj)
	if err != nil {
		log.Error(err.Error())
		return nil
	}
	return &obj
}
// func convertJsonToRegistrationInfo(jsonInfo string) *RegistrationInfo {
// 	var obj RegistrationInfo
// 	err := json.Unmarshal([]byte(jsonInfo), &obj)
// 	if err != nil {
// 		log.Error(err.Error())
// 		return nil
// 	}
// 	return &obj
// }

func convertRegistrationInfoToJson(obj *RegistrationInfo) string {
	jsonInfo, err := json.Marshal(*obj)
+6 −0
Original line number Diff line number Diff line
@@ -3,7 +3,10 @@ module github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-webhook
go 1.12

require (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr v0.0.0 // indirect
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model v0.0.0 // indirect
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq v0.0.0
	github.com/ghodss/yaml v1.0.0
	k8s.io/api v0.0.0-20190430012547-97d6bb8ea5f4
@@ -11,7 +14,10 @@ require (
)

replace (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr => ../../go-packages/meep-data-key-mgr
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model => ../../go-packages/meep-data-model
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger => ../../go-packages/meep-logger
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model => ../../go-packages/meep-model
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq => ../../go-packages/meep-mq
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis => ../../go-packages/meep-redis
)
+9 −0
Original line number Diff line number Diff line
github.com/KromDaniel/jonson v0.0.0-20180630143114-d2f9c3c389db/go.mod h1:RU+6d0CNIRSp6yo1mXLIIrnFa/3LHhvcDVLVJyovptM=
github.com/KromDaniel/rejonson v0.0.0-20180822072824-00b5bcf2b351 h1:1u1XrfCBnY+GijnyU6O1k4odp5TnqZQTsp5v7+n/E4Y=
github.com/KromDaniel/rejonson v0.0.0-20180822072824-00b5bcf2b351/go.mod h1:HxwfbuElTuGf+/uKZfjJrCnv0BmmpkPJDI7gBwj1KkM=
github.com/RyanCarrier/dijkstra v0.0.0-20190726134004-b51cadb5ae52 h1:trnwuu/Q8T59kgRjXcSDBODnyZP9wes+bnLn0lx4PgM=
github.com/RyanCarrier/dijkstra v0.0.0-20190726134004-b51cadb5ae52/go.mod h1:DdR6ymcLl8+sN/XOVNjnYO1NDYfgHskGjreZUDuQCTY=
github.com/RyanCarrier/dijkstra-1 v0.0.0-20170512020943-0e5801a26345/go.mod h1:OK4EvWJ441LQqGzed5NGB6vKBAE34n3z7iayPcEwr30=
github.com/albertorestifo/dijkstra v0.0.0-20160910063646-aba76f725f72/go.mod h1:o+JdB7VetTHjLhU0N57x18B9voDBQe0paApdEAEoEfw=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@@ -17,6 +23,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -24,6 +32,7 @@ github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be h1:AHimNtVIpiBjPU
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/mattomatic/dijkstra v0.0.0-20130617153013-6f6d134eb237/go.mod h1:UOnLAUmVG5paym8pD3C4B9BQylUDC2vXFJJpT7JrlEA=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+12 −2
Original line number Diff line number Diff line
@@ -26,18 +26,27 @@ import (
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"

	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"
)

type SandboxData struct {
	ScenarioName   string
	AppIdMap       map[string]string
	ActiveScenario *mod.Model
}

const moduleName = "meep-webhook"
const moduleNamespace = "default"

var mqGlobal *mq.MsgQueue
var handlerId int
var activeScenarioNames map[string]string
var mutex sync.Mutex
var sbxDataMap map[string]*SandboxData

func main() {
	var err error
@@ -46,7 +55,8 @@ func main() {
	// Initialize logging
	log.MeepJSONLogInit("meep-webhook")

	activeScenarioNames = make(map[string]string)
	// Initialize sandbox data map
	sbxDataMap = make(map[string]*SandboxData)

	// Create message queue
	mqGlobal, err = mq.NewMsgQueue(mq.GetGlobalName(), moduleName, moduleNamespace, "")
Loading