Loading go-apps/meep-mg-manager/server/mg-manager.go +216 −105 Original line number Diff line number Diff line Loading @@ -85,6 +85,9 @@ const lbAlgoHopCount = "HOP-COUNT" // const lbAlgoDistance = "DISTANCE" // const lbAlgoNone = "NONE" // MQ payload fields const fieldEventType = "event-type" type mgInfo struct { mg mgModel.MobilityGroup appInfoMap map[string]*appInfo Loading Loading @@ -144,17 +147,11 @@ type MgManager struct { activeModel *mod.Model lbRulesStore *lbRulesStore // Scenario network location list // Scenario data netLocList []string // Scenario service mappings svcInfoMap map[string]*serviceInfo mgSvcInfoMap map[string]*mgServiceInfo // mapping from element name to svc name for usercharts svcToElemMap map[string]string elemToSvcMap map[string]string // Network Element Info mapping netElemInfoMap map[string]*netElemInfo Loading @@ -170,8 +167,6 @@ func Init() (err error) { mgm.netLocList = make([]string, 0) mgm.svcInfoMap = make(map[string]*serviceInfo) mgm.mgSvcInfoMap = make(map[string]*mgServiceInfo) mgm.svcToElemMap = make(map[string]string) mgm.elemToSvcMap = make(map[string]string) mgm.netElemInfoMap = make(map[string]*netElemInfo) mgm.mgInfoMap = make(map[string]*mgInfo) Loading Loading @@ -222,7 +217,7 @@ func Init() (err error) { _ = mgm.lbRulesStore.rc.DBFlush(mgm.baseKey) // Initialize Edge-LB rules with current active scenario processActiveScenarioUpdate() processScenarioActivate() return nil } Loading @@ -246,35 +241,67 @@ func msgHandler(msg *mq.Msg, userData interface{}) { switch msg.Message { case mq.MsgScenarioActivate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) processActiveScenarioUpdate() processScenarioActivate() case mq.MsgScenarioUpdate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) processActiveScenarioUpdate() eventType := msg.Payload[fieldEventType] processScenarioUpdate(eventType) case mq.MsgScenarioTerminate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) processActiveScenarioUpdate() processScenarioTerminate() default: log.Trace("Ignoring unsupported message: ", mq.PrintMsg(msg)) } } func processActiveScenarioUpdate() { func processScenarioActivate() { // Sync with active scenario store mgm.activeModel.UpdateScenario() scenarioName := mgm.activeModel.GetScenarioName() if mgm.scenarioName != scenarioName { mgm.scenarioName = scenarioName _ = httpLog.ReInit(moduleName, mgm.sandboxName, scenarioName, redisAddr, influxAddr) // Get scenario name mgm.scenarioName = mgm.activeModel.GetScenarioName() if mgm.scenarioName == "" { log.Error("Failed to find active scenario") return } // Handle empty/missing scenario if scenarioName == "" { clearScenario() // Initialize HTTP metrics logger with scenario name _ = httpLog.ReInit(moduleName, mgm.sandboxName, mgm.scenarioName, redisAddr, influxAddr) // Parse scenario err := processScenario(mgm.activeModel) if err != nil { log.Error("Failed to process scenario with error: ", err.Error()) return } // Re-evaluate Network location Edge-LB mappings refreshNetLocAppMaps() // Re-evaluate MG Service mapping refreshMgSvcMapping() // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } func processScenarioUpdate(eventType string) { // Ignore unsupported update types switch eventType { case mod.EventMobility, mod.EventPoaInRange, mod.EventAddNode, mod.EventModifyNode, mod.EventRemoveNode: break default: return } // Sync with active scenario store mgm.activeModel.UpdateScenario() // Parse scenario err := processScenario(mgm.activeModel) if err != nil { Loading @@ -282,30 +309,48 @@ func processActiveScenarioUpdate() { return } // Set Default Edge-LB mapping setDefaultNetLocAppMaps() // Re-evaluate Network location Edge-LB mappings refreshNetLocAppMaps() // Re-evaluate MG Service mapping refreshMgSvcMapping() // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } func processScenarioTerminate() { // Sync with active scenario store mgm.activeModel.UpdateScenario() // Clear scenario data clearScenario() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } func clearScenario() { log.Debug("clearScenario() -- Resetting all variables") mgm.scenarioName = "" mgm.networkGraph = nil mgm.netLocList = make([]string, 0) mgm.svcInfoMap = make(map[string]*serviceInfo) mgm.mgSvcInfoMap = make(map[string]*mgServiceInfo) mgm.svcToElemMap = make(map[string]string) mgm.elemToSvcMap = make(map[string]string) mgm.netElemInfoMap = make(map[string]*netElemInfo) mgm.mgInfoMap = make(map[string]*mgInfo) // Flush module data and send update _ = mgm.lbRulesStore.rc.DBFlush(mgm.baseKey) } // publishLbRulesUpdate - Inform TC Engine of LB rules update func publishLbRulesUpdate() { // Send LB Rules Update message msg := mgm.mqLocal.CreateMsg(mq.MsgMgLbRulesUpdate, moduleTcEngine, mgm.sandboxName) Loading @@ -319,12 +364,20 @@ func clearScenario() { func processScenario(model *mod.Model) error { log.Debug("processScenario") // Reset service info maps mgm.svcInfoMap = make(map[string]*serviceInfo) mgm.mgSvcInfoMap = make(map[string]*mgServiceInfo) // Populate net location list mgm.netLocList = model.GetNodeNames(mod.NodeTypePoa, mod.NodeTypePoa4G, mod.NodeTypePoa5G, mod.NodeTypePoaWifi) mgm.netLocList = append(mgm.netLocList, model.GetNodeNames("DEFAULT")...) // Get list of processes procNames := model.GetNodeNames("CLOUD-APP", "EDGE-APP", "UE-APP") procNamesMap := make(map[string]bool) for _, procName := range procNames { procNamesMap[procName] = true } // Get network graph from model mgm.networkGraph = model.GetNetworkGraph() Loading Loading @@ -394,6 +447,38 @@ func processScenario(model *mod.Model) error { } } // Remove stale elements for procName := range mgm.netElemInfoMap { if _, found := procNamesMap[procName]; !found { log.Debug("Removing stale element: ", procName) delete(mgm.netElemInfoMap, procName) } } // Remove stale Mobility Groups for mgName, mgInfo := range mgm.mgInfoMap { if _, found := mgm.mgSvcInfoMap[mgName]; !found { log.Debug("Removing stale MG: ", mgName) delete(mgm.mgInfoMap, mgName) } else { // Remove stale MG Apps for appName := range mgInfo.appInfoMap { if _, found := procNamesMap[appName]; !found { log.Debug("Removing stale MG App: ", appName) delete(mgInfo.appInfoMap, appName) } } // Remove stale UEs for ueName := range mgInfo.ueInfoMap { ueNodeType := model.GetNodeType(ueName) if ueNodeType != mod.NodeTypeUE { log.Debug("Removing stale UE: ", ueName) delete(mgInfo.ueInfoMap, ueName) } } } } return nil } Loading Loading @@ -433,8 +518,6 @@ func addServiceInfo(svcName string, mgSvcName string, nodeName string) { // Add service instance to service info map mgm.svcInfoMap[svcInfo.name] = svcInfo mgm.svcToElemMap[svcInfo.name] = svcInfo.name mgm.elemToSvcMap[svcInfo.name] = svcInfo.name } func getNetElem(name string) *netElemInfo { Loading @@ -452,47 +535,57 @@ func getNetElem(name string) *netElemInfo { return netElem } func setDefaultNetLocAppMaps() { log.Debug("setDefaultNetLocAppMaps") // refreshNetLocAppMaps - Update all default & current network location application maps func refreshNetLocAppMaps() { log.Debug("refreshNetLocAppMaps") // For each MG Service & net location in scenario, use Group App instances from scenario and // default LB algorithm to determine which App instance is best for net location // For each mobility group, update the application maps for _, mgInfo := range mgm.mgInfoMap { // Only set on first pass if len(mgInfo.defaultNetLocAppMap) == 0 { for _, netLoc := range mgm.netLocList { mgInfo.defaultNetLocAppMap[netLoc] = runLbAlgoHopCount(mgm.mgSvcInfoMap[mgInfo.mg.Name].services, netLoc) // Refresh default Network Location App map refreshDefaultNetLocAppMap(mgInfo) // Refresh current Network Location App map refreshNetLocAppMap(mgInfo) } } // refreshDefaultNetLocAppMap - Update default network location application map for a single application func refreshDefaultNetLocAppMap(mgInfo *mgInfo) { log.Debug("refreshDefaultNetLocAppMap: ", mgInfo.mg.Name) // Use default LB algorithm to determine which App instance is best for each net location defaultNetLocAppMap := make(map[string]string) for _, netLoc := range mgm.netLocList { curLbSvc := mgInfo.defaultNetLocAppMap[netLoc] defaultNetLocAppMap[netLoc] = runLbAlgoHopCount(mgm.mgSvcInfoMap[mgInfo.mg.Name].services, netLoc, curLbSvc) } mgInfo.defaultNetLocAppMap = defaultNetLocAppMap } // refreshNetLocAppMap - Update current network location application map for a single application func refreshNetLocAppMap(mgInfo *mgInfo) { log.Debug("refreshNetLocAppMap") // Reset Net Loc App map mgInfo.netLocAppMap = make(map[string]string) log.Debug("refreshNetLocAppMap: ", mgInfo.mg.Name) // Retrieve list of registered app services var mgApps = map[string]*serviceInfo{} for _, appInfo := range mgInfo.appInfoMap { mgApps[appInfo.app.Id] = mgm.svcInfoMap[appInfo.app.Id] if mgApps[appInfo.app.Id] == nil { mgApps[appInfo.app.Id] = mgm.svcInfoMap[mgm.svcToElemMap[appInfo.app.Id]] } } // Refresh current Network Location App map // For each net location in scenario, use Group LB algorithm to determine which // registered Group App is best for net location netLocAppMap := make(map[string]string) for _, netLoc := range mgm.netLocList { if mgInfo.mg.LoadBalancingAlgorithm == lbAlgoHopCount { mgInfo.netLocAppMap[netLoc] = runLbAlgoHopCount(mgApps, netLoc) curLbSvc := mgInfo.netLocAppMap[netLoc] netLocAppMap[netLoc] = runLbAlgoHopCount(mgApps, netLoc, curLbSvc) } else { log.Error("LB algorithm not yet supported: ", mgInfo.mg.LoadBalancingAlgorithm) break } } mgInfo.netLocAppMap = netLocAppMap } func refreshMgSvcMapping() { Loading Loading @@ -533,7 +626,7 @@ func refreshMgSvcMapping() { // notification and update mapping if bestApp != currentApp { log.Info("Best App: " + bestApp + " != Current App: " + currentApp) completeStateTransfer(mgInfo, netElemInfo, ueInfo, mgm.elemToSvcMap[currentApp]) completeStateTransfer(mgInfo, netElemInfo, ueInfo, currentApp) setSvcMap(netElemInfo, mgInfo.mg.Name, bestApp) } Loading @@ -557,7 +650,7 @@ func refreshMgSvcMapping() { // notification and update mapping if bestApp != currentApp { log.Info("Best App: " + bestApp + " != Current App: " + currentApp) completeStateTransfer(mgInfo, netElemInfo, ueInfo, mgm.elemToSvcMap[currentApp]) completeStateTransfer(mgInfo, netElemInfo, ueInfo, currentApp) setSvcMap(netElemInfo, mgInfo.mg.Name, bestApp) } Loading Loading @@ -596,7 +689,8 @@ func setSvcMap(netElemInfo *netElemInfo, mgSvcName string, lbSvcName string) { // LB Algorithm: // - Compare hop count from current pod to each instance // - Choose closest instance func runLbAlgoHopCount(services map[string]*serviceInfo, elem string) string { // - Prefer current instance when hop counts equal func runLbAlgoHopCount(services map[string]*serviceInfo, elem string, curLbSvc string) string { var minDist int64 = -1 var lbSvc = "" Loading @@ -607,7 +701,7 @@ func runLbAlgoHopCount(services map[string]*serviceInfo, elem string) string { path, _ := mgm.networkGraph.Shortest(src, dst) // Store as LB service if closest service instance if lbSvc == "" || path.Distance < minDist { if lbSvc == "" || path.Distance < minDist || (path.Distance == minDist && svc.name == curLbSvc) { minDist = path.Distance lbSvc = svc.name } Loading @@ -624,8 +718,13 @@ func startStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app string event.Type_ = eventTypeStateTransferStart event.UeId = ue.ue.Id startTime := time.Now() appInfo := group.appInfoMap[app] if appInfo == nil { log.Error("App not found: ", app) return } //lint:ignore SA1012 context.TODO not supported here resp, err := group.appInfoMap[app].appClient.StateTransferApi.HandleEvent(nil, event) resp, err := appInfo.appClient.StateTransferApi.HandleEvent(nil, event) duration := float64(time.Since(startTime).Microseconds()) / 1000.0 if err != nil { log.Error(err.Error()) Loading @@ -648,8 +747,13 @@ func completeStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app str event.Type_ = eventTypeStateTransferComplete event.UeId = ue.ue.Id startTime := time.Now() appInfo := group.appInfoMap[app] if appInfo == nil { log.Error("App not found: ", app) return } //lint:ignore SA1012 context.TODO not supported here resp, err := group.appInfoMap[app].appClient.StateTransferApi.HandleEvent(nil, event) resp, err := appInfo.appClient.StateTransferApi.HandleEvent(nil, event) duration := float64(time.Since(startTime).Microseconds()) / 1000.0 if err != nil { log.Error(err.Error()) Loading @@ -659,7 +763,7 @@ func completeStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app str met.ObserveNotification(mgm.sandboxName, serviceName, notifStateTransferComplete, "", resp, duration) }() // Set flag indicating transfer has been started // Set flag indicating transfer has been completed elem.transferInProgress = false } Loading @@ -672,8 +776,13 @@ func cancelStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app strin event.Type_ = eventTypeStateTransferCancel event.UeId = ue.ue.Id startTime := time.Now() appInfo := group.appInfoMap[app] if appInfo == nil { log.Error("App not found: ", app) return } //lint:ignore SA1012 context.TODO not supported here resp, err := group.appInfoMap[app].appClient.StateTransferApi.HandleEvent(nil, event) resp, err := appInfo.appClient.StateTransferApi.HandleEvent(nil, event) duration := float64(time.Since(startTime).Microseconds()) / 1000.0 if err != nil { log.Error(err.Error()) Loading Loading @@ -723,22 +832,12 @@ func applyMgSvcMapping() { log.Error(err.Error()) return } // Send LB Rules Update message msg := mgm.mqLocal.CreateMsg(mq.MsgMgLbRulesUpdate, moduleTcEngine, mgm.sandboxName) log.Debug("TX MSG: ", mq.PrintMsg(msg)) err = mgm.mqLocal.SendMsg(msg) if err != nil { log.Error("Failed to send message. Error: ", err.Error()) } } func mgCreate(mg *mgModel.MobilityGroup) error { // Make sure group does not already exist if mgm.mgInfoMap[mg.Name] != nil { log.Warn("Mobility group already exists: ", mg.Name) err := errors.New("Mobility group already exists") return err return errors.New("Mobility group already exists") } // Create new Mobility Group & copy data Loading @@ -760,8 +859,8 @@ func mgUpdate(mg *mgModel.MobilityGroup) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mg.Name] if mgInfo == nil { log.Error("Mobility group does not exist: ", mg.Name) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mg.Name) log.Error(err.Error()) return err } Loading @@ -775,8 +874,8 @@ func mgUpdate(mg *mgModel.MobilityGroup) error { func mgDelete(mgName string) error { // Make sure group exists if mgm.mgInfoMap[mgName] == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } Loading @@ -791,14 +890,20 @@ func mgAppCreate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App does not already exist if mgInfo.appInfoMap[mgApp.Id] != nil { log.Error("Mobility group App already exists: ", mgApp.Id) err := errors.New("Mobility group App already exists") err := errors.New("Mobility group App already exists: " + mgApp.Id) log.Error(err.Error()) return err } // Make sure App ID is equal to a service instance if mgm.svcInfoMap[mgApp.Id] == nil { err := errors.New("MG App ID not equal to service instance: " + mgApp.Id) log.Error(err.Error()) return err } Loading @@ -819,6 +924,8 @@ func mgAppCreate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Add to MG App map & App client map mgInfo.appInfoMap[mgApp.Id] = mgAppInfo log.Info("Created new MG App: " + mgApp.Id + " in group: " + mgName) // Re-evaluate MG best app instance for each scenario network location refreshNetLocAppMap(mgInfo) // Re-evaluate MG Service mapping Loading @@ -827,6 +934,9 @@ func mgAppCreate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() return nil } Loading @@ -834,15 +944,15 @@ func mgAppUpdate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App exists mgAppInfo := mgInfo.appInfoMap[mgApp.Id] if mgAppInfo == nil { log.Error("Mobility group App does not exist: ", mgApp.Id) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + mgApp.Id) log.Error(err.Error()) return err } Loading @@ -854,8 +964,8 @@ func mgAppUpdate(mgName string, mgApp *mgModel.MobilityGroupApp) error { mgAppClientCfg.BasePath = mgApp.Url mgAppInfo.appClient = mga.NewAPIClient(mgAppClientCfg) if mgAppInfo.appClient == nil { log.Error("Failed to create MG App REST API client: ", mgAppClientCfg.BasePath) err := errors.New("Failed to create MG App REST API client") err := errors.New("Failed to create MG App REST API client: " + mgAppClientCfg.BasePath) log.Error(err.Error()) return err } Loading @@ -867,20 +977,22 @@ func mgAppDelete(mgName string, appID string) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App exists if mgInfo.appInfoMap[appID] == nil { log.Error("Mobility group App does not exist: ", appID) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + appID) log.Error(err.Error()) return err } // Remove entry from App map & App Client map delete(mgInfo.appInfoMap, appID) log.Info("Deleted MG App: " + appID + " in group: " + mgName) // Re-evaluate MG best app instance for each scenario network location refreshNetLocAppMap(mgInfo) return nil Loading @@ -890,14 +1002,21 @@ func mgUeCreate(mgName string, appID string, mgUe *mgModel.MobilityGroupUe) erro // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App exists if mgInfo.appInfoMap[appID] == nil { log.Error("Mobility group App does not exist: ", appID) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + appID) log.Error(err.Error()) return err } // Make sure UE is in active scenario ueNodeType := mgm.activeModel.GetNodeType(mgUe.Id) if ueNodeType != mod.NodeTypeUE { err := errors.New("MG UE ID not found in active scenario: " + mgUe.Id) log.Error(err.Error()) return err } Loading @@ -915,6 +1034,9 @@ func mgUeCreate(mgName string, appID string, mgUe *mgModel.MobilityGroupUe) erro // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } return nil } Loading @@ -925,23 +1047,22 @@ func processAppState(mgName string, appID string, mgAppState *mgModel.MobilityGr // Retrieve MG info mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Retrieve App info appInfo := mgInfo.appInfoMap[appID] if appInfo == nil { log.Error("Mobility group App does not exist: ", appID) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + appID) log.Error(err.Error()) return err } // Retrieve UE Info ueInfo := mgInfo.ueInfoMap[mgAppState.UeId] if ueInfo == nil { log.Error("Mobility group UE does not exist: ", mgAppState.UeId) err := errors.New("Mobility group UE does not exist") err := errors.New("Mobility group UE does not exist: " + mgAppState.UeId) log.Error(err.Error()) return err } Loading @@ -955,8 +1076,6 @@ func processAppState(mgName string, appID string, mgAppState *mgModel.MobilityGr mgm.mutex.Lock() for appName := range ueInfo.appsInRange { appName = mgm.elemToSvcMap[appName] if appName != appID { appInfo := mgInfo.appInfoMap[appName] if appInfo == nil { Loading Loading @@ -1432,14 +1551,6 @@ func mgTransferAppState(w http.ResponseWriter, r *http.Request) { // log.Debug(" " + k) // } // } // log.Debug("+++ svcToElemMap:") // for k, v := range mgm.svcToElemMap { // log.Debug(" " + k + ":" + v) // } // log.Debug("+++ elemToSvcMap:") // for k, v := range mgm.elemToSvcMap { // log.Debug(" " + k + ":" + v) // } // log.Debug("+++ netElemInfoMap:") // for netElemName, netElemInfo := range mgm.netElemInfoMap { // log.Debug(" " + netElemName + ":") Loading go-apps/meep-sandbox-ctrl/server/sandbox-ctrl.go +3 −50 Original line number Diff line number Diff line Loading @@ -674,7 +674,6 @@ func sendEventPoasInRange(event dataModel.Event) (error, int, string) { err := errors.New("Malformed request: missing EventPoasInRange") return err, http.StatusBadRequest, "" } var ue *dataModel.PhysicalLocation // Retrieve UE name ueName := event.EventPoasInRange.Ue Loading @@ -685,41 +684,9 @@ func sendEventPoasInRange(event dataModel.Event) (error, int, string) { description := "[" + ueName + "] poas in range: " + strings.Join(poasInRange, ", ") // Find UE log.Debug("Searching for UE in active scenario") n := sbxCtrl.activeModel.GetNode(ueName) if n == nil { err := errors.New("Node not found " + ueName) return err, http.StatusNotFound, "" } ue, ok := n.(*dataModel.PhysicalLocation) if !ok { ue = nil } else if ue.Type_ != "UE" { ue = nil } // Update POAS in range if necessary if ue != nil { log.Debug("UE Found. Checking for update to visible POAs") // Compare new list of poas with current UE list and update if necessary if !equal(poasInRange, ue.NetworkLocationsInRange) { log.Debug("Updating POAs in range for UE: " + ue.Name) ue.NetworkLocationsInRange = poasInRange //Publish updated scenario err := sbxCtrl.activeModel.Activate() // Update active model err := sbxCtrl.activeModel.UpdatePoasInRange(ueName, poasInRange, nil) if err != nil { return err, http.StatusInternalServerError, "" } log.Debug("Active scenario updated") } else { log.Debug("POA list unchanged. Ignoring.") } } else { err := errors.New("Failed to find UE") return err, http.StatusNotFound, "" } return nil, -1, description Loading Loading @@ -786,20 +753,6 @@ func getScenarioNodeName(node *dataModel.ScenarioNode) string { return name } // Equal tells whether a and b contain the same elements. // A nil argument is equivalent to an empty slice. func equal(a, b []string) bool { if len(a) != len(b) { return false } for i, v := range a { if v != b[i] { return false } } return true } func ceCreateReplayFile(w http.ResponseWriter, r *http.Request) { log.Debug("ceCreateReplayFile") vars := mux.Vars(r) Loading go-apps/meep-tc-engine/routing-engine.go +19 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,17 @@ const typeMeSvc string = "ME-SVC" const typeIngressSvc string = "INGRESS-SVC" const typeEgressSvc string = "EGRESS-SVC" const fieldSvcType string = "svc-type" const fieldSvcName string = "svc-name" const fieldSvcIp string = "svc-ip" const fieldSvcProtocol string = "svc-protocol" const fieldSvcPort string = "svc-port" const fieldLbSvcName string = "lb-svc-name" const fieldLbSvcIp string = "lb-svc-ip" const fieldLbSvcPort string = "lb-svc-port" const fieldLbPodName string = "lb-pod-name" const fieldLbPodIp string = "lb-pod-ip" const DEFAULT_LB_RULES_DB = 0 // LbRulesStore - Loading Loading @@ -96,6 +107,8 @@ func (re *RoutingEngine) RefreshLbRules() { for _, svcMap := range netElem.ServiceMaps { if svcInfo, found := svcInfoMap[svcMap.LbSvcName]; found { podInfo.MgSvcMap[svcMap.MgSvcName] = svcInfo } else { log.Error("failed to find service instance: ", svcMap.LbSvcName) } } } Loading Loading @@ -141,6 +154,8 @@ func (re *RoutingEngine) applyLbRules() { fields[fieldLbSvcName] = svcInfo.Name fields[fieldLbSvcIp] = tce.ipManager.GetSvcIp(svcInfo.Name) fields[fieldLbSvcPort] = portInfo.Port fields[fieldLbPodName] = svcInfo.Node fields[fieldLbPodIp] = tce.ipManager.GetPodIp(svcInfo.Node) // Make unique key key := tce.netCharStore.baseKey + typeLb + ":" + podInfo.Name + ":" + Loading Loading @@ -176,6 +191,8 @@ func (re *RoutingEngine) applyLbRules() { fields[fieldLbSvcName] = svcInfo.Name fields[fieldLbSvcIp] = tce.ipManager.GetSvcIp(svcInfo.Name) fields[fieldLbSvcPort] = svcMap.SvcPort fields[fieldLbPodName] = svcInfo.Node fields[fieldLbPodIp] = tce.ipManager.GetPodIp(svcInfo.Node) // Make unique key key := tce.netCharStore.baseKey + typeLb + ":" + podInfo.Name + ":" + Loading @@ -198,6 +215,8 @@ func (re *RoutingEngine) applyLbRules() { fields[fieldLbSvcName] = svcMap.SvcName fields[fieldLbSvcIp] = svcMap.SvcIp fields[fieldLbSvcPort] = svcMap.SvcPort fields[fieldLbPodName] = "n/a" fields[fieldLbPodIp] = IP_ADDR_NONE // Make unique key key := tce.netCharStore.baseKey + typeLb + ":" + podInfo.Name + ":" + Loading go-apps/meep-tc-engine/tc-engine.go +0 −9 Original line number Diff line number Diff line Loading @@ -40,15 +40,6 @@ const tcEngineKey string = "tc-engine:" const mgManagerKey string = "mg-manager:" const typeNet string = "net" const fieldSvcType string = "svc-type" const fieldSvcName string = "svc-name" const fieldSvcIp string = "svc-ip" const fieldSvcProtocol string = "svc-protocol" const fieldSvcPort string = "svc-port" const fieldLbSvcName string = "lb-svc-name" const fieldLbSvcIp string = "lb-svc-ip" const fieldLbSvcPort string = "lb-svc-port" // MQ payload fields const fieldEventType = "event-type" Loading go-apps/meep-tc-sidecar/destination.go +2 −8 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ func (u *destination) compute() (st stat) { return } func (u *destination) processRxTx(ifbStatsStr string) float64 { func (u *destination) processRxTx(ifbStatsStr string, curTime time.Time) float64 { // Retrieve ifb statistics from passed string // NOTE: we have to read the ifbStats from the back since based on the results are always at Loading @@ -164,9 +164,6 @@ func (u *destination) processRxTx(ifbStatsStr string) float64 { log.Error("Error in the ifb statistics output: ", ifbStats) } // Get timestamp for calculations curTime := time.Now() // Calculate throughput in Mbps var tput float64 rxBytes := curRxBytes - u.prevRx.rxBytes Loading @@ -182,7 +179,7 @@ func (u *destination) processRxTx(ifbStatsStr string) float64 { return tput } func (u *destination) logRxTx(ifbStatsStr string) { func (u *destination) logRxTx(ifbStatsStr string, curTime time.Time) { // Retrieve ifb statistics from passed string // NOTE: we have to read the ifbStats from the back since based on the results are always at Loading @@ -199,9 +196,6 @@ func (u *destination) logRxTx(ifbStatsStr string) { log.Error("Error in the ifb statistics output: ", ifbStats) } // Get timestamp for calculations curTime := time.Now() // Calculate packet loss percentage var loss float64 rxPkt := curRxPkt - u.prevRxLog.rxPkt Loading Loading
go-apps/meep-mg-manager/server/mg-manager.go +216 −105 Original line number Diff line number Diff line Loading @@ -85,6 +85,9 @@ const lbAlgoHopCount = "HOP-COUNT" // const lbAlgoDistance = "DISTANCE" // const lbAlgoNone = "NONE" // MQ payload fields const fieldEventType = "event-type" type mgInfo struct { mg mgModel.MobilityGroup appInfoMap map[string]*appInfo Loading Loading @@ -144,17 +147,11 @@ type MgManager struct { activeModel *mod.Model lbRulesStore *lbRulesStore // Scenario network location list // Scenario data netLocList []string // Scenario service mappings svcInfoMap map[string]*serviceInfo mgSvcInfoMap map[string]*mgServiceInfo // mapping from element name to svc name for usercharts svcToElemMap map[string]string elemToSvcMap map[string]string // Network Element Info mapping netElemInfoMap map[string]*netElemInfo Loading @@ -170,8 +167,6 @@ func Init() (err error) { mgm.netLocList = make([]string, 0) mgm.svcInfoMap = make(map[string]*serviceInfo) mgm.mgSvcInfoMap = make(map[string]*mgServiceInfo) mgm.svcToElemMap = make(map[string]string) mgm.elemToSvcMap = make(map[string]string) mgm.netElemInfoMap = make(map[string]*netElemInfo) mgm.mgInfoMap = make(map[string]*mgInfo) Loading Loading @@ -222,7 +217,7 @@ func Init() (err error) { _ = mgm.lbRulesStore.rc.DBFlush(mgm.baseKey) // Initialize Edge-LB rules with current active scenario processActiveScenarioUpdate() processScenarioActivate() return nil } Loading @@ -246,35 +241,67 @@ func msgHandler(msg *mq.Msg, userData interface{}) { switch msg.Message { case mq.MsgScenarioActivate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) processActiveScenarioUpdate() processScenarioActivate() case mq.MsgScenarioUpdate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) processActiveScenarioUpdate() eventType := msg.Payload[fieldEventType] processScenarioUpdate(eventType) case mq.MsgScenarioTerminate: log.Debug("RX MSG: ", mq.PrintMsg(msg)) processActiveScenarioUpdate() processScenarioTerminate() default: log.Trace("Ignoring unsupported message: ", mq.PrintMsg(msg)) } } func processActiveScenarioUpdate() { func processScenarioActivate() { // Sync with active scenario store mgm.activeModel.UpdateScenario() scenarioName := mgm.activeModel.GetScenarioName() if mgm.scenarioName != scenarioName { mgm.scenarioName = scenarioName _ = httpLog.ReInit(moduleName, mgm.sandboxName, scenarioName, redisAddr, influxAddr) // Get scenario name mgm.scenarioName = mgm.activeModel.GetScenarioName() if mgm.scenarioName == "" { log.Error("Failed to find active scenario") return } // Handle empty/missing scenario if scenarioName == "" { clearScenario() // Initialize HTTP metrics logger with scenario name _ = httpLog.ReInit(moduleName, mgm.sandboxName, mgm.scenarioName, redisAddr, influxAddr) // Parse scenario err := processScenario(mgm.activeModel) if err != nil { log.Error("Failed to process scenario with error: ", err.Error()) return } // Re-evaluate Network location Edge-LB mappings refreshNetLocAppMaps() // Re-evaluate MG Service mapping refreshMgSvcMapping() // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } func processScenarioUpdate(eventType string) { // Ignore unsupported update types switch eventType { case mod.EventMobility, mod.EventPoaInRange, mod.EventAddNode, mod.EventModifyNode, mod.EventRemoveNode: break default: return } // Sync with active scenario store mgm.activeModel.UpdateScenario() // Parse scenario err := processScenario(mgm.activeModel) if err != nil { Loading @@ -282,30 +309,48 @@ func processActiveScenarioUpdate() { return } // Set Default Edge-LB mapping setDefaultNetLocAppMaps() // Re-evaluate Network location Edge-LB mappings refreshNetLocAppMaps() // Re-evaluate MG Service mapping refreshMgSvcMapping() // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } func processScenarioTerminate() { // Sync with active scenario store mgm.activeModel.UpdateScenario() // Clear scenario data clearScenario() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } func clearScenario() { log.Debug("clearScenario() -- Resetting all variables") mgm.scenarioName = "" mgm.networkGraph = nil mgm.netLocList = make([]string, 0) mgm.svcInfoMap = make(map[string]*serviceInfo) mgm.mgSvcInfoMap = make(map[string]*mgServiceInfo) mgm.svcToElemMap = make(map[string]string) mgm.elemToSvcMap = make(map[string]string) mgm.netElemInfoMap = make(map[string]*netElemInfo) mgm.mgInfoMap = make(map[string]*mgInfo) // Flush module data and send update _ = mgm.lbRulesStore.rc.DBFlush(mgm.baseKey) } // publishLbRulesUpdate - Inform TC Engine of LB rules update func publishLbRulesUpdate() { // Send LB Rules Update message msg := mgm.mqLocal.CreateMsg(mq.MsgMgLbRulesUpdate, moduleTcEngine, mgm.sandboxName) Loading @@ -319,12 +364,20 @@ func clearScenario() { func processScenario(model *mod.Model) error { log.Debug("processScenario") // Reset service info maps mgm.svcInfoMap = make(map[string]*serviceInfo) mgm.mgSvcInfoMap = make(map[string]*mgServiceInfo) // Populate net location list mgm.netLocList = model.GetNodeNames(mod.NodeTypePoa, mod.NodeTypePoa4G, mod.NodeTypePoa5G, mod.NodeTypePoaWifi) mgm.netLocList = append(mgm.netLocList, model.GetNodeNames("DEFAULT")...) // Get list of processes procNames := model.GetNodeNames("CLOUD-APP", "EDGE-APP", "UE-APP") procNamesMap := make(map[string]bool) for _, procName := range procNames { procNamesMap[procName] = true } // Get network graph from model mgm.networkGraph = model.GetNetworkGraph() Loading Loading @@ -394,6 +447,38 @@ func processScenario(model *mod.Model) error { } } // Remove stale elements for procName := range mgm.netElemInfoMap { if _, found := procNamesMap[procName]; !found { log.Debug("Removing stale element: ", procName) delete(mgm.netElemInfoMap, procName) } } // Remove stale Mobility Groups for mgName, mgInfo := range mgm.mgInfoMap { if _, found := mgm.mgSvcInfoMap[mgName]; !found { log.Debug("Removing stale MG: ", mgName) delete(mgm.mgInfoMap, mgName) } else { // Remove stale MG Apps for appName := range mgInfo.appInfoMap { if _, found := procNamesMap[appName]; !found { log.Debug("Removing stale MG App: ", appName) delete(mgInfo.appInfoMap, appName) } } // Remove stale UEs for ueName := range mgInfo.ueInfoMap { ueNodeType := model.GetNodeType(ueName) if ueNodeType != mod.NodeTypeUE { log.Debug("Removing stale UE: ", ueName) delete(mgInfo.ueInfoMap, ueName) } } } } return nil } Loading Loading @@ -433,8 +518,6 @@ func addServiceInfo(svcName string, mgSvcName string, nodeName string) { // Add service instance to service info map mgm.svcInfoMap[svcInfo.name] = svcInfo mgm.svcToElemMap[svcInfo.name] = svcInfo.name mgm.elemToSvcMap[svcInfo.name] = svcInfo.name } func getNetElem(name string) *netElemInfo { Loading @@ -452,47 +535,57 @@ func getNetElem(name string) *netElemInfo { return netElem } func setDefaultNetLocAppMaps() { log.Debug("setDefaultNetLocAppMaps") // refreshNetLocAppMaps - Update all default & current network location application maps func refreshNetLocAppMaps() { log.Debug("refreshNetLocAppMaps") // For each MG Service & net location in scenario, use Group App instances from scenario and // default LB algorithm to determine which App instance is best for net location // For each mobility group, update the application maps for _, mgInfo := range mgm.mgInfoMap { // Only set on first pass if len(mgInfo.defaultNetLocAppMap) == 0 { for _, netLoc := range mgm.netLocList { mgInfo.defaultNetLocAppMap[netLoc] = runLbAlgoHopCount(mgm.mgSvcInfoMap[mgInfo.mg.Name].services, netLoc) // Refresh default Network Location App map refreshDefaultNetLocAppMap(mgInfo) // Refresh current Network Location App map refreshNetLocAppMap(mgInfo) } } // refreshDefaultNetLocAppMap - Update default network location application map for a single application func refreshDefaultNetLocAppMap(mgInfo *mgInfo) { log.Debug("refreshDefaultNetLocAppMap: ", mgInfo.mg.Name) // Use default LB algorithm to determine which App instance is best for each net location defaultNetLocAppMap := make(map[string]string) for _, netLoc := range mgm.netLocList { curLbSvc := mgInfo.defaultNetLocAppMap[netLoc] defaultNetLocAppMap[netLoc] = runLbAlgoHopCount(mgm.mgSvcInfoMap[mgInfo.mg.Name].services, netLoc, curLbSvc) } mgInfo.defaultNetLocAppMap = defaultNetLocAppMap } // refreshNetLocAppMap - Update current network location application map for a single application func refreshNetLocAppMap(mgInfo *mgInfo) { log.Debug("refreshNetLocAppMap") // Reset Net Loc App map mgInfo.netLocAppMap = make(map[string]string) log.Debug("refreshNetLocAppMap: ", mgInfo.mg.Name) // Retrieve list of registered app services var mgApps = map[string]*serviceInfo{} for _, appInfo := range mgInfo.appInfoMap { mgApps[appInfo.app.Id] = mgm.svcInfoMap[appInfo.app.Id] if mgApps[appInfo.app.Id] == nil { mgApps[appInfo.app.Id] = mgm.svcInfoMap[mgm.svcToElemMap[appInfo.app.Id]] } } // Refresh current Network Location App map // For each net location in scenario, use Group LB algorithm to determine which // registered Group App is best for net location netLocAppMap := make(map[string]string) for _, netLoc := range mgm.netLocList { if mgInfo.mg.LoadBalancingAlgorithm == lbAlgoHopCount { mgInfo.netLocAppMap[netLoc] = runLbAlgoHopCount(mgApps, netLoc) curLbSvc := mgInfo.netLocAppMap[netLoc] netLocAppMap[netLoc] = runLbAlgoHopCount(mgApps, netLoc, curLbSvc) } else { log.Error("LB algorithm not yet supported: ", mgInfo.mg.LoadBalancingAlgorithm) break } } mgInfo.netLocAppMap = netLocAppMap } func refreshMgSvcMapping() { Loading Loading @@ -533,7 +626,7 @@ func refreshMgSvcMapping() { // notification and update mapping if bestApp != currentApp { log.Info("Best App: " + bestApp + " != Current App: " + currentApp) completeStateTransfer(mgInfo, netElemInfo, ueInfo, mgm.elemToSvcMap[currentApp]) completeStateTransfer(mgInfo, netElemInfo, ueInfo, currentApp) setSvcMap(netElemInfo, mgInfo.mg.Name, bestApp) } Loading @@ -557,7 +650,7 @@ func refreshMgSvcMapping() { // notification and update mapping if bestApp != currentApp { log.Info("Best App: " + bestApp + " != Current App: " + currentApp) completeStateTransfer(mgInfo, netElemInfo, ueInfo, mgm.elemToSvcMap[currentApp]) completeStateTransfer(mgInfo, netElemInfo, ueInfo, currentApp) setSvcMap(netElemInfo, mgInfo.mg.Name, bestApp) } Loading Loading @@ -596,7 +689,8 @@ func setSvcMap(netElemInfo *netElemInfo, mgSvcName string, lbSvcName string) { // LB Algorithm: // - Compare hop count from current pod to each instance // - Choose closest instance func runLbAlgoHopCount(services map[string]*serviceInfo, elem string) string { // - Prefer current instance when hop counts equal func runLbAlgoHopCount(services map[string]*serviceInfo, elem string, curLbSvc string) string { var minDist int64 = -1 var lbSvc = "" Loading @@ -607,7 +701,7 @@ func runLbAlgoHopCount(services map[string]*serviceInfo, elem string) string { path, _ := mgm.networkGraph.Shortest(src, dst) // Store as LB service if closest service instance if lbSvc == "" || path.Distance < minDist { if lbSvc == "" || path.Distance < minDist || (path.Distance == minDist && svc.name == curLbSvc) { minDist = path.Distance lbSvc = svc.name } Loading @@ -624,8 +718,13 @@ func startStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app string event.Type_ = eventTypeStateTransferStart event.UeId = ue.ue.Id startTime := time.Now() appInfo := group.appInfoMap[app] if appInfo == nil { log.Error("App not found: ", app) return } //lint:ignore SA1012 context.TODO not supported here resp, err := group.appInfoMap[app].appClient.StateTransferApi.HandleEvent(nil, event) resp, err := appInfo.appClient.StateTransferApi.HandleEvent(nil, event) duration := float64(time.Since(startTime).Microseconds()) / 1000.0 if err != nil { log.Error(err.Error()) Loading @@ -648,8 +747,13 @@ func completeStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app str event.Type_ = eventTypeStateTransferComplete event.UeId = ue.ue.Id startTime := time.Now() appInfo := group.appInfoMap[app] if appInfo == nil { log.Error("App not found: ", app) return } //lint:ignore SA1012 context.TODO not supported here resp, err := group.appInfoMap[app].appClient.StateTransferApi.HandleEvent(nil, event) resp, err := appInfo.appClient.StateTransferApi.HandleEvent(nil, event) duration := float64(time.Since(startTime).Microseconds()) / 1000.0 if err != nil { log.Error(err.Error()) Loading @@ -659,7 +763,7 @@ func completeStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app str met.ObserveNotification(mgm.sandboxName, serviceName, notifStateTransferComplete, "", resp, duration) }() // Set flag indicating transfer has been started // Set flag indicating transfer has been completed elem.transferInProgress = false } Loading @@ -672,8 +776,13 @@ func cancelStateTransfer(group *mgInfo, elem *netElemInfo, ue *ueInfo, app strin event.Type_ = eventTypeStateTransferCancel event.UeId = ue.ue.Id startTime := time.Now() appInfo := group.appInfoMap[app] if appInfo == nil { log.Error("App not found: ", app) return } //lint:ignore SA1012 context.TODO not supported here resp, err := group.appInfoMap[app].appClient.StateTransferApi.HandleEvent(nil, event) resp, err := appInfo.appClient.StateTransferApi.HandleEvent(nil, event) duration := float64(time.Since(startTime).Microseconds()) / 1000.0 if err != nil { log.Error(err.Error()) Loading Loading @@ -723,22 +832,12 @@ func applyMgSvcMapping() { log.Error(err.Error()) return } // Send LB Rules Update message msg := mgm.mqLocal.CreateMsg(mq.MsgMgLbRulesUpdate, moduleTcEngine, mgm.sandboxName) log.Debug("TX MSG: ", mq.PrintMsg(msg)) err = mgm.mqLocal.SendMsg(msg) if err != nil { log.Error("Failed to send message. Error: ", err.Error()) } } func mgCreate(mg *mgModel.MobilityGroup) error { // Make sure group does not already exist if mgm.mgInfoMap[mg.Name] != nil { log.Warn("Mobility group already exists: ", mg.Name) err := errors.New("Mobility group already exists") return err return errors.New("Mobility group already exists") } // Create new Mobility Group & copy data Loading @@ -760,8 +859,8 @@ func mgUpdate(mg *mgModel.MobilityGroup) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mg.Name] if mgInfo == nil { log.Error("Mobility group does not exist: ", mg.Name) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mg.Name) log.Error(err.Error()) return err } Loading @@ -775,8 +874,8 @@ func mgUpdate(mg *mgModel.MobilityGroup) error { func mgDelete(mgName string) error { // Make sure group exists if mgm.mgInfoMap[mgName] == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } Loading @@ -791,14 +890,20 @@ func mgAppCreate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App does not already exist if mgInfo.appInfoMap[mgApp.Id] != nil { log.Error("Mobility group App already exists: ", mgApp.Id) err := errors.New("Mobility group App already exists") err := errors.New("Mobility group App already exists: " + mgApp.Id) log.Error(err.Error()) return err } // Make sure App ID is equal to a service instance if mgm.svcInfoMap[mgApp.Id] == nil { err := errors.New("MG App ID not equal to service instance: " + mgApp.Id) log.Error(err.Error()) return err } Loading @@ -819,6 +924,8 @@ func mgAppCreate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Add to MG App map & App client map mgInfo.appInfoMap[mgApp.Id] = mgAppInfo log.Info("Created new MG App: " + mgApp.Id + " in group: " + mgName) // Re-evaluate MG best app instance for each scenario network location refreshNetLocAppMap(mgInfo) // Re-evaluate MG Service mapping Loading @@ -827,6 +934,9 @@ func mgAppCreate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() return nil } Loading @@ -834,15 +944,15 @@ func mgAppUpdate(mgName string, mgApp *mgModel.MobilityGroupApp) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App exists mgAppInfo := mgInfo.appInfoMap[mgApp.Id] if mgAppInfo == nil { log.Error("Mobility group App does not exist: ", mgApp.Id) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + mgApp.Id) log.Error(err.Error()) return err } Loading @@ -854,8 +964,8 @@ func mgAppUpdate(mgName string, mgApp *mgModel.MobilityGroupApp) error { mgAppClientCfg.BasePath = mgApp.Url mgAppInfo.appClient = mga.NewAPIClient(mgAppClientCfg) if mgAppInfo.appClient == nil { log.Error("Failed to create MG App REST API client: ", mgAppClientCfg.BasePath) err := errors.New("Failed to create MG App REST API client") err := errors.New("Failed to create MG App REST API client: " + mgAppClientCfg.BasePath) log.Error(err.Error()) return err } Loading @@ -867,20 +977,22 @@ func mgAppDelete(mgName string, appID string) error { // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App exists if mgInfo.appInfoMap[appID] == nil { log.Error("Mobility group App does not exist: ", appID) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + appID) log.Error(err.Error()) return err } // Remove entry from App map & App Client map delete(mgInfo.appInfoMap, appID) log.Info("Deleted MG App: " + appID + " in group: " + mgName) // Re-evaluate MG best app instance for each scenario network location refreshNetLocAppMap(mgInfo) return nil Loading @@ -890,14 +1002,21 @@ func mgUeCreate(mgName string, appID string, mgUe *mgModel.MobilityGroupUe) erro // Make sure group exists mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Make sure App exists if mgInfo.appInfoMap[appID] == nil { log.Error("Mobility group App does not exist: ", appID) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + appID) log.Error(err.Error()) return err } // Make sure UE is in active scenario ueNodeType := mgm.activeModel.GetNodeType(mgUe.Id) if ueNodeType != mod.NodeTypeUE { err := errors.New("MG UE ID not found in active scenario: " + mgUe.Id) log.Error(err.Error()) return err } Loading @@ -915,6 +1034,9 @@ func mgUeCreate(mgName string, appID string, mgUe *mgModel.MobilityGroupUe) erro // Store & Apply latest MG Service mappings applyMgSvcMapping() // Inform TC Engine of LB rules updatge publishLbRulesUpdate() } return nil } Loading @@ -925,23 +1047,22 @@ func processAppState(mgName string, appID string, mgAppState *mgModel.MobilityGr // Retrieve MG info mgInfo := mgm.mgInfoMap[mgName] if mgInfo == nil { log.Error("Mobility group does not exist: ", mgName) err := errors.New("Mobility group does not exist") err := errors.New("Mobility group does not exist: " + mgName) log.Error(err.Error()) return err } // Retrieve App info appInfo := mgInfo.appInfoMap[appID] if appInfo == nil { log.Error("Mobility group App does not exist: ", appID) err := errors.New("Mobility group App does not exist") err := errors.New("Mobility group App does not exist: " + appID) log.Error(err.Error()) return err } // Retrieve UE Info ueInfo := mgInfo.ueInfoMap[mgAppState.UeId] if ueInfo == nil { log.Error("Mobility group UE does not exist: ", mgAppState.UeId) err := errors.New("Mobility group UE does not exist") err := errors.New("Mobility group UE does not exist: " + mgAppState.UeId) log.Error(err.Error()) return err } Loading @@ -955,8 +1076,6 @@ func processAppState(mgName string, appID string, mgAppState *mgModel.MobilityGr mgm.mutex.Lock() for appName := range ueInfo.appsInRange { appName = mgm.elemToSvcMap[appName] if appName != appID { appInfo := mgInfo.appInfoMap[appName] if appInfo == nil { Loading Loading @@ -1432,14 +1551,6 @@ func mgTransferAppState(w http.ResponseWriter, r *http.Request) { // log.Debug(" " + k) // } // } // log.Debug("+++ svcToElemMap:") // for k, v := range mgm.svcToElemMap { // log.Debug(" " + k + ":" + v) // } // log.Debug("+++ elemToSvcMap:") // for k, v := range mgm.elemToSvcMap { // log.Debug(" " + k + ":" + v) // } // log.Debug("+++ netElemInfoMap:") // for netElemName, netElemInfo := range mgm.netElemInfoMap { // log.Debug(" " + netElemName + ":") Loading
go-apps/meep-sandbox-ctrl/server/sandbox-ctrl.go +3 −50 Original line number Diff line number Diff line Loading @@ -674,7 +674,6 @@ func sendEventPoasInRange(event dataModel.Event) (error, int, string) { err := errors.New("Malformed request: missing EventPoasInRange") return err, http.StatusBadRequest, "" } var ue *dataModel.PhysicalLocation // Retrieve UE name ueName := event.EventPoasInRange.Ue Loading @@ -685,41 +684,9 @@ func sendEventPoasInRange(event dataModel.Event) (error, int, string) { description := "[" + ueName + "] poas in range: " + strings.Join(poasInRange, ", ") // Find UE log.Debug("Searching for UE in active scenario") n := sbxCtrl.activeModel.GetNode(ueName) if n == nil { err := errors.New("Node not found " + ueName) return err, http.StatusNotFound, "" } ue, ok := n.(*dataModel.PhysicalLocation) if !ok { ue = nil } else if ue.Type_ != "UE" { ue = nil } // Update POAS in range if necessary if ue != nil { log.Debug("UE Found. Checking for update to visible POAs") // Compare new list of poas with current UE list and update if necessary if !equal(poasInRange, ue.NetworkLocationsInRange) { log.Debug("Updating POAs in range for UE: " + ue.Name) ue.NetworkLocationsInRange = poasInRange //Publish updated scenario err := sbxCtrl.activeModel.Activate() // Update active model err := sbxCtrl.activeModel.UpdatePoasInRange(ueName, poasInRange, nil) if err != nil { return err, http.StatusInternalServerError, "" } log.Debug("Active scenario updated") } else { log.Debug("POA list unchanged. Ignoring.") } } else { err := errors.New("Failed to find UE") return err, http.StatusNotFound, "" } return nil, -1, description Loading Loading @@ -786,20 +753,6 @@ func getScenarioNodeName(node *dataModel.ScenarioNode) string { return name } // Equal tells whether a and b contain the same elements. // A nil argument is equivalent to an empty slice. func equal(a, b []string) bool { if len(a) != len(b) { return false } for i, v := range a { if v != b[i] { return false } } return true } func ceCreateReplayFile(w http.ResponseWriter, r *http.Request) { log.Debug("ceCreateReplayFile") vars := mux.Vars(r) Loading
go-apps/meep-tc-engine/routing-engine.go +19 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,17 @@ const typeMeSvc string = "ME-SVC" const typeIngressSvc string = "INGRESS-SVC" const typeEgressSvc string = "EGRESS-SVC" const fieldSvcType string = "svc-type" const fieldSvcName string = "svc-name" const fieldSvcIp string = "svc-ip" const fieldSvcProtocol string = "svc-protocol" const fieldSvcPort string = "svc-port" const fieldLbSvcName string = "lb-svc-name" const fieldLbSvcIp string = "lb-svc-ip" const fieldLbSvcPort string = "lb-svc-port" const fieldLbPodName string = "lb-pod-name" const fieldLbPodIp string = "lb-pod-ip" const DEFAULT_LB_RULES_DB = 0 // LbRulesStore - Loading Loading @@ -96,6 +107,8 @@ func (re *RoutingEngine) RefreshLbRules() { for _, svcMap := range netElem.ServiceMaps { if svcInfo, found := svcInfoMap[svcMap.LbSvcName]; found { podInfo.MgSvcMap[svcMap.MgSvcName] = svcInfo } else { log.Error("failed to find service instance: ", svcMap.LbSvcName) } } } Loading Loading @@ -141,6 +154,8 @@ func (re *RoutingEngine) applyLbRules() { fields[fieldLbSvcName] = svcInfo.Name fields[fieldLbSvcIp] = tce.ipManager.GetSvcIp(svcInfo.Name) fields[fieldLbSvcPort] = portInfo.Port fields[fieldLbPodName] = svcInfo.Node fields[fieldLbPodIp] = tce.ipManager.GetPodIp(svcInfo.Node) // Make unique key key := tce.netCharStore.baseKey + typeLb + ":" + podInfo.Name + ":" + Loading Loading @@ -176,6 +191,8 @@ func (re *RoutingEngine) applyLbRules() { fields[fieldLbSvcName] = svcInfo.Name fields[fieldLbSvcIp] = tce.ipManager.GetSvcIp(svcInfo.Name) fields[fieldLbSvcPort] = svcMap.SvcPort fields[fieldLbPodName] = svcInfo.Node fields[fieldLbPodIp] = tce.ipManager.GetPodIp(svcInfo.Node) // Make unique key key := tce.netCharStore.baseKey + typeLb + ":" + podInfo.Name + ":" + Loading @@ -198,6 +215,8 @@ func (re *RoutingEngine) applyLbRules() { fields[fieldLbSvcName] = svcMap.SvcName fields[fieldLbSvcIp] = svcMap.SvcIp fields[fieldLbSvcPort] = svcMap.SvcPort fields[fieldLbPodName] = "n/a" fields[fieldLbPodIp] = IP_ADDR_NONE // Make unique key key := tce.netCharStore.baseKey + typeLb + ":" + podInfo.Name + ":" + Loading
go-apps/meep-tc-engine/tc-engine.go +0 −9 Original line number Diff line number Diff line Loading @@ -40,15 +40,6 @@ const tcEngineKey string = "tc-engine:" const mgManagerKey string = "mg-manager:" const typeNet string = "net" const fieldSvcType string = "svc-type" const fieldSvcName string = "svc-name" const fieldSvcIp string = "svc-ip" const fieldSvcProtocol string = "svc-protocol" const fieldSvcPort string = "svc-port" const fieldLbSvcName string = "lb-svc-name" const fieldLbSvcIp string = "lb-svc-ip" const fieldLbSvcPort string = "lb-svc-port" // MQ payload fields const fieldEventType = "event-type" Loading
go-apps/meep-tc-sidecar/destination.go +2 −8 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ func (u *destination) compute() (st stat) { return } func (u *destination) processRxTx(ifbStatsStr string) float64 { func (u *destination) processRxTx(ifbStatsStr string, curTime time.Time) float64 { // Retrieve ifb statistics from passed string // NOTE: we have to read the ifbStats from the back since based on the results are always at Loading @@ -164,9 +164,6 @@ func (u *destination) processRxTx(ifbStatsStr string) float64 { log.Error("Error in the ifb statistics output: ", ifbStats) } // Get timestamp for calculations curTime := time.Now() // Calculate throughput in Mbps var tput float64 rxBytes := curRxBytes - u.prevRx.rxBytes Loading @@ -182,7 +179,7 @@ func (u *destination) processRxTx(ifbStatsStr string) float64 { return tput } func (u *destination) logRxTx(ifbStatsStr string) { func (u *destination) logRxTx(ifbStatsStr string, curTime time.Time) { // Retrieve ifb statistics from passed string // NOTE: we have to read the ifbStats from the back since based on the results are always at Loading @@ -199,9 +196,6 @@ func (u *destination) logRxTx(ifbStatsStr string) { log.Error("Error in the ifb statistics output: ", ifbStats) } // Get timestamp for calculations curTime := time.Now() // Calculate packet loss percentage var loss float64 rxPkt := curRxPkt - u.prevRxLog.rxPkt Loading