Commit 4a234e9e authored by M. Rehan Abbasi's avatar M. Rehan Abbasi
Browse files

implement basic VIS POST /provide_predicted_qos logic

parent 712e2673
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@ go 1.12
require (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model v0.0.0 // indirect
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-cache v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-engine-client v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-metrics v0.0.0
@@ -28,6 +28,7 @@ replace (
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr => ../../go-packages/meep-data-key-mgr
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model => ../../go-packages/meep-data-model
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-cache => ../../go-packages/meep-gis-cache
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-engine-client => ../../go-packages/meep-gis-engine-client
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger => ../../go-packages/meep-http-logger
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger => ../../go-packages/meep-logger
	github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-metrics => ../../go-packages/meep-metrics
+32 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2019  InterDigital Communications, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package server

import (
	"encoding/json"

	log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
)

func convertPredictedQostoJson(predictedQos *PredictedQos) string {
	jsonInfo, err := json.Marshal(*predictedQos)
	if err != nil {
		log.Error(err.Error())
		return ""
	}
	return string(jsonInfo)
}
+94 −24
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
@@ -31,6 +32,7 @@ import (
	sbi "github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-vis/sbi"
	asc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client"
	dkm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr"
	gisClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-engine-client"
	httpLog "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger"
	log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
	redis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis"
@@ -111,6 +113,9 @@ var locality []string
var basePath string
var baseKey string

var gisAppClient *gisClient.APIClient
var gisAppClientUrl string = "http://meep-gis-engine"

// var mutex sync.Mutex

// var expiryTicker *time.Ticker
@@ -403,6 +408,16 @@ func Init() (err error) {
	_ = rc.DBFlush(baseKey)
	log.Info("Connected to Redis DB, V2XI service table")

	gisAppClientCfg := gisClient.NewConfiguration()
	gisAppClientCfg.BasePath = gisAppClientUrl + "/gis/v1"

	gisAppClient = gisClient.NewAPIClient(gisAppClientCfg)
	if gisAppClient == nil {
		log.Error("Failed to create GIS App REST API client: ", gisAppClientCfg.BasePath)
		err := errors.New("Failed to create GIS App REST API client")
		return err
	}

	// Initialize SBI
	sbiCfg := sbi.SbiCfg{
		ModuleName:  moduleName,
@@ -596,35 +611,90 @@ func updateStoreName(storeName string) {
}

func predictedQosPost(w http.ResponseWriter, r *http.Request) {
	log.Info(">>> predictedQosPost")
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

	// This hard-coded response is just for testing purpose
	// VIS QoS logic shall be imlemented here
	expected_pointA := LocationInfoGeoArea{7.413917, 43.733505}
	expected_locationInfoA := LocationInfo{nil, &expected_pointA}
	expected_pointB := LocationInfoGeoArea{7.413916, 43.733515}
	expected_locationInfoB := LocationInfo{nil, &expected_pointB}
	// Fill PredictedQosRoutesRouteInfo with LocationInfo list
	expected_routeInfo := make([]PredictedQosRoutesRouteInfo, 2)
	expected_routeInfo[0] = PredictedQosRoutesRouteInfo{&expected_locationInfoA, 0, 0, nil}
	expected_routeInfo[1] = PredictedQosRoutesRouteInfo{&expected_locationInfoB, 0, 0, nil}
	// PredictedQosRoutes with PredictedQosRoutesRouteInfo list
	expected_predictedQosRoutes := PredictedQosRoutes{expected_routeInfo}
	// Fill PredictedQos with PredictedQosRoutes list
	expected_routes := make([]PredictedQosRoutes, 1)
	expected_routes[0] = expected_predictedQosRoutes
	response := PredictedQos{"100", expected_routes, nil}
	fmt.Println("response: ", response)
	// End of hard-coded response

	jsonResponse, err := json.Marshal(response)
	var requestData PredictedQos
	bodyBytes, _ := ioutil.ReadAll(r.Body)
	err := json.Unmarshal(bodyBytes, &requestData)
	if err != nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)

	fmt.Fprintf(w, string(jsonResponse))
	// Validating mandatory parameters in request
	if requestData.LocationGranularity == "" {
		log.Error("Mandatory locationGranularity parameter not present")
		http.Error(w, "Mandatory locationGranularity parameter not present", http.StatusBadRequest)
		return
	}

	if requestData.Routes == nil {
		log.Error("Mandatory routes parameter not present")
		http.Error(w, "Mandatory routes parameter not present", http.StatusBadRequest)
		return
	}

	if len(requestData.Routes) < 2 {
		log.Error("At least two routes are required")
		http.Error(w, "At least two routes are required", http.StatusBadRequest)
	}

	responseData := requestData // Both reqesut and response have same data model

	for i, route := range requestData.Routes {
		if route.RouteInfo == nil {
			log.Error("Mandatory routeInfo parameter not present in routes")
			http.Error(w, "Mandatory routeInfo parameter not present in route", http.StatusBadRequest)
			return
		}

		var geocoordinates []gisClient.GeoCoordinate
		for _, routeInfo := range route.RouteInfo {
			if routeInfo.Location == nil {
				log.Error("Mandatory location parameter not present in routeInfo")
				http.Error(w, "Mandatory location parameter not present in routeInfo", http.StatusBadRequest)
				return
			}

			if routeInfo.Location.Ecgi != nil && routeInfo.Location.GeoArea == nil {
				log.Error("Ecgi is not supported in geoArea for MEC Sandbox")
				http.Error(w, "Ecgi is not supported in geoArea for MEC Sandbox", http.StatusBadRequest)
				return
			}

			isValidGeoArea := routeInfo.Location.GeoArea != nil && (routeInfo.Location.GeoArea.Latitude == 0 || routeInfo.Location.GeoArea.Longitude == 0)
			if isValidGeoArea {
				log.Error("Mandatory latitude/longitude parameter(s) not present in geoArea")
				http.Error(w, "Mandatory latitude/longitude parameter(s) not present in geoArea", http.StatusBadRequest)
				return
			}

			geocoordinates = append(geocoordinates, gisClient.GeoCoordinate{
				Latitude:  routeInfo.Location.GeoArea.Latitude,
				Longitude: routeInfo.Location.GeoArea.Longitude,
			})
		}

		var geocoordinatesList gisClient.GeoCoordinateList
		geocoordinatesList.GeoCoordinates = geocoordinates
		powerResp, _, err := gisAppClient.GeospatialDataApi.GetGeoDataPowerValues(context.TODO(), geocoordinatesList)
		if err != nil {
			log.Error("Failed to communicate with gis engine: ", err)
			return
		}
		routeInfoList := responseData.Routes[i].RouteInfo
		for j, routeInfo := range routeInfoList {
			currGeoCoordinate := powerResp.CoordinatesPower[j]
			latCheck := routeInfo.Location.GeoArea.Latitude == currGeoCoordinate.Latitude
			longCheck := routeInfo.Location.GeoArea.Longitude == currGeoCoordinate.Longitude
			if latCheck && longCheck {
				routeInfoList[j].Rsrq = currGeoCoordinate.Rsrq
				routeInfoList[j].Rsrp = currGeoCoordinate.Rsrp
			}
		}
	}

	jsonResponse := convertPredictedQostoJson(&responseData)
	w.WriteHeader(http.StatusCreated)
	fmt.Fprint(w, jsonResponse)
}