Commit b3037bd6 authored by Kevin Di Lallo's avatar Kevin Di Lallo
Browse files

gis-engine support for active scenario model updates

parent b62113ec
Loading
Loading
Loading
Loading
+115 −60
Original line number Diff line number Diff line
@@ -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
@@ -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"))
@@ -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
			}

@@ -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
			}

@@ -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
			}

@@ -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) {
@@ -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) {
@@ -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())
@@ -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())
@@ -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())
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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()
	)`)
+18 −18
Original line number Diff line number Diff line
@@ -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")
	}

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

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

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

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

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

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

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

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

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

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