Loading examples/demo3/src/backend/server/demo3_service.go +4 −3 Original line number Diff line number Diff line Loading @@ -1122,12 +1122,13 @@ func sendReadyConfirmation(appInstanceId string) error { appReady.Indication = "READY" log.Info(appSupportClientPath) resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmReadyPOST(context.TODO(), appReady, appInstanceId) status := strconv.Itoa(resp.StatusCode) if err != nil { log.Error("Failed to receive confirmation acknowlegement ", resp.Status) appActivityLogs = append(appActivityLogs, "Send confirm ready ["+status+"]") log.Error(err.Error()) //log.Error("Failed to receive confirmation acknowlegement ", resp.Status) appActivityLogs = append(appActivityLogs, "Send confirm ready ["+err.Error()+"]") return err } status := strconv.Itoa(resp.StatusCode) appActivityLogs = append(appActivityLogs, "Send confirm ready ["+status+"]") return nil Loading go-apps/meep-gis-engine/server/gis-automation.go +21 −9 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ const ( ) func resetAutomation() { log.Debug("Reset automation") log.Info(">>> Reset automation") // Stop automation if running _ = setAutomation(AutoTypeMovement, false) Loading @@ -60,6 +60,7 @@ func resetAutomation() { } func setAutomation(automationType string, state bool) (err error) { log.Info(">>> setAutomation: ", automationType) // Validate automation type if _, found := ge.automation[automationType]; !found { Loading Loading @@ -101,8 +102,9 @@ func setAutomation(automationType string, state bool) (err error) { } func startAutomation() { log.Info(">>> startAutomation") if ge.automationTicker == nil { log.Debug("Starting automation loop") log.Info("Starting automation loop") ge.automationTicker = time.NewTicker(1000 * time.Millisecond) go func() { for range ge.automationTicker.C { Loading @@ -113,14 +115,17 @@ func startAutomation() { } func stopAutomation() { log.Info(">>> stopAutomation") if ge.automationTicker != nil { ge.automationTicker.Stop() ge.automationTicker = nil log.Debug("Stopping automation loop") log.Info("Stopping automation loop") } } func runAutomation() { log.Info(">>> runAutomation: ") var ueMap map[string]*am.Ue var poaMap map[string]*am.Poa var err error Loading @@ -146,6 +151,7 @@ func runAutomation() { } // Mobility log.Info("runAutomation: ge.automation[AutoTypeMobility]: ", ge.automation[AutoTypeMobility]) if ge.automation[AutoTypeMobility] { runAutoMobility(ueMap) } Loading @@ -169,7 +175,7 @@ func runAutomation() { } func runAutoMovement() { log.Debug("Auto Movement: updating UE positions") log.Info("Auto Movement: updating UE positions") // Calculate number of increments (seconds) for position update currentTime := time.Now() Loading @@ -189,6 +195,8 @@ func runAutoMovement() { } func runAutoMobility(ueMap map[string]*am.Ue) { log.Info(">>> runAutoMobility: updating UE positions: ", ueMap) for _, ue := range ueMap { // Get stored UE info ueInfo := getUeInfo(ue.Name) Loading Loading @@ -418,7 +426,7 @@ func calculateThroughput(radius float32, distance float32, maxUl int32, maxDl in // ---------------------------- REST API ------------------------------------ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { log.Debug("Get all automation states") log.Info("Get all automation states") var automationList AutomationStateList for automation, state := range ge.automation { Loading @@ -443,10 +451,12 @@ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { } func geGetAutomationStateByName(w http.ResponseWriter, r *http.Request) { log.Info(">>> geGetAutomationStateByName: ", r) // Get automation type from request path parameters vars := mux.Vars(r) log.Info(">>> geGetAutomationStateByName: vars: ", vars) automationType := vars["type"] log.Debug("Get automation state for type: ", automationType) log.Info("***************** Get automation state for type: ", automationType) // Get automation state var automationState AutomationState Loading Loading @@ -475,17 +485,19 @@ func geGetAutomationStateByName(w http.ResponseWriter, r *http.Request) { } func geSetAutomationStateByName(w http.ResponseWriter, r *http.Request) { log.Info(">>> geSetAutomationStateByName: ", *r) // Get automation type from request path parameters vars := mux.Vars(r) vars := mux.Vars(r) //returns map[] https://stackoverflow.com/questions/31371111/mux-vars-not-working log.Info("geSetAutomationStateByName: vars: ", vars) automationType := vars["type"] // Retrieve requested state from query parameters query := r.URL.Query() automationState, _ := strconv.ParseBool(query.Get("run")) if automationState { log.Debug("Start automation for type: ", automationType) log.Info("Start automation for type: ", automationType) } else { log.Debug("Stop automation for type: ", automationType) log.Info("Stop automation for type: ", automationType) } // Set automation state Loading go-apps/meep-gis-engine/server/gis-engine.go +45 −20 Original line number Diff line number Diff line Loading @@ -284,13 +284,13 @@ func msgHandler(msg *mq.Msg, userData interface{}) { switch msg.Message { case mq.MsgScenarioActivate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) log.Info("RX MSG: ", mq.PrintMsg(msg)) processScenarioActivate() case mq.MsgScenarioUpdate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) log.Info("RX MSG: ", mq.PrintMsg(msg)) processScenarioUpdate() case mq.MsgScenarioTerminate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) log.Info("RX MSG: ", mq.PrintMsg(msg)) processScenarioTerminate() default: log.Trace("Ignoring unsupported message: ", mq.PrintMsg(msg)) Loading @@ -298,16 +298,19 @@ func msgHandler(msg *mq.Msg, userData interface{}) { } func processScenarioActivate() { log.Info(">>> processScenarioActivate") // Sync with active scenario store ge.activeModel.UpdateScenario() // Retrieve & process POA and Compute Assets in active scenario assetList := ge.activeModel.GetNodeNames(mod.NodeTypePoa, mod.NodeTypePoa4G, mod.NodeTypePoa5G, mod.NodeTypePoaWifi, mod.NodeTypeEdge, mod.NodeTypeFog, mod.NodeTypeCloud) log.Info("processScenarioActivate: assetList (Poa): ", assetList) setAssets(assetList) // Retrieve & process UE assets in active scenario // NOTE: Required to make sure initial UE selection takes all POAs into account assetList = ge.activeModel.GetNodeNames(mod.NodeTypeUE) log.Info("processScenarioActivate: assetList (Ue): ", assetList) setAssets(assetList) // Update Gis cache Loading @@ -315,6 +318,7 @@ func processScenarioActivate() { // Start snapshot thread scenarioName := ge.activeModel.GetScenarioName() log.Info("processScenarioActivate: scenarioName: ", scenarioName) if scenarioName != "" { err := ge.StartSnapshotThread() Loading Loading @@ -347,6 +351,7 @@ func processScenarioActivate() { } func processScenarioUpdate() { log.Info(">>> processScenarioUpdate") // Sync with active scenario store ge.activeModel.UpdateScenario() Loading @@ -366,6 +371,7 @@ func processScenarioUpdate() { } // Create, update & delete assets according to scenario update log.Info("processScenarioUpdate: assetList: ", assetList) setAssets(assetList) removeAssets(assetsToRemove) Loading @@ -374,6 +380,7 @@ func processScenarioUpdate() { } func processScenarioTerminate() { log.Info(">>> processScenarioTerminate") // Sync with active scenario store ge.activeModel.UpdateScenario() Loading @@ -389,7 +396,7 @@ func processScenarioTerminate() { _ = ge.assetMgr.DeleteAllCompute() // Clear asset list log.Debug("GeoData deleted for all assets") log.Info("GeoData deleted for all assets") ge.assets = make(map[string]*Asset) // Flush cache Loading @@ -397,6 +404,7 @@ func processScenarioTerminate() { } func setAssets(assetList []string) { log.Info(">>> setAssets") for _, assetName := range assetList { var geoData *AssetGeoData = nil var err error Loading Loading @@ -461,21 +469,21 @@ func removeAssets(assetList []string) { delete(ge.assets, assetName) if isUe(nodeType) { log.Debug("GeoData deleted for UE: ", assetName) log.Info("GeoData deleted for UE: ", assetName) err := ge.assetMgr.DeleteUe(assetName) if err != nil { log.Error(err.Error()) continue } } else if isPoa(nodeType) { log.Debug("GeoData deleted for POA: ", assetName) log.Info("GeoData deleted for POA: ", assetName) err := ge.assetMgr.DeletePoa(assetName) if err != nil { log.Error(err.Error()) continue } } else if isCompute(nodeType) { log.Debug("GeoData deleted for Compute: ", assetName) log.Info("GeoData deleted for Compute: ", assetName) err := ge.assetMgr.DeleteCompute(assetName) if err != nil { log.Error(err.Error()) Loading @@ -488,6 +496,7 @@ func removeAssets(assetList []string) { } func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) error { log.Info(">>> setUe") // UE data map ueData := make(map[string]interface{}) Loading Loading @@ -521,7 +530,7 @@ func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData created for UE: ", asset.name) log.Info("GeoData created for UE: ", asset.name) asset.geoData = geoData } else { Loading Loading @@ -559,7 +568,7 @@ func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData updated for UE: ", asset.name) log.Info("GeoData updated for UE: ", asset.name) } } Loading @@ -567,6 +576,7 @@ func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) } func setPoa(asset *Asset, nl *dataModel.NetworkLocation, geoData *AssetGeoData) error { log.Info(">>> setUe") // Get POA Data poaData := make(map[string]interface{}) Loading @@ -587,7 +597,7 @@ func setPoa(asset *Asset, nl *dataModel.NetworkLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData stored for POA: ", asset.name) log.Info("GeoData stored for POA: ", asset.name) asset.geoData = geoData } else { // Update Geodata Loading @@ -606,13 +616,14 @@ func setPoa(asset *Asset, nl *dataModel.NetworkLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData created for POA: ", asset.name) log.Info("GeoData created for POA: ", asset.name) } } return nil } func setCompute(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) error { log.Info(">>> setUe") // Get Compute Data computeData := make(map[string]interface{}) Loading @@ -633,7 +644,7 @@ func setCompute(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoD if err != nil { return err } log.Debug("GeoData created for Compute: ", asset.name) log.Info("GeoData created for Compute: ", asset.name) asset.geoData = geoData } else { // Update Geodata Loading @@ -655,7 +666,7 @@ func setCompute(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoD if err != nil { return err } log.Debug("GeoData updated for Compute: ", asset.name) log.Info("GeoData updated for Compute: ", asset.name) } } return nil Loading Loading @@ -995,7 +1006,7 @@ func updateCache() { if profiling { proFinish = time.Now() log.Debug("updateCache: ", proFinish.Sub(proStart)) log.Info("updateCache: ", proFinish.Sub(proStart)) } } Loading Loading @@ -1036,7 +1047,7 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusNotFound) return } log.Debug("Delete GeoData for asset: ", asset.name) log.Info("Delete GeoData for asset: ", asset.name) // Remove asset from DB if isUe(asset.typ) { Loading Loading @@ -1086,7 +1097,7 @@ func geGetAssetData(w http.ResponseWriter, r *http.Request) { if subType != "" { subTypeStr = subType } log.Debug("Get GeoData for assetType[", assetTypeStr, "] subType[", subTypeStr, "] excludePath[", excludePath, "]") log.Info("Get GeoData for assetType[", assetTypeStr, "] subType[", subTypeStr, "] excludePath[", excludePath, "]") var assetList GeoDataAssetList Loading Loading @@ -1209,7 +1220,7 @@ func geGetDistanceGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Get Distance GeoData for asset: ", assetName) log.Info("Get Distance GeoData for asset: ", assetName) // Make sure scenario is active if ge.activeModel.GetScenarioName() == "" { Loading Loading @@ -1329,7 +1340,7 @@ func geGetWithinRangeGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Get Within Range GeoData for asset: ", assetName) log.Info("Get Within Range GeoData for asset: ", assetName) // Make sure scenario is active if ge.activeModel.GetScenarioName() == "" { Loading Loading @@ -1444,16 +1455,24 @@ func geGetWithinRangeGeoDataByName(w http.ResponseWriter, r *http.Request) { } func geGetGeoDataByName(w http.ResponseWriter, r *http.Request) { log.Info(">>> geGetGeoDataByName: ", *r) // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Get GeoData for asset: ", assetName) log.Info("Get GeoData for asset: ", assetName) // Retrieve query parameters query := r.URL.Query() log.Info("geGetGeoDataByName: query: ", query) if assetName == "" { assetName = query.Get("assetName") } excludePath := query.Get("excludePath") log.Info("geGetGeoDataByName: excludePath: ", excludePath) // Make sure scenario is active log.Info("geGetGeoDataByName: ge.activeModel.GetScenarioName: ", ge.activeModel.GetScenarioName()) if ge.activeModel.GetScenarioName() == "" { err := errors.New("No active scenario") log.Error(err.Error()) Loading @@ -1463,6 +1482,7 @@ func geGetGeoDataByName(w http.ResponseWriter, r *http.Request) { // Find asset in active scenario model node := ge.activeModel.GetNode(assetName) log.Info("geGetGeoDataByName: node: ", node) if node == nil { err := errors.New("Asset not found in active scenario") log.Error(err.Error()) Loading @@ -1477,6 +1497,11 @@ func geGetGeoDataByName(w http.ResponseWriter, r *http.Request) { // Retrieve geodata from Asset Manager using asset name & type nodeType := ge.activeModel.GetNodeType(assetName) asset.SubType = nodeType log.Info("geGetGeoDataByName: nodeType: ", nodeType) log.Info("geGetGeoDataByName: isUe(nodeType): ", isUe(nodeType)) ueMap, _ := ge.assetMgr.GetAllUe() log.Info("geGetGeoDataByName: All UEs: ", ueMap) if isUe(nodeType) { // Get UE information Loading Loading @@ -1553,7 +1578,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Set GeoData for asset: ", assetName) log.Info("Set GeoData for asset: ", assetName) // Retrieve Geodata to set from request body var geoData GeoDataAsset Loading go-apps/meep-gis-engine/server/gis-engine_test.go +150 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package server import ( "os" //"bytes" //"encoding/json" "encoding/json" "errors" "fmt" "io" Loading Loading @@ -516,14 +516,138 @@ func TestGetAutomationState(t *testing.T) { time.Sleep(1000 * time.Millisecond) var expectedResponse AutomationStateList expectedResponse.States = make([]AutomationState, 4) expectedResponse.States[0] = AutomationState{"MOVEMENT", false} expectedResponse.States[1] = AutomationState{"MOBILITY", false} expectedResponse.States[2] = AutomationState{"POAS-IN-RANGE", false} expectedResponse.States[3] = AutomationState{"NETWORK-CHARACTERISTICS-UPDATE", false} r, err := sendRequest(http.MethodGet, "/automation", nil, nil, nil, http.StatusOK, GetAutomationState) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> ", r) var respBody AutomationStateList err = json.Unmarshal([]byte(r), &respBody) // Verify Json conversion if err != nil { t.Fatalf("Failed to get expected response") } if !validateAutomationStateList(respBody, expectedResponse) { t.Fatalf("Failed to get expected response") } terminateScenario() Stop() err = Uninit() if err != nil { t.Fatalf("Error terminating test basic procedure") } } func TestGetGeodata(t *testing.T) { fmt.Println("--- ", t.Name()) log.MeepTextLogInit(t.Name()) initializeVars() err := Init() if err != nil { t.Fatalf("Error initializing test basic procedure") } err = Run() if err != nil { t.Fatalf("Error running test basic procedure") } fmt.Println("Set a scenario") initialiseScenario(testScenario) time.Sleep(1000 * time.Millisecond) r, err := sendRequest(http.MethodGet, "/geodata?assetName=UE", nil, nil, nil, http.StatusNotFound, GetGeoDataByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> r: ", r) updateScenario("mobility1") time.Sleep(1000 * time.Millisecond) r, err = sendRequest(http.MethodGet, "/geodata?assetName=ue1", nil, nil, nil, http.StatusOK, GetGeoDataByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> r: ", r) terminateScenario() Stop() err = Uninit() if err != nil { t.Fatalf("Error terminating test basic procedure") } } /*func TestGetAutomationStateByName(t *testing.T) { fmt.Println("--- ", t.Name()) log.MeepTextLogInit(t.Name()) initializeVars() err := Init() if err != nil { t.Fatalf("Error initializing test basic procedure") } err = Run() if err != nil { t.Fatalf("Error running test basic procedure") } fmt.Println("Set a scenario") initialiseScenario(testScenario) time.Sleep(1000 * time.Millisecond) // HTTP error 500 expected _, err = sendRequest(http.MethodGet, "/automation/MOBILITY", nil, nil, nil, http.StatusInternalServerError, GetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } updateScenario("mobility1") time.Sleep(1000 * time.Millisecond) // Set MOBILITY _, err = sendRequest(http.MethodPost, "/automation/MOBILITY?run=true", nil, nil, nil, http.StatusOK, SetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } // HTTP OK expected r, err := sendRequest(http.MethodGet, "/automation/MOBILITY", nil, nil, nil, http.StatusOK, GetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> r: ", r) updateScenario("mobility1") time.Sleep(1000 * time.Millisecond) // Unset MOBILITY _, err = sendRequest(http.MethodPost, "/automation/MOBILITY?run=false", nil, nil, nil, http.StatusOK, SetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } // HTTP error 500 expected _, err = sendRequest(http.MethodGet, "/automation/MOBILITY", nil, nil, nil, http.StatusInternalServerError, GetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } terminateScenario() Stop() err = Uninit() if err != nil { t.Fatalf("Error terminating test basic procedure") } }*/ func terminateScenario() { if mqLocal != nil { Loading Loading @@ -684,3 +808,27 @@ func sendRequest(method string, url string, body io.Reader, vars map[string]stri } return string(rr.Body.String()), nil } func validateAutomationStateList(response AutomationStateList, expectedResponse AutomationStateList) bool { if len(response.States) != len(expectedResponse.States) { fmt.Println("len(response) != len(expectedResponse)") return false } notFound := false for _, item := range response.States { found := false for _, item1 := range expectedResponse.States { if item == item1 { // Found it fmt.Println("validateAutomationStateList: item: ", item, "found") found = true break } } if !found { notFound = true break } } return !notFound } go-apps/meep-vis/server/vis.go +1 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,7 @@ func predictedQosPost(w http.ResponseWriter, r *http.Request) { powerResp, _, err := gisAppClient.GeospatialDataApi.GetGeoDataPowerValues(context.TODO(), geocoordinatesList) if err != nil { log.Error("Failed to communicate with gis engine: ", err) errHandlerProblemDetails(w, "Failed to communicate with gis engine.", http.StatusBadRequest) return } routeInfoList := responseData.Routes[i].RouteInfo Loading Loading
examples/demo3/src/backend/server/demo3_service.go +4 −3 Original line number Diff line number Diff line Loading @@ -1122,12 +1122,13 @@ func sendReadyConfirmation(appInstanceId string) error { appReady.Indication = "READY" log.Info(appSupportClientPath) resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmReadyPOST(context.TODO(), appReady, appInstanceId) status := strconv.Itoa(resp.StatusCode) if err != nil { log.Error("Failed to receive confirmation acknowlegement ", resp.Status) appActivityLogs = append(appActivityLogs, "Send confirm ready ["+status+"]") log.Error(err.Error()) //log.Error("Failed to receive confirmation acknowlegement ", resp.Status) appActivityLogs = append(appActivityLogs, "Send confirm ready ["+err.Error()+"]") return err } status := strconv.Itoa(resp.StatusCode) appActivityLogs = append(appActivityLogs, "Send confirm ready ["+status+"]") return nil Loading
go-apps/meep-gis-engine/server/gis-automation.go +21 −9 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ const ( ) func resetAutomation() { log.Debug("Reset automation") log.Info(">>> Reset automation") // Stop automation if running _ = setAutomation(AutoTypeMovement, false) Loading @@ -60,6 +60,7 @@ func resetAutomation() { } func setAutomation(automationType string, state bool) (err error) { log.Info(">>> setAutomation: ", automationType) // Validate automation type if _, found := ge.automation[automationType]; !found { Loading Loading @@ -101,8 +102,9 @@ func setAutomation(automationType string, state bool) (err error) { } func startAutomation() { log.Info(">>> startAutomation") if ge.automationTicker == nil { log.Debug("Starting automation loop") log.Info("Starting automation loop") ge.automationTicker = time.NewTicker(1000 * time.Millisecond) go func() { for range ge.automationTicker.C { Loading @@ -113,14 +115,17 @@ func startAutomation() { } func stopAutomation() { log.Info(">>> stopAutomation") if ge.automationTicker != nil { ge.automationTicker.Stop() ge.automationTicker = nil log.Debug("Stopping automation loop") log.Info("Stopping automation loop") } } func runAutomation() { log.Info(">>> runAutomation: ") var ueMap map[string]*am.Ue var poaMap map[string]*am.Poa var err error Loading @@ -146,6 +151,7 @@ func runAutomation() { } // Mobility log.Info("runAutomation: ge.automation[AutoTypeMobility]: ", ge.automation[AutoTypeMobility]) if ge.automation[AutoTypeMobility] { runAutoMobility(ueMap) } Loading @@ -169,7 +175,7 @@ func runAutomation() { } func runAutoMovement() { log.Debug("Auto Movement: updating UE positions") log.Info("Auto Movement: updating UE positions") // Calculate number of increments (seconds) for position update currentTime := time.Now() Loading @@ -189,6 +195,8 @@ func runAutoMovement() { } func runAutoMobility(ueMap map[string]*am.Ue) { log.Info(">>> runAutoMobility: updating UE positions: ", ueMap) for _, ue := range ueMap { // Get stored UE info ueInfo := getUeInfo(ue.Name) Loading Loading @@ -418,7 +426,7 @@ func calculateThroughput(radius float32, distance float32, maxUl int32, maxDl in // ---------------------------- REST API ------------------------------------ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { log.Debug("Get all automation states") log.Info("Get all automation states") var automationList AutomationStateList for automation, state := range ge.automation { Loading @@ -443,10 +451,12 @@ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { } func geGetAutomationStateByName(w http.ResponseWriter, r *http.Request) { log.Info(">>> geGetAutomationStateByName: ", r) // Get automation type from request path parameters vars := mux.Vars(r) log.Info(">>> geGetAutomationStateByName: vars: ", vars) automationType := vars["type"] log.Debug("Get automation state for type: ", automationType) log.Info("***************** Get automation state for type: ", automationType) // Get automation state var automationState AutomationState Loading Loading @@ -475,17 +485,19 @@ func geGetAutomationStateByName(w http.ResponseWriter, r *http.Request) { } func geSetAutomationStateByName(w http.ResponseWriter, r *http.Request) { log.Info(">>> geSetAutomationStateByName: ", *r) // Get automation type from request path parameters vars := mux.Vars(r) vars := mux.Vars(r) //returns map[] https://stackoverflow.com/questions/31371111/mux-vars-not-working log.Info("geSetAutomationStateByName: vars: ", vars) automationType := vars["type"] // Retrieve requested state from query parameters query := r.URL.Query() automationState, _ := strconv.ParseBool(query.Get("run")) if automationState { log.Debug("Start automation for type: ", automationType) log.Info("Start automation for type: ", automationType) } else { log.Debug("Stop automation for type: ", automationType) log.Info("Stop automation for type: ", automationType) } // Set automation state Loading
go-apps/meep-gis-engine/server/gis-engine.go +45 −20 Original line number Diff line number Diff line Loading @@ -284,13 +284,13 @@ func msgHandler(msg *mq.Msg, userData interface{}) { switch msg.Message { case mq.MsgScenarioActivate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) log.Info("RX MSG: ", mq.PrintMsg(msg)) processScenarioActivate() case mq.MsgScenarioUpdate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) log.Info("RX MSG: ", mq.PrintMsg(msg)) processScenarioUpdate() case mq.MsgScenarioTerminate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) log.Info("RX MSG: ", mq.PrintMsg(msg)) processScenarioTerminate() default: log.Trace("Ignoring unsupported message: ", mq.PrintMsg(msg)) Loading @@ -298,16 +298,19 @@ func msgHandler(msg *mq.Msg, userData interface{}) { } func processScenarioActivate() { log.Info(">>> processScenarioActivate") // Sync with active scenario store ge.activeModel.UpdateScenario() // Retrieve & process POA and Compute Assets in active scenario assetList := ge.activeModel.GetNodeNames(mod.NodeTypePoa, mod.NodeTypePoa4G, mod.NodeTypePoa5G, mod.NodeTypePoaWifi, mod.NodeTypeEdge, mod.NodeTypeFog, mod.NodeTypeCloud) log.Info("processScenarioActivate: assetList (Poa): ", assetList) setAssets(assetList) // Retrieve & process UE assets in active scenario // NOTE: Required to make sure initial UE selection takes all POAs into account assetList = ge.activeModel.GetNodeNames(mod.NodeTypeUE) log.Info("processScenarioActivate: assetList (Ue): ", assetList) setAssets(assetList) // Update Gis cache Loading @@ -315,6 +318,7 @@ func processScenarioActivate() { // Start snapshot thread scenarioName := ge.activeModel.GetScenarioName() log.Info("processScenarioActivate: scenarioName: ", scenarioName) if scenarioName != "" { err := ge.StartSnapshotThread() Loading Loading @@ -347,6 +351,7 @@ func processScenarioActivate() { } func processScenarioUpdate() { log.Info(">>> processScenarioUpdate") // Sync with active scenario store ge.activeModel.UpdateScenario() Loading @@ -366,6 +371,7 @@ func processScenarioUpdate() { } // Create, update & delete assets according to scenario update log.Info("processScenarioUpdate: assetList: ", assetList) setAssets(assetList) removeAssets(assetsToRemove) Loading @@ -374,6 +380,7 @@ func processScenarioUpdate() { } func processScenarioTerminate() { log.Info(">>> processScenarioTerminate") // Sync with active scenario store ge.activeModel.UpdateScenario() Loading @@ -389,7 +396,7 @@ func processScenarioTerminate() { _ = ge.assetMgr.DeleteAllCompute() // Clear asset list log.Debug("GeoData deleted for all assets") log.Info("GeoData deleted for all assets") ge.assets = make(map[string]*Asset) // Flush cache Loading @@ -397,6 +404,7 @@ func processScenarioTerminate() { } func setAssets(assetList []string) { log.Info(">>> setAssets") for _, assetName := range assetList { var geoData *AssetGeoData = nil var err error Loading Loading @@ -461,21 +469,21 @@ func removeAssets(assetList []string) { delete(ge.assets, assetName) if isUe(nodeType) { log.Debug("GeoData deleted for UE: ", assetName) log.Info("GeoData deleted for UE: ", assetName) err := ge.assetMgr.DeleteUe(assetName) if err != nil { log.Error(err.Error()) continue } } else if isPoa(nodeType) { log.Debug("GeoData deleted for POA: ", assetName) log.Info("GeoData deleted for POA: ", assetName) err := ge.assetMgr.DeletePoa(assetName) if err != nil { log.Error(err.Error()) continue } } else if isCompute(nodeType) { log.Debug("GeoData deleted for Compute: ", assetName) log.Info("GeoData deleted for Compute: ", assetName) err := ge.assetMgr.DeleteCompute(assetName) if err != nil { log.Error(err.Error()) Loading @@ -488,6 +496,7 @@ func removeAssets(assetList []string) { } func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) error { log.Info(">>> setUe") // UE data map ueData := make(map[string]interface{}) Loading Loading @@ -521,7 +530,7 @@ func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData created for UE: ", asset.name) log.Info("GeoData created for UE: ", asset.name) asset.geoData = geoData } else { Loading Loading @@ -559,7 +568,7 @@ func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData updated for UE: ", asset.name) log.Info("GeoData updated for UE: ", asset.name) } } Loading @@ -567,6 +576,7 @@ func setUe(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) } func setPoa(asset *Asset, nl *dataModel.NetworkLocation, geoData *AssetGeoData) error { log.Info(">>> setUe") // Get POA Data poaData := make(map[string]interface{}) Loading @@ -587,7 +597,7 @@ func setPoa(asset *Asset, nl *dataModel.NetworkLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData stored for POA: ", asset.name) log.Info("GeoData stored for POA: ", asset.name) asset.geoData = geoData } else { // Update Geodata Loading @@ -606,13 +616,14 @@ func setPoa(asset *Asset, nl *dataModel.NetworkLocation, geoData *AssetGeoData) if err != nil { return err } log.Debug("GeoData created for POA: ", asset.name) log.Info("GeoData created for POA: ", asset.name) } } return nil } func setCompute(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoData) error { log.Info(">>> setUe") // Get Compute Data computeData := make(map[string]interface{}) Loading @@ -633,7 +644,7 @@ func setCompute(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoD if err != nil { return err } log.Debug("GeoData created for Compute: ", asset.name) log.Info("GeoData created for Compute: ", asset.name) asset.geoData = geoData } else { // Update Geodata Loading @@ -655,7 +666,7 @@ func setCompute(asset *Asset, pl *dataModel.PhysicalLocation, geoData *AssetGeoD if err != nil { return err } log.Debug("GeoData updated for Compute: ", asset.name) log.Info("GeoData updated for Compute: ", asset.name) } } return nil Loading Loading @@ -995,7 +1006,7 @@ func updateCache() { if profiling { proFinish = time.Now() log.Debug("updateCache: ", proFinish.Sub(proStart)) log.Info("updateCache: ", proFinish.Sub(proStart)) } } Loading Loading @@ -1036,7 +1047,7 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusNotFound) return } log.Debug("Delete GeoData for asset: ", asset.name) log.Info("Delete GeoData for asset: ", asset.name) // Remove asset from DB if isUe(asset.typ) { Loading Loading @@ -1086,7 +1097,7 @@ func geGetAssetData(w http.ResponseWriter, r *http.Request) { if subType != "" { subTypeStr = subType } log.Debug("Get GeoData for assetType[", assetTypeStr, "] subType[", subTypeStr, "] excludePath[", excludePath, "]") log.Info("Get GeoData for assetType[", assetTypeStr, "] subType[", subTypeStr, "] excludePath[", excludePath, "]") var assetList GeoDataAssetList Loading Loading @@ -1209,7 +1220,7 @@ func geGetDistanceGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Get Distance GeoData for asset: ", assetName) log.Info("Get Distance GeoData for asset: ", assetName) // Make sure scenario is active if ge.activeModel.GetScenarioName() == "" { Loading Loading @@ -1329,7 +1340,7 @@ func geGetWithinRangeGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Get Within Range GeoData for asset: ", assetName) log.Info("Get Within Range GeoData for asset: ", assetName) // Make sure scenario is active if ge.activeModel.GetScenarioName() == "" { Loading Loading @@ -1444,16 +1455,24 @@ func geGetWithinRangeGeoDataByName(w http.ResponseWriter, r *http.Request) { } func geGetGeoDataByName(w http.ResponseWriter, r *http.Request) { log.Info(">>> geGetGeoDataByName: ", *r) // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Get GeoData for asset: ", assetName) log.Info("Get GeoData for asset: ", assetName) // Retrieve query parameters query := r.URL.Query() log.Info("geGetGeoDataByName: query: ", query) if assetName == "" { assetName = query.Get("assetName") } excludePath := query.Get("excludePath") log.Info("geGetGeoDataByName: excludePath: ", excludePath) // Make sure scenario is active log.Info("geGetGeoDataByName: ge.activeModel.GetScenarioName: ", ge.activeModel.GetScenarioName()) if ge.activeModel.GetScenarioName() == "" { err := errors.New("No active scenario") log.Error(err.Error()) Loading @@ -1463,6 +1482,7 @@ func geGetGeoDataByName(w http.ResponseWriter, r *http.Request) { // Find asset in active scenario model node := ge.activeModel.GetNode(assetName) log.Info("geGetGeoDataByName: node: ", node) if node == nil { err := errors.New("Asset not found in active scenario") log.Error(err.Error()) Loading @@ -1477,6 +1497,11 @@ func geGetGeoDataByName(w http.ResponseWriter, r *http.Request) { // Retrieve geodata from Asset Manager using asset name & type nodeType := ge.activeModel.GetNodeType(assetName) asset.SubType = nodeType log.Info("geGetGeoDataByName: nodeType: ", nodeType) log.Info("geGetGeoDataByName: isUe(nodeType): ", isUe(nodeType)) ueMap, _ := ge.assetMgr.GetAllUe() log.Info("geGetGeoDataByName: All UEs: ", ueMap) if isUe(nodeType) { // Get UE information Loading Loading @@ -1553,7 +1578,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get asset name from request path parameters vars := mux.Vars(r) assetName := vars["assetName"] log.Debug("Set GeoData for asset: ", assetName) log.Info("Set GeoData for asset: ", assetName) // Retrieve Geodata to set from request body var geoData GeoDataAsset Loading
go-apps/meep-gis-engine/server/gis-engine_test.go +150 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package server import ( "os" //"bytes" //"encoding/json" "encoding/json" "errors" "fmt" "io" Loading Loading @@ -516,14 +516,138 @@ func TestGetAutomationState(t *testing.T) { time.Sleep(1000 * time.Millisecond) var expectedResponse AutomationStateList expectedResponse.States = make([]AutomationState, 4) expectedResponse.States[0] = AutomationState{"MOVEMENT", false} expectedResponse.States[1] = AutomationState{"MOBILITY", false} expectedResponse.States[2] = AutomationState{"POAS-IN-RANGE", false} expectedResponse.States[3] = AutomationState{"NETWORK-CHARACTERISTICS-UPDATE", false} r, err := sendRequest(http.MethodGet, "/automation", nil, nil, nil, http.StatusOK, GetAutomationState) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> ", r) var respBody AutomationStateList err = json.Unmarshal([]byte(r), &respBody) // Verify Json conversion if err != nil { t.Fatalf("Failed to get expected response") } if !validateAutomationStateList(respBody, expectedResponse) { t.Fatalf("Failed to get expected response") } terminateScenario() Stop() err = Uninit() if err != nil { t.Fatalf("Error terminating test basic procedure") } } func TestGetGeodata(t *testing.T) { fmt.Println("--- ", t.Name()) log.MeepTextLogInit(t.Name()) initializeVars() err := Init() if err != nil { t.Fatalf("Error initializing test basic procedure") } err = Run() if err != nil { t.Fatalf("Error running test basic procedure") } fmt.Println("Set a scenario") initialiseScenario(testScenario) time.Sleep(1000 * time.Millisecond) r, err := sendRequest(http.MethodGet, "/geodata?assetName=UE", nil, nil, nil, http.StatusNotFound, GetGeoDataByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> r: ", r) updateScenario("mobility1") time.Sleep(1000 * time.Millisecond) r, err = sendRequest(http.MethodGet, "/geodata?assetName=ue1", nil, nil, nil, http.StatusOK, GetGeoDataByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> r: ", r) terminateScenario() Stop() err = Uninit() if err != nil { t.Fatalf("Error terminating test basic procedure") } } /*func TestGetAutomationStateByName(t *testing.T) { fmt.Println("--- ", t.Name()) log.MeepTextLogInit(t.Name()) initializeVars() err := Init() if err != nil { t.Fatalf("Error initializing test basic procedure") } err = Run() if err != nil { t.Fatalf("Error running test basic procedure") } fmt.Println("Set a scenario") initialiseScenario(testScenario) time.Sleep(1000 * time.Millisecond) // HTTP error 500 expected _, err = sendRequest(http.MethodGet, "/automation/MOBILITY", nil, nil, nil, http.StatusInternalServerError, GetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } updateScenario("mobility1") time.Sleep(1000 * time.Millisecond) // Set MOBILITY _, err = sendRequest(http.MethodPost, "/automation/MOBILITY?run=true", nil, nil, nil, http.StatusOK, SetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } // HTTP OK expected r, err := sendRequest(http.MethodGet, "/automation/MOBILITY", nil, nil, nil, http.StatusOK, GetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } fmt.Println("==> r: ", r) updateScenario("mobility1") time.Sleep(1000 * time.Millisecond) // Unset MOBILITY _, err = sendRequest(http.MethodPost, "/automation/MOBILITY?run=false", nil, nil, nil, http.StatusOK, SetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } // HTTP error 500 expected _, err = sendRequest(http.MethodGet, "/automation/MOBILITY", nil, nil, nil, http.StatusInternalServerError, GetAutomationStateByName) if err != nil { t.Fatal("Failed to get expected response: ", err.Error()) } terminateScenario() Stop() err = Uninit() if err != nil { t.Fatalf("Error terminating test basic procedure") } }*/ func terminateScenario() { if mqLocal != nil { Loading Loading @@ -684,3 +808,27 @@ func sendRequest(method string, url string, body io.Reader, vars map[string]stri } return string(rr.Body.String()), nil } func validateAutomationStateList(response AutomationStateList, expectedResponse AutomationStateList) bool { if len(response.States) != len(expectedResponse.States) { fmt.Println("len(response) != len(expectedResponse)") return false } notFound := false for _, item := range response.States { found := false for _, item1 := range expectedResponse.States { if item == item1 { // Found it fmt.Println("validateAutomationStateList: item: ", item, "found") found = true break } } if !found { notFound = true break } } return !notFound }
go-apps/meep-vis/server/vis.go +1 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,7 @@ func predictedQosPost(w http.ResponseWriter, r *http.Request) { powerResp, _, err := gisAppClient.GeospatialDataApi.GetGeoDataPowerValues(context.TODO(), geocoordinatesList) if err != nil { log.Error("Failed to communicate with gis engine: ", err) errHandlerProblemDetails(w, "Failed to communicate with gis engine.", http.StatusBadRequest) return } routeInfoList := responseData.Routes[i].RouteInfo Loading