X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Fusecases%2Foruclosedlooprecovery%2Fgoversion%2Fmain.go;h=b7d689549db8a1b7f40f66b9ef24344a61ad4cd0;hb=46a0fd717e5f49ebae6cb2c4fbcf54f0e329dc86;hp=86da4d48b3aa6c22b5b8ffb8a3b0119f750c5000;hpb=f1cee0f81c6bc482f73182c8f4c903e8376381e8;p=nonrtric.git diff --git a/test/usecases/oruclosedlooprecovery/goversion/main.go b/test/usecases/oruclosedlooprecovery/goversion/main.go index 86da4d48..b7d68954 100644 --- a/test/usecases/oruclosedlooprecovery/goversion/main.go +++ b/test/usecases/oruclosedlooprecovery/goversion/main.go @@ -21,10 +21,13 @@ package main import ( + "crypto/tls" "encoding/json" "fmt" "net/http" - "time" + "os" + "os/signal" + "syscall" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" @@ -34,86 +37,134 @@ import ( "oransc.org/usecase/oruclosedloop/internal/restclient" ) -const timeoutHTTPClient = time.Second * 5 +type Server interface { + ListenAndServe() error +} + const jobId = "14e7bb84-a44d-44c1-90b7-6995a92ad43c" -var infoCoordAddress string +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 host string -var port string -var client restclient.HTTPClient +var consumerPort string func init() { - configuration := config.New() + doInit() +} - client = &http.Client{ - Timeout: timeoutHTTPClient, - } +func doInit() { + configuration = config.New() log.SetLevel(configuration.LogLevel) + log.Debug("Using configuration: ", configuration) + + 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: %v", err) + log.Fatalf("Unable to start consumer due to configuration error: %v", err) } - host = configuration.ConsumerHost - port = fmt.Sprint(configuration.ConsumerPort) csvFileHelper := repository.NewCsvFileHelperImpl() - if initErr := initializeLookupService(csvFileHelper, configuration); initErr != nil { + 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) } - infoCoordAddress = configuration.InfoCoordinatorAddress - - linkfailureConfig = linkfailure.Configuration{ - 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 validateConfiguration(configuration *config.Config) error { if configuration.ConsumerHost == "" || configuration.ConsumerPort == 0 { return fmt.Errorf("consumer host and port must be provided") } - return nil -} -func initializeLookupService(csvFileHelper repository.CsvFileHelper, configuration *config.Config) error { - lookupService = repository.NewLookupServiceImpl(csvFileHelper, configuration.ORUToODUMapFile) - if initErr := lookupService.Init(); initErr != nil { - return initErr + if configuration.ConsumerCertPath == "" || configuration.ConsumerKeyPath == "" { + return fmt.Errorf("missing CONSUMER_CERT and/or CONSUMER_KEY") } + return nil } -func main() { - defer deleteJob() +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() { + 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.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(infoCoordAddress+"/data-consumer/v1/info-jobs/"+jobId, body, client) + 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.") @@ -122,12 +173,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(infoCoordAddress+"/data-consumer/v1/info-jobs/"+jobId, client) + return restclient.Delete(configuration.InfoCoordinatorAddress+"/data-consumer/v1/info-jobs/"+jobId, client) }