diff --git a/.github/workflows/commit-msg-check.yml b/.github/workflows/commit-msg-check.yml index fd6835dec7e5ba1c403e36972fb8895436e95adf..58f298bb63855fe810e4644b4e72bc27fe10dd3e 100644 --- a/.github/workflows/commit-msg-check.yml +++ b/.github/workflows/commit-msg-check.yml @@ -1,8 +1,6 @@ name: 'Commit Message Check' on: - push: - branches: [ main ] pull_request: branches: [ main ] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..521b465ef18c49e353bc280404c8a0758638c2e5 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +GO_BIN_PATH = bin + +WEBCONSOLE = webconsole + +WEBCONSOLE_GO_FILES = $(shell find -name "*.go" ! -name "*_test.go") +WEBCONSOLE_JS_FILES = $(shell find ./frontend -name '*.tsx' ! -path "*/node_modules/*") +WEBCONSOLE_FRONTEND = ./public + +debug: GCFLAGS += -N -l + +$(WEBCONSOLE): $(GO_BIN_PATH)/$(WEBCONSOLE) $(WEBCONSOLE_FRONTEND) + +$(GO_BIN_PATH)/$(WEBCONSOLE): server.go $(WEBCONSOLE_GO_FILES) + @echo "Start building $(@F)...." + CGO_ENABLED=0 go build -ldflags "$(WEBCONSOLE_LDFLAGS)" -o $@ ./server.go + +$(WEBCONSOLE_FRONTEND): $(WEBCONSOLE_JS_FILES) + @echo "Start building $(@F) frontend...." + cd frontend && \ + sudo corepack enable && \ + yarn install && \ + yarn build && \ + rm -rf ../public && \ + cp -R build ../public + +clean: + rm -rf $(GO_BIN_PATH)/$(WEBCONSOLE) + rm -rf public \ No newline at end of file diff --git a/backend/WebUI/api_charging.go b/backend/WebUI/api_charging.go index 3f92b0703f65d6d03980aecc97d860561a786c6c..22db196ee14d16390a8636550c9ca02e6471a7c2 100644 --- a/backend/WebUI/api_charging.go +++ b/backend/WebUI/api_charging.go @@ -172,7 +172,10 @@ func GetChargingRecord(c *gin.Context) { } for rg, du := range ratingGroupDataUsages { - filter := bson.M{"ratingGroup": rg} + filter := bson.M{ + "ueId": supi, + "ratingGroup": rg, + } chargingDataInterface, err := mongoapi.RestfulAPIGetOne(chargingDataColl, filter) if err != nil { logger.ProcLog.Errorf("PostSubscriberByID err: %+v", err) diff --git a/backend/billing/server.go b/backend/billing/server.go index f2ef04602a665748a70dff33a6ec5e94e053035a..d31cb1d79cb3f0936fa29b7d849f147b87b6e80f 100644 --- a/backend/billing/server.go +++ b/backend/billing/server.go @@ -6,7 +6,6 @@ import ( "os" "strconv" "sync" - "time" "github.com/fclairamb/ftpserver/config" "github.com/fclairamb/ftpserver/server" @@ -19,6 +18,7 @@ import ( type BillingDomain struct { ftpServer *ftpserver.FtpServer driver *server.Server + wg *sync.WaitGroup } type Access struct { @@ -28,10 +28,17 @@ type Access struct { Params map[string]string `json:"params"` } +type PortRange struct { + Start int `json:"start"` + End int `json:"end"` +} + type FtpConfig struct { Version int `json:"version"` Accesses []Access `json:"accesses"` Listen_address string `json:"listen_address"` + + Passive_transfer_port_range PortRange `json:"passive_transfer_port_range"` } // The ftp server is for CDR Push method, that is the CHF will send the CDR file to the FTP server @@ -39,7 +46,9 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { // Arguments vars confFile := "/tmp/webconsole/ftpserver.json" - b := &BillingDomain{} + b := &BillingDomain{ + wg: wg, + } if _, err := os.Stat("/tmp/webconsole"); err != nil { if err := os.Mkdir("/tmp/webconsole", os.ModePerm); err != nil { logger.BillingLog.Error(err) @@ -68,7 +77,10 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { Params: params, }, }, - + Passive_transfer_port_range: PortRange{ + Start: 2123, + End: 2130, + }, Listen_address: addr, } @@ -105,33 +117,26 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { // Setting up the ftpserver logger b.ftpServer.Logger = logger.FtpServerLog - go b.Serve(wg) + go b.Serve() logger.BillingLog.Info("Billing server Start") return b } -func (b *BillingDomain) Serve(wg *sync.WaitGroup) { - defer func() { - logger.BillingLog.Error("Billing server stopped") - b.Stop() - wg.Done() - }() - +func (b *BillingDomain) Serve() { if err := b.ftpServer.ListenAndServe(); err != nil { logger.BillingLog.Error("Problem listening ", "err", err) } - - // We wait at most 1 minutes for all clients to disconnect - if err := b.driver.WaitGracefully(time.Minute); err != nil { - logger.BillingLog.Warn("Problem stopping server", "Err", err) - } } func (b *BillingDomain) Stop() { - b.driver.Stop() + logger.BillingLog.Infoln("Stop BillingDomain server") + b.driver.Stop() if err := b.ftpServer.Stop(); err != nil { logger.BillingLog.Error("Problem stopping server", "Err", err) } + + logger.BillingLog.Infoln("BillingDomain server stopped") + b.wg.Done() } diff --git a/backend/webui_context/context.go b/backend/webui_context/context.go index 3414c338697b4618fb47aed2a2ac52cbaada4355..6f938b3a0e598dee8971143833b1bb3c38ca3f9f 100644 --- a/backend/webui_context/context.go +++ b/backend/webui_context/context.go @@ -10,7 +10,6 @@ import ( "github.com/free5gc/openapi/Nnrf_NFManagement" "github.com/free5gc/openapi/models" "github.com/free5gc/openapi/oauth" - "github.com/free5gc/webconsole/backend/billing" "github.com/free5gc/webconsole/backend/factory" "github.com/free5gc/webconsole/backend/logger" ) @@ -21,7 +20,9 @@ type WEBUIContext struct { NfInstanceID string NFProfiles []models.NfProfile NFOamInstances []NfOamInstance - BillingServer *billing.BillingDomain + + // is registered to NRF as AF + IsRegistered bool NrfUri string OAuth2Required bool @@ -40,6 +41,8 @@ func Init() { webuiContext.NfInstanceID = uuid.New().String() webuiContext.NrfUri = factory.WebuiConfig.Configuration.NrfUri + webuiContext.IsRegistered = false + ManagementConfig := Nnrf_NFManagement.NewConfiguration() ManagementConfig.SetBasePath(GetSelf().NrfUri) webuiContext.NFManagementClient = Nnrf_NFManagement.NewAPIClient(ManagementConfig) diff --git a/backend/webui_context/nrf_management.go b/backend/webui_context/nrf_management.go index c404d97e49fcd934bda9a96e4c8d675b3fc938de..1e6224f7d02f4acf7e44b455fcc248ca1ba73af7 100644 --- a/backend/webui_context/nrf_management.go +++ b/backend/webui_context/nrf_management.go @@ -33,7 +33,7 @@ func SendNFRegistration() error { NFInstanceIDDocumentApi. RegisterNFInstance(context.TODO(), GetSelf().NfInstanceID, profile) if err != nil || res == nil { - logger.ConsumerLog.Infof("Webconsole-AF register to NRF Error[%s]", err.Error()) + logger.ConsumerLog.Warnf("Webconsole-AF register to NRF Error[%s]", err.Error()) time.Sleep(2 * time.Second) retryTime += 1 if retryTime == 10 { diff --git a/backend/webui_service/webui_init.go b/backend/webui_service/webui_init.go index 2b9c9014a90ce118b45c9bea7af8ab44ee27551b..e318378888aa6e6ade97cbaa751bb2a2d29e60e6 100644 --- a/backend/webui_service/webui_init.go +++ b/backend/webui_service/webui_init.go @@ -1,12 +1,15 @@ package webui_service import ( + "context" "io" + "net/http" "os" "os/signal" "runtime/debug" "sync" "syscall" + "time" "github.com/gin-contrib/cors" "github.com/sirupsen/logrus" @@ -22,10 +25,17 @@ import ( type WebuiApp struct { cfg *factory.Config webuiCtx *webui_context.WEBUIContext + + wg *sync.WaitGroup + server *http.Server + billingServer *billing.BillingDomain } func NewApp(cfg *factory.Config) (*WebuiApp, error) { - webui := &WebuiApp{cfg: cfg} + webui := &WebuiApp{ + cfg: cfg, + wg: &sync.WaitGroup{}, + } webui.SetLogEnable(cfg.GetLogEnable()) webui.SetLogLevel(cfg.GetLogLevel()) webui.SetReportCaller(cfg.GetLogReportCaller()) @@ -87,6 +97,7 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) { logger.InitLog.Infoln("Server started") + a.wg.Add(1) signalChannel := make(chan os.Signal, 1) signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) go func() { @@ -99,7 +110,7 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) { <-signalChannel a.Terminate() - os.Exit(0) + a.wg.Done() }() go func() { @@ -110,6 +121,8 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) { logger.InitLog.Errorln(retry_err) logger.InitLog.Warningln("The registration to NRF failed, resulting in limited functionalities.") } + } else { + a.webuiCtx.IsRegistered = true } }() @@ -135,37 +148,66 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) { self := webui_context.GetSelf() self.UpdateNfProfiles() - wg := sync.WaitGroup{} - if billingServer.Enable { - wg.Add(1) - self.BillingServer = billing.OpenServer(&wg) - if self.BillingServer == nil { + a.wg.Add(1) + a.billingServer = billing.OpenServer(a.wg) + if a.billingServer == nil { logger.InitLog.Errorln("Billing Server open error.") } } router.NoRoute(ReturnPublic()) + var addr string if webServer != nil { - logger.InitLog.Infoln(router.Run(webServer.IP + ":" + webServer.PORT)) + addr = webServer.IP + ":" + webServer.PORT } else { - logger.InitLog.Infoln(router.Run(":5000")) + addr = ":5000" } - wg.Wait() + a.server = &http.Server{ + Addr: addr, + Handler: router, + } + go func() { + logger.MainLog.Infof("Http server listening on %+v", addr) + if err := a.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + logger.MainLog.Fatalf("listen: %s\n", err) + } + }() + + logger.MainLog.Infoln("wait all routine stopped") + a.wg.Wait() } func (a *WebuiApp) Terminate() { - logger.InitLog.Infoln("Terminating WebUI-AF...") + logger.MainLog.Infoln("Terminating WebUI-AF...") + + if a.billingServer != nil { + a.billingServer.Stop() + } + + if a.server != nil { + logger.MainLog.Infoln("stopping HTTP server") + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := a.server.Shutdown(ctx); err != nil { + logger.MainLog.Fatal("HTTP server forced to shutdown: ", err) + } + } // Deregister with NRF - problemDetails, err := webui_context.SendDeregisterNFInstance() - if problemDetails != nil { - logger.InitLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails) - } else if err != nil { - logger.InitLog.Errorf("Deregister NF instance Error[%+v]", err) - } else { - logger.InitLog.Infof("Deregister from NRF successfully") + if a.webuiCtx.IsRegistered { + problemDetails, err := webui_context.SendDeregisterNFInstance() + if problemDetails != nil { + logger.InitLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails) + } else if err != nil { + logger.InitLog.Errorf("Deregister NF instance Error[%+v]", err) + } else { + logger.InitLog.Infof("Deregister from NRF successfully") + } } + + logger.MainLog.Infoln("WebUI-AF Terminated") } diff --git a/config/webuicfg.yaml b/config/webuicfg.yaml index 6f55547ccab49c1514dbbe97a586d961681eab3f..232a56f8b1e982bf9d9d42ee5335074b07ba1ea4 100644 --- a/config/webuicfg.yaml +++ b/config/webuicfg.yaml @@ -14,8 +14,8 @@ configuration: billingServer: enable: true hostIPv4: 127.0.0.1 - listenPort: 2122 - port: 2121 + listenPort: 2121 + port: 2122 tls: pem: cert/chf.pem key: cert/chf.key