X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Fusecases%2Foruclosedlooprecovery%2Fgoversion%2Fmain.go;h=bef9e24ca1eb593f383020234abf23637059eb09;hb=2d522d44bf5f69b091380b57e2879d3b7139bc8f;hp=5574f8ccd5e9a5af12ecb697b913bbba5286a411;hpb=2f0d0d08efe5efe671178e63fdab4dacee543f9a;p=nonrtric.git diff --git a/test/usecases/oruclosedlooprecovery/goversion/main.go b/test/usecases/oruclosedlooprecovery/goversion/main.go index 5574f8cc..bef9e24c 100644 --- a/test/usecases/oruclosedlooprecovery/goversion/main.go +++ b/test/usecases/oruclosedlooprecovery/goversion/main.go @@ -24,6 +24,10 @@ import ( "encoding/json" "fmt" "net/http" + "os" + "os/signal" + "syscall" + "time" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" @@ -33,63 +37,123 @@ import ( "oransc.org/usecase/oruclosedloop/internal/restclient" ) -var consumerConfig linkfailure.Configuration -var lookupService repository.LookupService -var host string -var port string +type Server interface { + ListenAndServe() error +} +const timeoutHTTPClient = time.Second * 5 const jobId = "14e7bb84-a44d-44c1-90b7-6995a92ad43c" +var jobRegistrationInfo = struct { + InfoTypeId string `json:"info_type_id"` + JobResultUri string `json:"job_result_uri"` + JobOwner string `json:"job_owner"` + JobDefinition interface{} `json:"job_definition"` +}{ + InfoTypeId: "STD_Fault_Messages", + JobResultUri: "", + JobOwner: "O-RU Closed Loop Usecase", + JobDefinition: "{}", +} + +var client restclient.HTTPClient +var configuration *config.Config +var linkfailureConfig linkfailure.Configuration +var lookupService repository.LookupService +var consumerPort string + func init() { - configuration := config.New() + doInit() +} + +func doInit() { + configuration = config.New() log.SetLevel(configuration.LogLevel) - if configuration.ConsumerHost == "" || configuration.ConsumerPort == 0 { - log.Fatal("Consumer host and port must be provided!") + client = &http.Client{ + Timeout: timeoutHTTPClient, } - host = configuration.ConsumerHost - port = fmt.Sprint(configuration.ConsumerPort) - csvFileHelper := repository.NewCsvFileHelper() - lookupService = repository.NewLookupServiceImpl(&csvFileHelper, configuration.ORUToODUMapFile) - if initErr := lookupService.Init(); initErr != nil { + consumerPort = fmt.Sprint(configuration.ConsumerPort) + jobRegistrationInfo.JobResultUri = configuration.ConsumerHost + ":" + consumerPort + + linkfailureConfig = linkfailure.Configuration{ + SDNRAddress: configuration.SDNRHost + ":" + fmt.Sprint(configuration.SDNRPort), + SDNRUser: configuration.SDNRUser, + SDNRPassword: configuration.SDNPassword, + } +} + +func main() { + if err := validateConfiguration(configuration); err != nil { + log.Fatalf("Unable to start consumer due to configuration error: %v", err) + } + + csvFileHelper := repository.NewCsvFileHelperImpl() + if initErr := initializeLookupService(csvFileHelper, configuration.ORUToODUMapFile); initErr != nil { log.Fatalf("Unable to create LookupService due to inability to get O-RU-ID to O-DU-ID map. Cause: %v", initErr) } - consumerConfig = linkfailure.Configuration{ - InfoCoordAddress: configuration.InfoCoordinatorAddress, - SDNRAddress: configuration.SDNRHost + ":" + fmt.Sprint(configuration.SDNRPort), - SDNRUser: configuration.SDNRUser, - SDNRPassword: configuration.SDNPassword, + + go func() { + startServer(&http.Server{ + Addr: ":" + consumerPort, + Handler: getRouter(), + }) + deleteJob() + os.Exit(1) // If the startServer function exits, it is because there has been a failure in the server, so we exit. + }() + + go func() { + deleteOnShutdown(make(chan os.Signal, 1)) + os.Exit(0) + }() + + keepConsumerAlive() +} + +func validateConfiguration(configuration *config.Config) error { + if configuration.ConsumerHost == "" || configuration.ConsumerPort == 0 { + return fmt.Errorf("consumer host and port must be provided") } + return nil } -func main() { - defer deleteJob() - messageHandler := linkfailure.NewLinkFailureHandler(lookupService, consumerConfig) +func initializeLookupService(csvFileHelper repository.CsvFileHelper, csvFile string) error { + lookupService = repository.NewLookupServiceImpl(csvFileHelper, csvFile) + return lookupService.Init() +} + +func getRouter() *mux.Router { + messageHandler := linkfailure.NewLinkFailureHandler(lookupService, linkfailureConfig, client) + r := mux.NewRouter() - r.HandleFunc("/", messageHandler.MessagesHandler).Methods(http.MethodPost) - r.HandleFunc("/admin/start", startHandler).Methods(http.MethodPost) - r.HandleFunc("/admin/stop", stopHandler).Methods(http.MethodPost) - log.Error(http.ListenAndServe(":"+port, r)) + r.HandleFunc("/", messageHandler.MessagesHandler).Methods(http.MethodPost).Name("messageHandler") + r.HandleFunc("/admin/start", startHandler).Methods(http.MethodPost).Name("start") + r.HandleFunc("/admin/stop", stopHandler).Methods(http.MethodPost).Name("stop") + + return r } -func startHandler(w http.ResponseWriter, r *http.Request) { - jobRegistrationInfo := struct { - InfoTypeId string `json:"info_type_id"` - JobResultUri string `json:"job_result_uri"` - JobOwner string `json:"job_owner"` - JobDefinition interface{} `json:"job_definition"` - }{ - InfoTypeId: "STD_Fault_Messages", - JobResultUri: host + ":" + port, - JobOwner: "O-RU Closed Loop Usecase", - JobDefinition: "{}", +func startServer(server Server) { + if err := server.ListenAndServe(); err != nil { + log.Errorf("Server stopped unintentionally due to: %v. Deleteing job.", err) + if deleteErr := deleteJob(); deleteErr != nil { + log.Error(fmt.Sprintf("Unable to delete consumer job due to: %v. Please remove job %v manually.", deleteErr, jobId)) + } } +} + +func keepConsumerAlive() { + forever := make(chan int) + <-forever +} + +func startHandler(w http.ResponseWriter, r *http.Request) { body, _ := json.Marshal(jobRegistrationInfo) - putErr := restclient.PutWithoutAuth(consumerConfig.InfoCoordAddress+"/data-consumer/v1/info-jobs/"+jobId, body) + putErr := restclient.PutWithoutAuth(configuration.InfoCoordinatorAddress+"/data-consumer/v1/info-jobs/"+jobId, body, client) if putErr != nil { - http.Error(w, fmt.Sprintf("Unable to register consumer job: %v", putErr), http.StatusBadRequest) + http.Error(w, fmt.Sprintf("Unable to register consumer job due to: %v.", putErr), http.StatusBadRequest) return } log.Debug("Registered job.") @@ -98,12 +162,22 @@ func startHandler(w http.ResponseWriter, r *http.Request) { func stopHandler(w http.ResponseWriter, r *http.Request) { deleteErr := deleteJob() if deleteErr != nil { - http.Error(w, fmt.Sprintf("Unable to delete consumer job: %v", deleteErr), http.StatusBadRequest) + http.Error(w, fmt.Sprintf("Unable to delete consumer job due to: %v. Please remove job %v manually.", deleteErr, jobId), http.StatusBadRequest) return } log.Debug("Deleted job.") } +func deleteOnShutdown(s chan os.Signal) { + signal.Notify(s, os.Interrupt) + signal.Notify(s, syscall.SIGTERM) + <-s + log.Info("Shutting down gracefully.") + if err := deleteJob(); err != nil { + log.Error(fmt.Sprintf("Unable to delete job on shutdown due to: %v. Please remove job %v manually.", err, jobId)) + } +} + func deleteJob() error { - return restclient.Delete(consumerConfig.InfoCoordAddress + "/data-consumer/v1/info-jobs/" + jobId) + return restclient.Delete(configuration.InfoCoordinatorAddress+"/data-consumer/v1/info-jobs/"+jobId, client) }