X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Fusecases%2Foruclosedlooprecovery%2Fgoversion%2Fmain.go;h=c3d731f4c4015a1dd7378b7c1c459f07a31d54a3;hb=5b26de71a0aae08360a38477150551651a7ef734;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..c3d731f4 100644 --- a/test/usecases/oruclosedlooprecovery/goversion/main.go +++ b/test/usecases/oruclosedlooprecovery/goversion/main.go @@ -21,9 +21,13 @@ package main import ( + "crypto/tls" "encoding/json" "fmt" "net/http" + "os" + "os/signal" + "syscall" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" @@ -33,77 +37,166 @@ import ( "oransc.org/usecase/oruclosedloop/internal/restclient" ) -var consumerConfig linkfailure.Configuration -var lookupService repository.LookupService -var host string -var port string - 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 +var started bool + func init() { - configuration := config.New() + doInit() +} + +func doInit() { + configuration = config.New() log.SetLevel(configuration.LogLevel) + log.Debug("Using configuration: ", configuration) - if configuration.ConsumerHost == "" || configuration.ConsumerPort == 0 { - log.Fatal("Consumer host and port must be provided!") + consumerPort = fmt.Sprint(configuration.ConsumerPort) + jobRegistrationInfo.JobResultURI = configuration.ConsumerHost + ":" + consumerPort + + linkfailureConfig = linkfailure.Configuration{ + SDNRAddress: configuration.SDNRAddress, + 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) } - host = configuration.ConsumerHost - port = fmt.Sprint(configuration.ConsumerPort) - csvFileHelper := repository.NewCsvFileHelper() - lookupService = repository.NewLookupServiceImpl(&csvFileHelper, configuration.ORUToODUMapFile) - if initErr := lookupService.Init(); initErr != nil { + 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, + + var cert tls.Certificate + if c, err := restclient.CreateClientCertificate(configuration.ConsumerCertPath, configuration.ConsumerKeyPath); err == nil { + cert = c + } else { + log.Fatalf("Stopping producer due to error: %v", err) } + client = restclient.CreateRetryClient(cert) + + go func() { + startServer() + 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 main() { - defer deleteJob() - messageHandler := linkfailure.NewLinkFailureHandler(lookupService, consumerConfig) +func validateConfiguration(configuration *config.Config) error { + if configuration.ConsumerHost == "" || configuration.ConsumerPort == 0 { + return fmt.Errorf("consumer host and port must be provided") + } + + if configuration.ConsumerCertPath == "" || configuration.ConsumerKeyPath == "" { + return fmt.Errorf("missing CONSUMER_CERT and/or CONSUMER_KEY") + } + + return nil +} + +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("/status", statusHandler).Methods(http.MethodGet).Name("status") + 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() { + var err error + if restclient.IsUrlSecure(configuration.ConsumerHost) { + err = http.ListenAndServeTLS(fmt.Sprintf(":%v", configuration.ConsumerPort), configuration.ConsumerCertPath, configuration.ConsumerKeyPath, getRouter()) + } else { + err = http.ListenAndServe(fmt.Sprintf(":%v", configuration.ConsumerPort), getRouter()) } + if err != nil { + log.Errorf("Server stopped unintentionally due to: %v. Deleteing job.", err) + if deleteErr := deleteJob(); deleteErr != nil { + log.Errorf("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.") + started = true } 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.") + started = false +} + +func statusHandler(w http.ResponseWriter, r *http.Request) { + runStatus := "started" + if !started { + runStatus = "stopped" + } + fmt.Fprintf(w, `{"status": "%v"}`, runStatus) +} + +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.Errorf("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) }