Commit 19b97bf0 authored by Kevin Di Lallo's avatar Kevin Di Lallo
Browse files

sandbox-ctrl services endpoint implementation

parent c99df6e7
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -770,6 +770,13 @@ default:
#         path: '/events/{type}'
#         method: 'POST'
#         mode: 'allow'
#       - name: 'ServicesGET'
#         path: '/services'
#         method: 'GET'
#         mode: 'verify'
#         roles:
#           admin: 'allow'
#           user: 'allow'
#   #------------------------------
#   #  WAI Service (Sbox)
#   #------------------------------
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ go 1.12
require (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-applications v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-couch v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr v0.0.0 // indirect
	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
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0
@@ -13,7 +13,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-pdu-session-store v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis v0.0.0 // indirect
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-replay-manager v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-store v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-swagger-api-mgr v0.0.0
+33 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020  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.
 *
 * AdvantEDGE Sandbox Controller REST API
 *
 * This API is the main Sandbox Controller API for scenario deployment & event injection <p>**Micro-service**<br>[meep-sandbox-ctrl](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-sandbox-ctrl) <p>**Type & Usage**<br>Platform runtime interface to manage active scenarios and inject events in AdvantEDGE platform <p>**Details**<br>API details available at _your-AdvantEDGE-ip-address/api_
 *
 * API version: 1.0.0
 * Contact: AdvantEDGE@InterDigital.com
 * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
 */

package server

import (
	"net/http"
)

func ServicesGET(w http.ResponseWriter, r *http.Request) {
	servicesGET(w, r)
}
+98 −6
Original line number Diff line number Diff line
@@ -23,29 +23,33 @@ import (
	"net/http"
	"net/url"
	"strconv"
	"strings"

	apps "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-applications"
	dkm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr"
	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"
	redis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis"
	uuid "github.com/google/uuid"
	"github.com/gorilla/mux"
)

// MQ payload fields
const (
	mqFieldAppId   = "id"
	mqFieldPersist = "persist"
)

type AppCtrl struct {
	sandboxName string
	appStore    *apps.ApplicationStore
	mqLocal     *mq.MsgQueue
	handlerId   int
	rc          *redis.Connector
}

// MQ payload fields
const (
	mqFieldAppId   = "id"
	mqFieldPersist = "persist"
)

// App Controller
var appCtrl *AppCtrl

@@ -58,6 +62,14 @@ func appCtrlInit(sandboxName string, mqLocal *mq.MsgQueue) error {
	appCtrl.sandboxName = sandboxName
	appCtrl.mqLocal = mqLocal

	// Connect to Redis DB
	appCtrl.rc, err = redis.NewConnector(redisDBAddr, redisDBTable)
	if err != nil {
		log.Error("Failed connection to Redis DB. Error: ", err)
		return err
	}
	log.Info("Connected to Redis DB")

	// Create Application Store
	cfg := &apps.ApplicationStoreCfg{
		Name:      moduleName,
@@ -462,6 +474,86 @@ func applicationsGET(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, string(jsonResponse))
}

func servicesGET(w http.ResponseWriter, r *http.Request) {
	log.Info("servicesGET")
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

	// Validate & retrieve query parameters
	u, _ := url.Parse(r.URL.String())
	q := u.Query()
	validParams := []string{"appInstanceId"}
	err := validateQueryParams(q, validParams)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	appId := q.Get("appInstanceId")

	// Check if app instance exists
	if appId != "" {
		_, err = appCtrl.appStore.Get(appId)
		if err != nil {
			http.Error(w, "Invalid App instance ID", http.StatusBadRequest)
			return
		}
	}

	// Retrieve service info list if scenario is active
	serviceInfoList := []*dataModel.ServiceInfo{}
	activeModel := getActiveModel()
	if activeModel != nil {
		// Create key match string
		baseKey := dkm.GetKeyRoot(appCtrl.sandboxName) + "app-enablement:mep:*:"
		var keyMatchStr string
		if appId == "" {
			keyMatchStr = baseKey + "app:*:svc:*"
		} else {
			keyMatchStr = baseKey + "app:" + appId + ":svc:*"
		}

		// Get list of services registered to app enablement service
		err = appCtrl.rc.ForEachJSONEntry(keyMatchStr, populateServiceInfoList, &serviceInfoList)
		if err != nil {
			log.Error(err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}

	// Send response
	jsonResponse, err := json.Marshal(serviceInfoList)
	if err != nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, string(jsonResponse))
}

func populateServiceInfoList(key string, jsonInfo string, sInfoList interface{}) error {
	// Get query params & userlist from user data
	serviceInfoList := sInfoList.(*[]*dataModel.ServiceInfo)
	if serviceInfoList == nil {
		return errors.New("ServiceInfoList not found")
	}

	// Use entry key only to avoid dependency on MEC011 packages
	// Obtain app instance id & service instance id from key
	fields := strings.Split(strings.TrimPrefix(key, dkm.GetKeyRoot(appCtrl.sandboxName)+"app-enablement:mep:"), ":")
	if len(fields) != 5 {
		return nil
	}

	// Add service info to list
	serviceInfo := &dataModel.ServiceInfo{
		AppId: fields[2],
		Id:    fields[4],
	}
	*serviceInfoList = append(*serviceInfoList, serviceInfo)
	return nil
}

// Get a new unique app instance
func getNewInstanceId() (string, error) {
	//allow 3 tries, if not return an error
+7 −0
Original line number Diff line number Diff line
@@ -297,4 +297,11 @@ var routes = Routes{
		"/sandbox-ctrl/v1/events/{type}",
		SendEvent,
	},

	Route{
		"ServicesGET",
		strings.ToUpper("Get"),
		"/sandbox-ctrl/v1/services",
		ServicesGET,
	},
}
Loading