Loading go-apps/meep-gis-engine/server/gis-engine.go +115 −60 Original line number Diff line number Diff line Loading @@ -37,13 +37,18 @@ const redisAddr = "meep-redis-master.default.svc.cluster.local:6379" const postgisUser = "postgres" const postgisPwd = "pwd" type Asset struct { allocated bool assetType string } type GisEngine struct { sandboxName string mqLocal *mq.MsgQueue handlerId int activeModel *mod.Model pc *postgis.Connector unallocatedAssets map[string]string assets map[string]Asset } var ge *GisEngine Loading @@ -51,7 +56,7 @@ var ge *GisEngine // Init - GIS Engine initialization func Init() (err error) { ge = new(GisEngine) ge.unallocatedAssets = make(map[string]string) ge.assets = make(map[string]Asset) // Retrieve Sandbox name from environment variable ge.sandboxName = strings.TrimSpace(os.Getenv("MEEP_SANDBOX_NAME")) Loading Loading @@ -146,16 +151,66 @@ func processScenarioActivate() { // Retrieve & process Assets in active scenario assetList := ge.activeModel.GetNodeNames(mod.NodeTypeUE, mod.NodeTypePoa, mod.NodeTypePoaCell, mod.NodeTypeEdge, mod.NodeTypeFog) addAssets(assetList) } func processScenarioUpdate() { // Sync with active scenario store ge.activeModel.UpdateScenario() // Get latest asset list newAssetList := ge.activeModel.GetNodeNames(mod.NodeTypeUE, mod.NodeTypePoa, mod.NodeTypePoaCell, mod.NodeTypeEdge, mod.NodeTypeFog) newAssets := make(map[string]bool) var assetsToAdd []string var assetsToRemove []string // Compare with GIS Engine asset list to identify assets that should be added or removed from DB for _, assetName := range newAssetList { newAssets[assetName] = true asset, found := ge.assets[assetName] if !found || !asset.allocated { assetsToAdd = append(assetsToAdd, assetName) } } for assetName := range ge.assets { if _, found := newAssets[assetName]; !found { assetsToRemove = append(assetsToRemove, assetName) } } // Add & remove assets from model update addAssets(assetsToAdd) removeAssets(assetsToRemove) } func processScenarioTerminate() { // Sync with active scenario store ge.activeModel.UpdateScenario() // Flush all postgis tables _ = ge.pc.DeleteAllUe() _ = ge.pc.DeleteAllPoa() _ = ge.pc.DeleteAllCompute() // Clear unallocated asset list log.Debug("GeoData deleted for all assets") ge.assets = make(map[string]Asset) } func addAssets(assetList []string) { for _, assetName := range assetList { // Get node type nodeType := ge.activeModel.GetNodeType(assetName) // Default asset to unallocated state ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} if nodeType == mod.NodeTypeUE { pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) // Parse Geo Data position, path, _, err := parseGeoData(pl.GeoData) if err != nil { ge.unallocatedAssets[assetName] = nodeType continue } Loading @@ -163,16 +218,16 @@ func processScenarioActivate() { err = ge.pc.CreateUe(pl.Id, assetName, position, path, postgis.PathModeLoop, 0.000) if err != nil { log.Error(err.Error()) ge.unallocatedAssets[assetName] = nodeType continue } log.Debug("GeoData stored for UE: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { nl := (ge.activeModel.GetNode(assetName)).(*dataModel.NetworkLocation) // Parse Geo Data position, _, radius, err := parseGeoData(nl.GeoData) if err != nil { ge.unallocatedAssets[assetName] = nodeType continue } Loading @@ -180,16 +235,16 @@ func processScenarioActivate() { err = ge.pc.CreatePoa(nl.Id, assetName, nodeType, position, radius) if err != nil { log.Error(err.Error()) ge.unallocatedAssets[assetName] = nodeType continue } log.Debug("GeoData stored for POA: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) // Parse Geo Data position, _, _, err := parseGeoData(pl.GeoData) if err != nil { ge.unallocatedAssets[assetName] = nodeType continue } Loading @@ -197,29 +252,47 @@ func processScenarioActivate() { err = ge.pc.CreateCompute(pl.Id, assetName, nodeType, position) if err != nil { log.Error(err.Error()) ge.unallocatedAssets[assetName] = nodeType continue } log.Debug("GeoData stored for Compute: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } } } func processScenarioUpdate() { // Sync with active scenario store ge.activeModel.UpdateScenario() } func processScenarioTerminate() { // Sync with active scenario store ge.activeModel.UpdateScenario() func removeAssets(assetList []string) { for _, assetName := range assetList { // Get asset node type nodeType := ge.assets[assetName].assetType // Flush all postgis tables _ = ge.pc.DeleteAllUe() _ = ge.pc.DeleteAllPoa() _ = ge.pc.DeleteAllCompute() // Remove asset delete(ge.assets, assetName) // Clear unallocated asset list ge.unallocatedAssets = make(map[string]string) if nodeType == mod.NodeTypeUE { log.Debug("GeoData deleted for UE: ", assetName) err := ge.pc.DeleteUe(assetName) if err != nil { log.Error(err.Error()) continue } } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { log.Debug("GeoData deleted for POA: ", assetName) err := ge.pc.DeletePoa(assetName) if err != nil { log.Error(err.Error()) continue } } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { log.Debug("GeoData deleted for Compute: ", assetName) err := ge.pc.DeleteCompute(assetName) if err != nil { log.Error(err.Error()) continue } } else { log.Error("Asset not found in scenario model") } } } func parseGeoData(geoData *dataModel.GeoData) (position string, path string, radius float32, err error) { Loading Loading @@ -314,30 +387,6 @@ func fillGeoDataAsset(geoData *GeoDataAsset, position string, path string, radiu return } // func getPositionString(point *Point) (position string) { // if point != nil { // positionBytes, err := json.Marshal(point) // if err != nil { // log.Error(err.Error()) // return "" // } // position = string(positionBytes) // } // return position // } // func getPathString(lineString *LineString) (path string) { // if lineString != nil { // pathBytes, err := json.Marshal(lineString) // if err != nil { // log.Error(err.Error()) // return "" // } // path = string(pathBytes) // } // return path // } // ---------------------------- REST API ------------------------------------ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { Loading @@ -364,7 +413,8 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get node type then remove it from the DB nodeType := ge.activeModel.GetNodeType(assetName) if nodeType == mod.NodeTypeUE { ge.unallocatedAssets[assetName] = nodeType log.Debug("GeoData deleted for UE: ", assetName) ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} err := ge.pc.DeleteUe(assetName) if err != nil { log.Error(err.Error()) Loading @@ -372,7 +422,8 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { return } } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { ge.unallocatedAssets[assetName] = nodeType log.Debug("GeoData deleted for POA: ", assetName) ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} err := ge.pc.DeletePoa(assetName) if err != nil { log.Error(err.Error()) Loading @@ -380,7 +431,8 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { return } } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { ge.unallocatedAssets[assetName] = nodeType log.Debug("GeoData deleted for Compute: ", assetName) ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} err := ge.pc.DeleteCompute(assetName) if err != nil { log.Error(err.Error()) Loading Loading @@ -648,7 +700,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { // Create/Update asset in DB nodeType := ge.activeModel.GetNodeType(assetName) if nodeType == mod.NodeTypeUE { if _, found := ge.unallocatedAssets[assetName]; found { if !ge.assets[assetName].allocated { // Create UE pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) err := ge.pc.CreateUe(pl.Id, assetName, position, path, postgis.PathModeLoop, 0.000) Loading @@ -657,7 +709,8 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } delete(ge.unallocatedAssets, assetName) log.Debug("GeoData stored for UE: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else { // Update UE err := ge.pc.UpdateUe(assetName, position, path, postgis.PathModeLoop, 0.000) Loading @@ -668,7 +721,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { } } } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { if _, found := ge.unallocatedAssets[assetName]; found { if !ge.assets[assetName].allocated { // Create POA nl := (ge.activeModel.GetNode(assetName)).(*dataModel.NetworkLocation) err := ge.pc.CreatePoa(nl.Id, assetName, nodeType, position, radius) Loading @@ -677,7 +730,8 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } delete(ge.unallocatedAssets, assetName) log.Debug("GeoData stored for POA: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else { // Update POA err := ge.pc.UpdatePoa(assetName, position, radius) Loading @@ -688,7 +742,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { } } } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { if _, found := ge.unallocatedAssets[assetName]; found { if !ge.assets[assetName].allocated { // Create Compute pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) err := ge.pc.CreateCompute(pl.Id, assetName, nodeType, position) Loading @@ -697,7 +751,8 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } delete(ge.unallocatedAssets, assetName) log.Debug("GeoData stored for Compute: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else { // Update Compute err := ge.pc.UpdateCompute(assetName, position) Loading go-packages/meep-postgis/db.go +1 −1 Original line number Diff line number Diff line Loading @@ -203,7 +203,7 @@ func (pc *Connector) CreateTables() (err error) { path_increment decimal(10,3) NOT NULL DEFAULT '0.000', path_fraction decimal(10,3) NOT NULL DEFAULT '0.000', poa varchar(100) NOT NULL DEFAULT '', poa_distance decimal(10,6) NOT NULL DEFAULT '0.000000', poa_distance decimal(10,3) NOT NULL DEFAULT '0.000', poa_in_range varchar(100)[] NOT NULL DEFAULT array[]::varchar[], start_time timestamptz NOT NULL DEFAULT now() )`) Loading go-packages/meep-postgis/db_test.go +18 −18 Original line number Diff line number Diff line Loading @@ -247,7 +247,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading @@ -259,7 +259,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -271,7 +271,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name}) { if !validateUe(ue, ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading Loading @@ -324,7 +324,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -337,7 +337,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -350,7 +350,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading @@ -375,10 +375,10 @@ func TestPostgisConnectorNew(t *testing.T) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa2Name, 0.000, []string{poa1Name, poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 391.15466, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 391.155, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name, poa2Name}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name, poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -397,13 +397,13 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || len(ueMap) != 3 { t.Fatalf("Failed to get all UE") } if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading Loading @@ -447,13 +447,13 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || len(ueMap) != 3 { t.Fatalf("Failed to get all UE") } if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa3Name, 328.98288, []string{}) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa3Name, 328.983, []string{}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa3Name, 268.81665, []string{}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa3Name, 268.817, []string{}) { t.Fatalf("UE validation failed") } Loading @@ -474,13 +474,13 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || len(ueMap) != 3 { t.Fatalf("Failed to get all UE") } if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading @@ -505,7 +505,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading Loading
go-apps/meep-gis-engine/server/gis-engine.go +115 −60 Original line number Diff line number Diff line Loading @@ -37,13 +37,18 @@ const redisAddr = "meep-redis-master.default.svc.cluster.local:6379" const postgisUser = "postgres" const postgisPwd = "pwd" type Asset struct { allocated bool assetType string } type GisEngine struct { sandboxName string mqLocal *mq.MsgQueue handlerId int activeModel *mod.Model pc *postgis.Connector unallocatedAssets map[string]string assets map[string]Asset } var ge *GisEngine Loading @@ -51,7 +56,7 @@ var ge *GisEngine // Init - GIS Engine initialization func Init() (err error) { ge = new(GisEngine) ge.unallocatedAssets = make(map[string]string) ge.assets = make(map[string]Asset) // Retrieve Sandbox name from environment variable ge.sandboxName = strings.TrimSpace(os.Getenv("MEEP_SANDBOX_NAME")) Loading Loading @@ -146,16 +151,66 @@ func processScenarioActivate() { // Retrieve & process Assets in active scenario assetList := ge.activeModel.GetNodeNames(mod.NodeTypeUE, mod.NodeTypePoa, mod.NodeTypePoaCell, mod.NodeTypeEdge, mod.NodeTypeFog) addAssets(assetList) } func processScenarioUpdate() { // Sync with active scenario store ge.activeModel.UpdateScenario() // Get latest asset list newAssetList := ge.activeModel.GetNodeNames(mod.NodeTypeUE, mod.NodeTypePoa, mod.NodeTypePoaCell, mod.NodeTypeEdge, mod.NodeTypeFog) newAssets := make(map[string]bool) var assetsToAdd []string var assetsToRemove []string // Compare with GIS Engine asset list to identify assets that should be added or removed from DB for _, assetName := range newAssetList { newAssets[assetName] = true asset, found := ge.assets[assetName] if !found || !asset.allocated { assetsToAdd = append(assetsToAdd, assetName) } } for assetName := range ge.assets { if _, found := newAssets[assetName]; !found { assetsToRemove = append(assetsToRemove, assetName) } } // Add & remove assets from model update addAssets(assetsToAdd) removeAssets(assetsToRemove) } func processScenarioTerminate() { // Sync with active scenario store ge.activeModel.UpdateScenario() // Flush all postgis tables _ = ge.pc.DeleteAllUe() _ = ge.pc.DeleteAllPoa() _ = ge.pc.DeleteAllCompute() // Clear unallocated asset list log.Debug("GeoData deleted for all assets") ge.assets = make(map[string]Asset) } func addAssets(assetList []string) { for _, assetName := range assetList { // Get node type nodeType := ge.activeModel.GetNodeType(assetName) // Default asset to unallocated state ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} if nodeType == mod.NodeTypeUE { pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) // Parse Geo Data position, path, _, err := parseGeoData(pl.GeoData) if err != nil { ge.unallocatedAssets[assetName] = nodeType continue } Loading @@ -163,16 +218,16 @@ func processScenarioActivate() { err = ge.pc.CreateUe(pl.Id, assetName, position, path, postgis.PathModeLoop, 0.000) if err != nil { log.Error(err.Error()) ge.unallocatedAssets[assetName] = nodeType continue } log.Debug("GeoData stored for UE: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { nl := (ge.activeModel.GetNode(assetName)).(*dataModel.NetworkLocation) // Parse Geo Data position, _, radius, err := parseGeoData(nl.GeoData) if err != nil { ge.unallocatedAssets[assetName] = nodeType continue } Loading @@ -180,16 +235,16 @@ func processScenarioActivate() { err = ge.pc.CreatePoa(nl.Id, assetName, nodeType, position, radius) if err != nil { log.Error(err.Error()) ge.unallocatedAssets[assetName] = nodeType continue } log.Debug("GeoData stored for POA: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) // Parse Geo Data position, _, _, err := parseGeoData(pl.GeoData) if err != nil { ge.unallocatedAssets[assetName] = nodeType continue } Loading @@ -197,29 +252,47 @@ func processScenarioActivate() { err = ge.pc.CreateCompute(pl.Id, assetName, nodeType, position) if err != nil { log.Error(err.Error()) ge.unallocatedAssets[assetName] = nodeType continue } log.Debug("GeoData stored for Compute: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } } } func processScenarioUpdate() { // Sync with active scenario store ge.activeModel.UpdateScenario() } func processScenarioTerminate() { // Sync with active scenario store ge.activeModel.UpdateScenario() func removeAssets(assetList []string) { for _, assetName := range assetList { // Get asset node type nodeType := ge.assets[assetName].assetType // Flush all postgis tables _ = ge.pc.DeleteAllUe() _ = ge.pc.DeleteAllPoa() _ = ge.pc.DeleteAllCompute() // Remove asset delete(ge.assets, assetName) // Clear unallocated asset list ge.unallocatedAssets = make(map[string]string) if nodeType == mod.NodeTypeUE { log.Debug("GeoData deleted for UE: ", assetName) err := ge.pc.DeleteUe(assetName) if err != nil { log.Error(err.Error()) continue } } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { log.Debug("GeoData deleted for POA: ", assetName) err := ge.pc.DeletePoa(assetName) if err != nil { log.Error(err.Error()) continue } } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { log.Debug("GeoData deleted for Compute: ", assetName) err := ge.pc.DeleteCompute(assetName) if err != nil { log.Error(err.Error()) continue } } else { log.Error("Asset not found in scenario model") } } } func parseGeoData(geoData *dataModel.GeoData) (position string, path string, radius float32, err error) { Loading Loading @@ -314,30 +387,6 @@ func fillGeoDataAsset(geoData *GeoDataAsset, position string, path string, radiu return } // func getPositionString(point *Point) (position string) { // if point != nil { // positionBytes, err := json.Marshal(point) // if err != nil { // log.Error(err.Error()) // return "" // } // position = string(positionBytes) // } // return position // } // func getPathString(lineString *LineString) (path string) { // if lineString != nil { // pathBytes, err := json.Marshal(lineString) // if err != nil { // log.Error(err.Error()) // return "" // } // path = string(pathBytes) // } // return path // } // ---------------------------- REST API ------------------------------------ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { Loading @@ -364,7 +413,8 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { // Get node type then remove it from the DB nodeType := ge.activeModel.GetNodeType(assetName) if nodeType == mod.NodeTypeUE { ge.unallocatedAssets[assetName] = nodeType log.Debug("GeoData deleted for UE: ", assetName) ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} err := ge.pc.DeleteUe(assetName) if err != nil { log.Error(err.Error()) Loading @@ -372,7 +422,8 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { return } } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { ge.unallocatedAssets[assetName] = nodeType log.Debug("GeoData deleted for POA: ", assetName) ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} err := ge.pc.DeletePoa(assetName) if err != nil { log.Error(err.Error()) Loading @@ -380,7 +431,8 @@ func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { return } } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { ge.unallocatedAssets[assetName] = nodeType log.Debug("GeoData deleted for Compute: ", assetName) ge.assets[assetName] = Asset{allocated: false, assetType: nodeType} err := ge.pc.DeleteCompute(assetName) if err != nil { log.Error(err.Error()) Loading Loading @@ -648,7 +700,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { // Create/Update asset in DB nodeType := ge.activeModel.GetNodeType(assetName) if nodeType == mod.NodeTypeUE { if _, found := ge.unallocatedAssets[assetName]; found { if !ge.assets[assetName].allocated { // Create UE pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) err := ge.pc.CreateUe(pl.Id, assetName, position, path, postgis.PathModeLoop, 0.000) Loading @@ -657,7 +709,8 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } delete(ge.unallocatedAssets, assetName) log.Debug("GeoData stored for UE: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else { // Update UE err := ge.pc.UpdateUe(assetName, position, path, postgis.PathModeLoop, 0.000) Loading @@ -668,7 +721,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { } } } else if nodeType == mod.NodeTypePoa || nodeType == mod.NodeTypePoaCell { if _, found := ge.unallocatedAssets[assetName]; found { if !ge.assets[assetName].allocated { // Create POA nl := (ge.activeModel.GetNode(assetName)).(*dataModel.NetworkLocation) err := ge.pc.CreatePoa(nl.Id, assetName, nodeType, position, radius) Loading @@ -677,7 +730,8 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } delete(ge.unallocatedAssets, assetName) log.Debug("GeoData stored for POA: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else { // Update POA err := ge.pc.UpdatePoa(assetName, position, radius) Loading @@ -688,7 +742,7 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { } } } else if nodeType == mod.NodeTypeFog || nodeType == mod.NodeTypeEdge { if _, found := ge.unallocatedAssets[assetName]; found { if !ge.assets[assetName].allocated { // Create Compute pl := (ge.activeModel.GetNode(assetName)).(*dataModel.PhysicalLocation) err := ge.pc.CreateCompute(pl.Id, assetName, nodeType, position) Loading @@ -697,7 +751,8 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } delete(ge.unallocatedAssets, assetName) log.Debug("GeoData stored for Compute: ", assetName) ge.assets[assetName] = Asset{allocated: true, assetType: nodeType} } else { // Update Compute err := ge.pc.UpdateCompute(assetName, position) Loading
go-packages/meep-postgis/db.go +1 −1 Original line number Diff line number Diff line Loading @@ -203,7 +203,7 @@ func (pc *Connector) CreateTables() (err error) { path_increment decimal(10,3) NOT NULL DEFAULT '0.000', path_fraction decimal(10,3) NOT NULL DEFAULT '0.000', poa varchar(100) NOT NULL DEFAULT '', poa_distance decimal(10,6) NOT NULL DEFAULT '0.000000', poa_distance decimal(10,3) NOT NULL DEFAULT '0.000', poa_in_range varchar(100)[] NOT NULL DEFAULT array[]::varchar[], start_time timestamptz NOT NULL DEFAULT now() )`) Loading
go-packages/meep-postgis/db_test.go +18 −18 Original line number Diff line number Diff line Loading @@ -247,7 +247,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading @@ -259,7 +259,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -271,7 +271,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name}) { if !validateUe(ue, ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading Loading @@ -324,7 +324,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -337,7 +337,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue1Id, ue1Name, ueLoc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -350,7 +350,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ue, ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading @@ -375,10 +375,10 @@ func TestPostgisConnectorNew(t *testing.T) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa2Name, 0.000, []string{poa1Name, poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 391.15466, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 391.155, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name, poa2Name}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name, poa2Name}) { t.Fatalf("UE validation failed") } Loading @@ -397,13 +397,13 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || len(ueMap) != 3 { t.Fatalf("Failed to get all UE") } if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading Loading @@ -447,13 +447,13 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || len(ueMap) != 3 { t.Fatalf("Failed to get all UE") } if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa3Name, 328.98288, []string{}) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa3Name, 328.983, []string{}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa3Name, 268.81665, []string{}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa3Name, 268.817, []string{}) { t.Fatalf("UE validation failed") } Loading @@ -474,13 +474,13 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || len(ueMap) != 3 { t.Fatalf("Failed to get all UE") } if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.24975, []string{poa1Name}) { if !validateUe(ueMap[ue1Name], ue1Id, ue1Name, ue1Loc, ue1Path, ue1PathMode, ue1Velocity, 1383.59, 0.004, 0.000, poa1Name, 83.25, []string{poa1Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ueMap[ue2Name], ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.99091, []string{poa1Name}) { if !validateUe(ueMap[ue3Name], ue3Id, ue3Name, ue3Loc, ue3Path, ue3PathMode, ue3Velocity, 810.678, 0.031, 0.000, poa1Name, 101.991, []string{poa1Name}) { t.Fatalf("UE validation failed") } Loading @@ -505,7 +505,7 @@ func TestPostgisConnectorNew(t *testing.T) { if err != nil || ue == nil { t.Fatalf("Failed to get UE") } if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.08527, []string{poa2Name}) { if !validateUe(ue, ue2Id, ue2Name, ue2Loc, ue2Path, ue2PathMode, ue2Velocity, 0.000, 0.000, 0.000, poa2Name, 10.085, []string{poa2Name}) { t.Fatalf("UE validation failed") } Loading