Skip to content
systemTest.go 9.84 KiB
Newer Older
Simon Pastor's avatar
Simon Pastor committed
package main

import (
	"errors"
	"io/ioutil"
Simon Pastor's avatar
Simon Pastor committed
	"net/http"
Simon Pastor's avatar
Simon Pastor committed
	"os"
	"os/signal"
	"strconv"
	"strings"
Simon Pastor's avatar
Simon Pastor committed
	"syscall"
	"time"

	gisClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-engine-client"
	log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
	platformCtrlClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-platform-ctrl-client"
	rnisClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-rnis-client"
	sandboxCtrlClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client"
	waisClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-wais-client"
Simon Pastor's avatar
Simon Pastor committed
)

var httpReqBody []string

var platformCtrlAppClient *platformCtrlClient.APIClient
var sandboxCtrlAppClient *sandboxCtrlClient.APIClient
var rnisAppClient *rnisClient.APIClient
var waisAppClient *waisClient.APIClient
var gisAppClient *gisClient.APIClient

var sandboxName = "sandbox-system-test"
var hostUrlStr = ""
var httpListenerPort = "3333"
var run = false

func resetHttpReqBody() {
	httpReqBody = []string{}
}

func printHttpReqBody() {
	for index, body := range httpReqBody {
		log.Info("Notification received: (" + strconv.Itoa(index) + "):" + body)
	}
}

func printHttpReqBodyByIndex(index int) {
	log.Info("Notification received: (" + strconv.Itoa(index) + "):" + httpReqBody[index])
}

Simon Pastor's avatar
Simon Pastor committed
func initialiseVars() {

	hostUrl, _ := url.Parse(strings.TrimSpace(os.Getenv("MEEP_HOST_TEST_URL")))
	hostUrlStr = hostUrl.String()
Simon Pastor's avatar
Simon Pastor committed
}

func createClients() error {

	// Create & store client for App REST API
	platformCtrlAppClientCfg := platformCtrlClient.NewConfiguration()
Simon Pastor's avatar
Simon Pastor committed
	if hostUrlStr == "" {
		platformCtrlAppClientCfg.BasePath = "http://localhost/platform-ctrl/v1"
	} else {
		platformCtrlAppClientCfg.BasePath = hostUrlStr + "/platform-ctrl/v1"
	}
	platformCtrlAppClient = platformCtrlClient.NewAPIClient(platformCtrlAppClientCfg)
	if platformCtrlAppClient == nil {
		log.Error("Failed to create Platform App REST API client: ", platformCtrlAppClientCfg.BasePath)
		err := errors.New("Failed to create Platform App REST API client")
		return err
Simon Pastor's avatar
Simon Pastor committed
	}
	return nil
}

func createSandboxClients(sandboxName string) error {

	// Create & store client for App REST API
	sandboxCtrlAppClientCfg := sandboxCtrlClient.NewConfiguration()
	if hostUrlStr == "" {
		sandboxCtrlAppClientCfg.BasePath = "http://localhost/" + sandboxName + "/sandbox-ctrl/v1"
	} else {
		sandboxCtrlAppClientCfg.BasePath = hostUrlStr + "/" + sandboxName + "/sandbox-ctrl/v1"
	}
	sandboxCtrlAppClient = sandboxCtrlClient.NewAPIClient(sandboxCtrlAppClientCfg)
	if sandboxCtrlAppClient == nil {
		log.Error("Failed to create Sandbox App REST API client: ", sandboxCtrlAppClientCfg.BasePath)
		err := errors.New("Failed to create Sandbox App REST API client")
		return err
	}

	rnisAppClientCfg := rnisClient.NewConfiguration()
	if hostUrlStr == "" {
		rnisAppClientCfg.BasePath = "http://localhost/" + sandboxName + "/rni/v2"
	} else {
		rnisAppClientCfg.BasePath = hostUrlStr + "/" + sandboxName + "/rni/v2"
	}
	rnisAppClient = rnisClient.NewAPIClient(rnisAppClientCfg)
	if rnisAppClient == nil {
		log.Error("Failed to create RNI App REST API client: ", rnisAppClientCfg.BasePath)
		err := errors.New("Failed to create RNI App REST API client")
		return err
	}

	waisAppClientCfg := waisClient.NewConfiguration()
	if hostUrlStr == "" {
		waisAppClientCfg.BasePath = "http://localhost/" + sandboxName + "/wai/v2"
	} else {
		waisAppClientCfg.BasePath = hostUrlStr + "/" + sandboxName + "/wai/v2"
	}
	waisAppClient = waisClient.NewAPIClient(waisAppClientCfg)
	if waisAppClient == nil {
		log.Error("Failed to create WAI App REST API client: ", waisAppClientCfg.BasePath)
		err := errors.New("Failed to create WAI App REST API client")
		return err
	}

	gisAppClientCfg := gisClient.NewConfiguration()
	if hostUrlStr == "" {
		gisAppClientCfg.BasePath = "http://localhost/" + sandboxName + "/gis/v1"
	} else {
		gisAppClientCfg.BasePath = hostUrlStr + "/" + sandboxName + "/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
	}

	return nil
Simon Pastor's avatar
Simon Pastor committed
}

func createSandbox(name string) error {

	config := platformCtrlClient.SandboxConfig{""}
	_, err := platformCtrlAppClient.SandboxControlApi.CreateSandboxWithName(context.TODO(), name, config)
	if err != nil {
		log.Error("Failed to create sandbox: ", err)
		return err
	}
Simon Pastor's avatar
Simon Pastor committed
}

func deleteSandbox(name string) error {

	_, err := platformCtrlAppClient.SandboxControlApi.DeleteSandbox(context.TODO(), name)
	if err != nil {
Simon Pastor's avatar
Simon Pastor committed
		log.Error("Failed to delete sandbox: ", err)
		return err
	}
func createScenario(name string, filepath string) error {

Simon Pastor's avatar
Simon Pastor committed
	//get the content of the file, assuming yaml content
	yamlContent, err := ioutil.ReadFile(filepath)
Simon Pastor's avatar
Simon Pastor committed
		log.Error("Couldn't read file: ", err)
Simon Pastor's avatar
Simon Pastor committed
	//converting to json since unmarshal with yaml directly not working well, while json does
	jsonContent, err := yaml.YAMLToJSON(yamlContent)
        if err != nil {
                log.Error("Failed converting yaml to json: ", err)
                return err
        }
	var scenario platformCtrlClient.Scenario
	err = json.Unmarshal([]byte(jsonContent), &scenario)
	if err != nil {
		log.Error("Failed to unmarshal: ", err)
		return err
	}
	_, err = platformCtrlAppClient.ScenarioConfigurationApi.CreateScenario(context.TODO(), name, scenario)
	if err != nil {
		log.Error("Failed to create scenario: ", err)
		return err
	}
Simon Pastor's avatar
Simon Pastor committed
}

func deleteScenario(name string) error {

	_, err := platformCtrlAppClient.ScenarioConfigurationApi.DeleteScenario(context.TODO(), name)
	if err != nil {
		log.Error("Failed to delete scenario: ", err)
		return err
	}
Simon Pastor's avatar
Simon Pastor committed
}

func activateScenario(name string) error {

	_, err := sandboxCtrlAppClient.ActiveScenarioApi.ActivateScenario(context.TODO(), name, nil)
	if err != nil {
		log.Error("Failed to activate scenario: ", err)
		return err
	}
Simon Pastor's avatar
Simon Pastor committed

	//reinitialisation of http msg queue
	resetHttpReqBody()

Simon Pastor's avatar
Simon Pastor committed
}

func terminateScenario() error {

	_, err := sandboxCtrlAppClient.ActiveScenarioApi.TerminateScenario(context.TODO())
	if err != nil {
		log.Error("Failed to terminate scenario: ", err)
		return err
	}
func createBasics() error {
Simon Pastor's avatar
Simon Pastor committed
	initialiseVars()
	log.Info("creating Clients")
	err := createClients()
	if err != nil {
		return err
	}
	log.Info("creating Sandbox")
	err = createSandbox(sandboxName)
	if err != nil {
		return err
	} else {
Simon Pastor's avatar
Simon Pastor committed
		time.Sleep(20000 * time.Millisecond)
	}
	log.Info("creating Sandbox Clients")
	err = createSandboxClients(sandboxName)
	if err != nil {
		clearBasics()
		return err
	}
	return nil
Simon Pastor's avatar
Simon Pastor committed
}

func clearBasics() {
	log.Info("deleting Sandbox")
	deleteSandbox(sandboxName)
func startSystemTest() error {
Simon Pastor's avatar
Simon Pastor committed
	if !run {
		go main()
		err := createBasics()
		if err != nil {
			run = false
			return err
		}
Simon Pastor's avatar
Simon Pastor committed
	}
Simon Pastor's avatar
Simon Pastor committed
}

func stopSystemTest() {
	if run {
		clearBasics()
		run = false
	}
Simon Pastor's avatar
Simon Pastor committed
}

func main() {

	//create default route handler
	http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
		log.Info("http message received!")
		defer req.Body.Close()
		body, _ := ioutil.ReadAll(req.Body)
		httpReqBody = append(httpReqBody, string(body))
	})

	log.Info(os.Args)

	log.Info("Starting System Test")

	run = true
	//creating a server for graceful shutdown
	listenerPort := ":" + httpListenerPort
	server := &http.Server{Addr: listenerPort}

Simon Pastor's avatar
Simon Pastor committed
	go func() {
		sigchan := make(chan os.Signal, 10)
		signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM)
		<-sigchan
		log.Info("Program killed !")
		// do last actions and wait for all write operations to end
		run = false
		//graceful server shutdown
		err := server.Shutdown(context.Background())
		if err != nil {
			log.Info("Error shuting down the server: ", err)
		}
Simon Pastor's avatar
Simon Pastor committed
	}()

	go func() {
		//create default route handler
		if err := server.ListenAndServe(); err != http.ErrServerClosed {
			// Error starting or closing listener
			log.Fatal("HTTP server ListenAndServe: ", err)
		}
		//log.Fatal(http.ListenAndServe(":" + httpListenerPort, nil))
Simon Pastor's avatar
Simon Pastor committed
		run = false
	}()

	count := 0
	for {
		if !run {
			log.Info("Ran for ", count, " seconds")
			clearBasics()
			break
		}
		time.Sleep(time.Second)
		count++
	}

}

func geAutomationUpdate(mobility bool, movement bool, poasInRange bool, netCharUpd bool) error {

	_, err := gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "MOBILITY", mobility)
	if err != nil {
		log.Error("Failed to communicate with gis engine: ", err)
		return err
	}
	_, err = gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "MOVEMENT", movement)
	if err != nil {
		log.Error("Failed to communicate with gis engine: ", err)
		return err
	}
	_, err = gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "POAS-IN-RANGE", poasInRange)
	if err != nil {
		log.Error("Failed to communicate with gis engine: ", err)
		return err
	}

	_, err = gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "NETWORK-CHARACTERISTICS-UPDATE", netCharUpd)
	if err != nil {
		log.Error("Failed to communicate with gis engine: ", err)
		return err
	}

	return nil
Simon Pastor's avatar
Simon Pastor committed
}

func geMoveAssetCoordinates(assetName string, long float32, lat float32) error {

	var geoData gisClient.GeoDataAsset
	point := gisClient.Point{"Point", []float32{long, lat}}
	geoData.Location = &point
	geoData.AssetName = assetName
	geoData.AssetType = "UE"
	geoData.SubType = "UE"
	err := geMoveAsset(assetName, geoData)
	if err != nil {
		log.Error("Failed to move asset: ", err)
		return err
	}
Simon Pastor's avatar
Simon Pastor committed
}

func geMoveAsset(assetName string, geoData gisClient.GeoDataAsset) error {

	_, err := gisAppClient.GeospatialDataApi.UpdateGeoDataByName(context.TODO(), assetName, geoData)
	if err != nil {
		log.Error("Failed to communicate with gis engine: ", err)
		return err
	}
Simon Pastor's avatar
Simon Pastor committed
}