Loading go-apps/meep-gis-engine/go.mod +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ require ( github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-postgis v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0 github.com/gorilla/handlers v1.4.2 github.com/gorilla/mux v1.7.4 ) Loading @@ -20,4 +21,5 @@ replace ( github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq => ../../go-packages/meep-mq github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-postgis => ../../go-packages/meep-postgis github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis => ../../go-packages/meep-redis github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client => ../../go-packages/meep-sandbox-ctrl-client ) go-apps/meep-gis-engine/go.sum +12 −0 Original line number Diff line number Diff line cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/KromDaniel/jonson v0.0.0-20180630143114-d2f9c3c389db/go.mod h1:RU+6d0CNIRSp6yo1mXLIIrnFa/3LHhvcDVLVJyovptM= github.com/KromDaniel/rejonson v0.0.0-20180822072824-00b5bcf2b351 h1:1u1XrfCBnY+GijnyU6O1k4odp5TnqZQTsp5v7+n/E4Y= github.com/KromDaniel/rejonson v0.0.0-20180822072824-00b5bcf2b351/go.mod h1:HxwfbuElTuGf+/uKZfjJrCnv0BmmpkPJDI7gBwj1KkM= Loading @@ -5,12 +6,15 @@ github.com/RyanCarrier/dijkstra v0.0.0-20190726134004-b51cadb5ae52 h1:trnwuu/Q8T github.com/RyanCarrier/dijkstra v0.0.0-20190726134004-b51cadb5ae52/go.mod h1:DdR6ymcLl8+sN/XOVNjnYO1NDYfgHskGjreZUDuQCTY= github.com/RyanCarrier/dijkstra-1 v0.0.0-20170512020943-0e5801a26345/go.mod h1:OK4EvWJ441LQqGzed5NGB6vKBAE34n3z7iayPcEwr30= github.com/albertorestifo/dijkstra v0.0.0-20160910063646-aba76f725f72/go.mod h1:o+JdB7VetTHjLhU0N57x18B9voDBQe0paApdEAEoEfw= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= Loading @@ -30,12 +34,20 @@ github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= Loading go-apps/meep-gis-engine/server/gis-engine.go +225 −9 Original line number Diff line number Diff line Loading @@ -17,38 +17,62 @@ package server import ( "context" "encoding/json" "errors" "fmt" "net/http" "os" "sort" "strconv" "strings" "time" dataModel "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model" log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" mod "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model" mq "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq" postgis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-postgis" sbox "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client" "github.com/gorilla/mux" ) const moduleName = "meep-gis-engine" const redisAddr = "meep-redis-master.default.svc.cluster.local:6379" const sboxCtrlBasepath = "http://meep-sandbox-ctrl/sandbox-ctrl/v1" const postgisUser = "postgres" const postgisPwd = "pwd" const ( AutoTypeMovement = "MOVEMENT" AutoTypeMobility = "MOBILITY" AutoTypeNetChar = "NETWORK-CHARACTERISTICS-UPDATE" AutoTypePoaInRange = "POAS-IN-RANGE" ) type Asset struct { allocated bool assetType string } type PoaInfo struct { poa string distance float32 poaInRange []string } type GisEngine struct { sandboxName string mqLocal *mq.MsgQueue handlerId int sboxCtrlClient *sbox.APIClient activeModel *mod.Model pc *postgis.Connector assets map[string]Asset uePoaInfo map[string]PoaInfo automation map[string]bool ticker *time.Ticker updateTime time.Time } var ge *GisEngine Loading @@ -57,6 +81,12 @@ var ge *GisEngine func Init() (err error) { ge = new(GisEngine) ge.assets = make(map[string]Asset) ge.uePoaInfo = make(map[string]PoaInfo) ge.automation = make(map[string]bool) resetAutomation() startAutomation() // timer := time.NewTimer(time.Second) // Retrieve Sandbox name from environment variable ge.sandboxName = strings.TrimSpace(os.Getenv("MEEP_SANDBOX_NAME")) Loading @@ -75,6 +105,16 @@ func Init() (err error) { } log.Info("Message Queue created") // Create Sandbox Controller REST API client sboxCfg := sbox.NewConfiguration() sboxCfg.BasePath = sboxCtrlBasepath ge.sboxCtrlClient = sbox.NewAPIClient(sboxCfg) if ge.sboxCtrlClient == nil { err := errors.New("Failed to create Sandbox Ctrl REST API client") return err } log.Info("Sandbox Ctrl REST API client created") // Create new active scenario model modelCfg := mod.ModelCfg{ Name: "activeScenario", Loading Loading @@ -387,21 +427,197 @@ func fillGeoDataAsset(geoData *GeoDataAsset, position string, path string, radiu return } func resetAutomation() { ge.automation[AutoTypeMobility] = false ge.automation[AutoTypeMovement] = false ge.automation[AutoTypeNetChar] = false ge.automation[AutoTypePoaInRange] = false } func startAutomation() { ge.ticker = time.NewTicker(1000 * time.Millisecond) ge.updateTime = time.Now() go func() { for range ge.ticker.C { runAutomationLoop() } }() } func runAutomationLoop() { // Movement if ge.automation[AutoTypeMovement] { log.Debug("Auto Movement: updating UE positions") } // Mobility & POA In Range if ge.automation[AutoTypeMobility] || ge.automation[AutoTypePoaInRange] { // Get all UE POA information ueMap, err := ge.pc.GetAllUe() if err == nil { for _, ue := range ueMap { // Get last POA info poaInfo, found := ge.uePoaInfo[ue.Name] // Send mobility event if necessary if ge.automation[AutoTypeMobility] { if !found || poaInfo.poa != ue.Poa { var event sbox.Event var mobilityEvent sbox.EventMobility event.Type_ = AutoTypeMobility mobilityEvent.ElementName = ue.Name mobilityEvent.Dest = ue.Poa event.EventMobility = &mobilityEvent go func() { _, err := ge.sboxCtrlClient.EventsApi.SendEvent(context.TODO(), event.Type_, event) if err != nil { log.Error(err) } }() } } // Send POA in range event if necessary if ge.automation[AutoTypePoaInRange] { updateRequired := false if len(poaInfo.poaInRange) != len(ue.PoaInRange) { updateRequired = true } else { sort.Strings(poaInfo.poaInRange) sort.Strings(ue.PoaInRange) for i, poa := range poaInfo.poaInRange { if poa != ue.PoaInRange[i] { updateRequired = true } } } if updateRequired { var event sbox.Event var poasInRangeEvent sbox.EventPoasInRange event.Type_ = AutoTypePoaInRange poasInRangeEvent = sbox.EventPoasInRange{Ue: ue.Name, PoasInRange: ue.PoaInRange} event.EventPoasInRange = &poasInRangeEvent go func() { _, err := ge.sboxCtrlClient.EventsApi.SendEvent(context.TODO(), event.Type_, event) if err != nil { log.Error(err) } }() } } // Update POA info ge.uePoaInfo[ue.Name] = PoaInfo{poa: ue.Poa, distance: ue.PoaDistance, poaInRange: ue.PoaInRange} } } else { log.Error(err.Error()) } } // Net Char if ge.automation[AutoTypeNetChar] { log.Debug("Auto Net Char: updating network characteristics") } } // ---------------------------- REST API ------------------------------------ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { log.Debug("Get all automation states") var automationList AutomationStateList for automation, state := range ge.automation { var automationState AutomationState automationState.Type_ = automation automationState.Active = state automationList.States = append(automationList.States, automationState) } // Format response jsonResponse, err := json.Marshal(&automationList) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Send response w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusNotImplemented) w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(jsonResponse)) } func geGetAutomationStateByName(w http.ResponseWriter, r *http.Request) { // Get automation type from request path parameters vars := mux.Vars(r) automationType := vars["type"] log.Debug("Get automation state for type: ", automationType) // Get automation state var automationState AutomationState automationState.Type_ = automationType if state, found := ge.automation[automationType]; found { automationState.Active = state } else { err := errors.New("Automation type not found") log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Format response jsonResponse, err := json.Marshal(&automationState) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Send response w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusNotImplemented) w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(jsonResponse)) } func geSetAutomationStateByName(w http.ResponseWriter, r *http.Request) { // Get automation type from request path parameters vars := mux.Vars(r) automationType := vars["type"] // Retrieve requested state from query parameters query := r.URL.Query() automationState, _ := strconv.ParseBool(query.Get("run")) if automationState { log.Debug("Start automation for type: ", automationType) } else { log.Debug("Stop automation for type: ", automationType) } // Validate automation type if _, found := ge.automation[automationType]; !found { err := errors.New("Automation type not found") log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Filter unsupported automation types if automationType == AutoTypeNetChar || automationType == AutoTypePoaInRange { err := errors.New("Automation type not supported") log.Error(err.Error()) http.Error(w, err.Error(), http.StatusNotImplemented) return } // Update automation state ge.automation[automationType] = automationState w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusNotImplemented) w.WriteHeader(http.StatusOK) } func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { Loading Loading
go-apps/meep-gis-engine/go.mod +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ require ( github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-postgis v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0 github.com/gorilla/handlers v1.4.2 github.com/gorilla/mux v1.7.4 ) Loading @@ -20,4 +21,5 @@ replace ( github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq => ../../go-packages/meep-mq github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-postgis => ../../go-packages/meep-postgis github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis => ../../go-packages/meep-redis github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client => ../../go-packages/meep-sandbox-ctrl-client )
go-apps/meep-gis-engine/go.sum +12 −0 Original line number Diff line number Diff line cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/KromDaniel/jonson v0.0.0-20180630143114-d2f9c3c389db/go.mod h1:RU+6d0CNIRSp6yo1mXLIIrnFa/3LHhvcDVLVJyovptM= github.com/KromDaniel/rejonson v0.0.0-20180822072824-00b5bcf2b351 h1:1u1XrfCBnY+GijnyU6O1k4odp5TnqZQTsp5v7+n/E4Y= github.com/KromDaniel/rejonson v0.0.0-20180822072824-00b5bcf2b351/go.mod h1:HxwfbuElTuGf+/uKZfjJrCnv0BmmpkPJDI7gBwj1KkM= Loading @@ -5,12 +6,15 @@ github.com/RyanCarrier/dijkstra v0.0.0-20190726134004-b51cadb5ae52 h1:trnwuu/Q8T github.com/RyanCarrier/dijkstra v0.0.0-20190726134004-b51cadb5ae52/go.mod h1:DdR6ymcLl8+sN/XOVNjnYO1NDYfgHskGjreZUDuQCTY= github.com/RyanCarrier/dijkstra-1 v0.0.0-20170512020943-0e5801a26345/go.mod h1:OK4EvWJ441LQqGzed5NGB6vKBAE34n3z7iayPcEwr30= github.com/albertorestifo/dijkstra v0.0.0-20160910063646-aba76f725f72/go.mod h1:o+JdB7VetTHjLhU0N57x18B9voDBQe0paApdEAEoEfw= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= Loading @@ -30,12 +34,20 @@ github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= Loading
go-apps/meep-gis-engine/server/gis-engine.go +225 −9 Original line number Diff line number Diff line Loading @@ -17,38 +17,62 @@ package server import ( "context" "encoding/json" "errors" "fmt" "net/http" "os" "sort" "strconv" "strings" "time" dataModel "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model" log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" mod "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model" mq "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq" postgis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-postgis" sbox "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client" "github.com/gorilla/mux" ) const moduleName = "meep-gis-engine" const redisAddr = "meep-redis-master.default.svc.cluster.local:6379" const sboxCtrlBasepath = "http://meep-sandbox-ctrl/sandbox-ctrl/v1" const postgisUser = "postgres" const postgisPwd = "pwd" const ( AutoTypeMovement = "MOVEMENT" AutoTypeMobility = "MOBILITY" AutoTypeNetChar = "NETWORK-CHARACTERISTICS-UPDATE" AutoTypePoaInRange = "POAS-IN-RANGE" ) type Asset struct { allocated bool assetType string } type PoaInfo struct { poa string distance float32 poaInRange []string } type GisEngine struct { sandboxName string mqLocal *mq.MsgQueue handlerId int sboxCtrlClient *sbox.APIClient activeModel *mod.Model pc *postgis.Connector assets map[string]Asset uePoaInfo map[string]PoaInfo automation map[string]bool ticker *time.Ticker updateTime time.Time } var ge *GisEngine Loading @@ -57,6 +81,12 @@ var ge *GisEngine func Init() (err error) { ge = new(GisEngine) ge.assets = make(map[string]Asset) ge.uePoaInfo = make(map[string]PoaInfo) ge.automation = make(map[string]bool) resetAutomation() startAutomation() // timer := time.NewTimer(time.Second) // Retrieve Sandbox name from environment variable ge.sandboxName = strings.TrimSpace(os.Getenv("MEEP_SANDBOX_NAME")) Loading @@ -75,6 +105,16 @@ func Init() (err error) { } log.Info("Message Queue created") // Create Sandbox Controller REST API client sboxCfg := sbox.NewConfiguration() sboxCfg.BasePath = sboxCtrlBasepath ge.sboxCtrlClient = sbox.NewAPIClient(sboxCfg) if ge.sboxCtrlClient == nil { err := errors.New("Failed to create Sandbox Ctrl REST API client") return err } log.Info("Sandbox Ctrl REST API client created") // Create new active scenario model modelCfg := mod.ModelCfg{ Name: "activeScenario", Loading Loading @@ -387,21 +427,197 @@ func fillGeoDataAsset(geoData *GeoDataAsset, position string, path string, radiu return } func resetAutomation() { ge.automation[AutoTypeMobility] = false ge.automation[AutoTypeMovement] = false ge.automation[AutoTypeNetChar] = false ge.automation[AutoTypePoaInRange] = false } func startAutomation() { ge.ticker = time.NewTicker(1000 * time.Millisecond) ge.updateTime = time.Now() go func() { for range ge.ticker.C { runAutomationLoop() } }() } func runAutomationLoop() { // Movement if ge.automation[AutoTypeMovement] { log.Debug("Auto Movement: updating UE positions") } // Mobility & POA In Range if ge.automation[AutoTypeMobility] || ge.automation[AutoTypePoaInRange] { // Get all UE POA information ueMap, err := ge.pc.GetAllUe() if err == nil { for _, ue := range ueMap { // Get last POA info poaInfo, found := ge.uePoaInfo[ue.Name] // Send mobility event if necessary if ge.automation[AutoTypeMobility] { if !found || poaInfo.poa != ue.Poa { var event sbox.Event var mobilityEvent sbox.EventMobility event.Type_ = AutoTypeMobility mobilityEvent.ElementName = ue.Name mobilityEvent.Dest = ue.Poa event.EventMobility = &mobilityEvent go func() { _, err := ge.sboxCtrlClient.EventsApi.SendEvent(context.TODO(), event.Type_, event) if err != nil { log.Error(err) } }() } } // Send POA in range event if necessary if ge.automation[AutoTypePoaInRange] { updateRequired := false if len(poaInfo.poaInRange) != len(ue.PoaInRange) { updateRequired = true } else { sort.Strings(poaInfo.poaInRange) sort.Strings(ue.PoaInRange) for i, poa := range poaInfo.poaInRange { if poa != ue.PoaInRange[i] { updateRequired = true } } } if updateRequired { var event sbox.Event var poasInRangeEvent sbox.EventPoasInRange event.Type_ = AutoTypePoaInRange poasInRangeEvent = sbox.EventPoasInRange{Ue: ue.Name, PoasInRange: ue.PoaInRange} event.EventPoasInRange = &poasInRangeEvent go func() { _, err := ge.sboxCtrlClient.EventsApi.SendEvent(context.TODO(), event.Type_, event) if err != nil { log.Error(err) } }() } } // Update POA info ge.uePoaInfo[ue.Name] = PoaInfo{poa: ue.Poa, distance: ue.PoaDistance, poaInRange: ue.PoaInRange} } } else { log.Error(err.Error()) } } // Net Char if ge.automation[AutoTypeNetChar] { log.Debug("Auto Net Char: updating network characteristics") } } // ---------------------------- REST API ------------------------------------ func geGetAutomationState(w http.ResponseWriter, r *http.Request) { log.Debug("Get all automation states") var automationList AutomationStateList for automation, state := range ge.automation { var automationState AutomationState automationState.Type_ = automation automationState.Active = state automationList.States = append(automationList.States, automationState) } // Format response jsonResponse, err := json.Marshal(&automationList) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Send response w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusNotImplemented) w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(jsonResponse)) } func geGetAutomationStateByName(w http.ResponseWriter, r *http.Request) { // Get automation type from request path parameters vars := mux.Vars(r) automationType := vars["type"] log.Debug("Get automation state for type: ", automationType) // Get automation state var automationState AutomationState automationState.Type_ = automationType if state, found := ge.automation[automationType]; found { automationState.Active = state } else { err := errors.New("Automation type not found") log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Format response jsonResponse, err := json.Marshal(&automationState) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Send response w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusNotImplemented) w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(jsonResponse)) } func geSetAutomationStateByName(w http.ResponseWriter, r *http.Request) { // Get automation type from request path parameters vars := mux.Vars(r) automationType := vars["type"] // Retrieve requested state from query parameters query := r.URL.Query() automationState, _ := strconv.ParseBool(query.Get("run")) if automationState { log.Debug("Start automation for type: ", automationType) } else { log.Debug("Stop automation for type: ", automationType) } // Validate automation type if _, found := ge.automation[automationType]; !found { err := errors.New("Automation type not found") log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Filter unsupported automation types if automationType == AutoTypeNetChar || automationType == AutoTypePoaInRange { err := errors.New("Automation type not supported") log.Error(err.Error()) http.Error(w, err.Error(), http.StatusNotImplemented) return } // Update automation state ge.automation[automationType] = automationState w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusNotImplemented) w.WriteHeader(http.StatusOK) } func geDeleteGeoDataByName(w http.ResponseWriter, r *http.Request) { Loading