From c6b3e89cadee7078097c7233e402440ff6cd3056 Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Mon, 22 Apr 2024 14:32:13 +0000 Subject: [PATCH 01/20] refactor: nrf-service-finish --- internal/sbi/consumer/consumer.go | 38 ++++ internal/sbi/consumer/nrf_service.go | 299 +++++++++++++++++++++++++++ pkg/service/init.go | 29 +++ 3 files changed, 366 insertions(+) create mode 100644 internal/sbi/consumer/consumer.go create mode 100644 internal/sbi/consumer/nrf_service.go diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go new file mode 100644 index 0000000..d757ca2 --- /dev/null +++ b/internal/sbi/consumer/consumer.go @@ -0,0 +1,38 @@ +package consumer + +import ( + "context" + + "github.com/free5gc/pcf/pkg/factory" + "github.com/free5gc/openapi/Nnrf_NFDiscovery" + "github.com/free5gc/openapi/Nnrf_NFManagement" + + pcf_context "github.com/free5gc/pcf/internal/context" +) + +type pcf interface { + Config() *factory.Config + Context() *pcf_context.PCFContext + CancelContext() context.Context +} + +type Consumer struct { + pcf + + // consumer services + *nnrfService +} + +func NewConsumer(pcf pcf) (*Consumer, error) { + c := &Consumer{ + pcf: pcf, + } + + c.nnrfService = &nnrfService{ + consumer: c, + nfMngmntClients: make(map[string]*Nnrf_NFManagement.APIClient), + nfDiscClients: make(map[string]*Nnrf_NFDiscovery.APIClient), + } + + return c, nil +} \ No newline at end of file diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go new file mode 100644 index 0000000..869c05f --- /dev/null +++ b/internal/sbi/consumer/nrf_service.go @@ -0,0 +1,299 @@ +package consumer + +import ( + "fmt" + "net/http" + "strings" + "time" + "sync" + + "github.com/antihax/optional" + "github.com/pkg/errors" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nnrf_NFDiscovery" + "github.com/free5gc/openapi/Nnrf_NFManagement" + "github.com/free5gc/openapi/models" + pcf_context "github.com/free5gc/pcf/internal/context" + "github.com/free5gc/pcf/internal/logger" + "github.com/free5gc/pcf/internal/util" +) +type nnrfService struct{ + consumer *Consumer + + nfMngmntMu sync.RWMutex + nfDiscMu sync.RWMutex + + nfMngmntClients map[string]*Nnrf_NFManagement.APIClient + nfDiscClients map[string]*Nnrf_NFDiscovery.APIClient + +} + +func (s *nnrfService) getNFManagementClient(uri string) *Nnrf_NFManagement.APIClient { + if uri == "" { + return nil + } + s.nfMngmntMu.RLock() + client, ok := s.nfMngmntClients[uri] + if ok { + defer s.nfMngmntMu.RUnlock() + return client + } + + configuration := Nnrf_NFManagement.NewConfiguration() + configuration.SetBasePath(uri) + client = Nnrf_NFManagement.NewAPIClient(configuration) + + s.nfMngmntMu.RUnlock() + s.nfMngmntMu.Lock() + defer s.nfMngmntMu.Unlock() + s.nfMngmntClients[uri] = client + return client +} + +func (s *nnrfService) getNFDiscClient(uri string) *Nnrf_NFDiscovery.APIClient{ + if uri == "" { + return nil + } + s.nfDiscMu.RLock() + client, ok := s.nfDiscClients[uri] + if ok { + defer s.nfDiscMu.RUnlock() + return client + } + + configuration := Nnrf_NFDiscovery.NewConfiguration() + configuration.SetBasePath(uri) + client = Nnrf_NFDiscovery.NewAPIClient(configuration) + + s.nfDiscMu.RUnlock() + s.nfDiscMu.Lock() + defer s.nfDiscMu.Unlock() + s.nfDiscClients[uri] = client + return client + +} +func (s *nnrfService) SendSearchNFInstances( + nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( + *models.SearchResult, error, +) { + // Set client and set url + client := s.getNFDiscClient(nrfUri) + + ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) + if err != nil { + return nil, err + } + + result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, ¶m) + if err != nil { + logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err) + } + defer func() { + if resCloseErr := res.Body.Close(); resCloseErr != nil { + logger.ConsumerLog.Errorf("NFInstancesStoreApi response body cannot close: %+v", resCloseErr) + } + }() + if res != nil && res.StatusCode == http.StatusTemporaryRedirect { + return nil, fmt.Errorf("Temporary Redirect For Non NRF Consumer") + } + + return &result, nil +} + +func (s *nnrfService) SendNFInstancesUDR(nrfUri, id string) string { + targetNfType := models.NfType_UDR + requestNfType := models.NfType_PCF + localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ + // DataSet: optional.NewInterface(models.DataSetId_SUBSCRIPTION), + } + // switch types { + // case NFDiscoveryToUDRParamSupi: + // localVarOptionals.Supi = optional.NewString(id) + // case NFDiscoveryToUDRParamExtGroupId: + // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) + // case NFDiscoveryToUDRParamGpsi: + // localVarOptionals.Gpsi = optional.NewString(id) + // } + + result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) + if err != nil { + logger.ConsumerLog.Error(err.Error()) + return "" + } + for _, profile := range result.NfInstances { + if uri := util.SearchNFServiceUri(profile, models.ServiceName_NUDR_DR, models.NfServiceStatus_REGISTERED); uri != "" { + return uri + } + } + return "" +} + +func (s *nnrfService) SendNFInstancesBSF(nrfUri string) string { + targetNfType := models.NfType_BSF + requestNfType := models.NfType_PCF + localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{} + + result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) + if err != nil { + logger.ConsumerLog.Error(err.Error()) + return "" + } + for _, profile := range result.NfInstances { + if uri := util.SearchNFServiceUri(profile, models.ServiceName_NBSF_MANAGEMENT, + models.NfServiceStatus_REGISTERED); uri != "" { + return uri + } + } + return "" +} + +func (s *nnrfService) SendNFInstancesAMF(nrfUri string, guami models.Guami, serviceName models.ServiceName) string { + targetNfType := models.NfType_AMF + requestNfType := models.NfType_PCF + + localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ + Guami: optional.NewInterface(util.MarshToJsonString(guami)), + } + // switch types { + // case NFDiscoveryToUDRParamSupi: + // localVarOptionals.Supi = optional.NewString(id) + // case NFDiscoveryToUDRParamExtGroupId: + // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) + // case NFDiscoveryToUDRParamGpsi: + // localVarOptionals.Gpsi = optional.NewString(id) + // } + + result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) + if err != nil { + logger.ConsumerLog.Error(err.Error()) + return "" + } + for _, profile := range result.NfInstances { + return util.SearchNFServiceUri(profile, serviceName, models.NfServiceStatus_REGISTERED) + } + return "" +} +//management +func (s *nnrfService) BuildNFInstance(context *pcf_context.PCFContext) (profile models.NfProfile, err error) { + profile.NfInstanceId = context.NfId + profile.NfType = models.NfType_PCF + profile.NfStatus = models.NfStatus_REGISTERED + profile.Ipv4Addresses = append(profile.Ipv4Addresses, context.RegisterIPv4) + service := []models.NfService{} + for _, nfService := range context.NfService { + service = append(service, nfService) + } + profile.NfServices = &service + profile.PcfInfo = &models.PcfInfo{ + DnnList: []string{ + "free5gc", + "internet", + }, + // SupiRanges: &[]models.SupiRange{ + // { + // //from TS 29.510 6.1.6.2.9 example2 + // //no need to set supirange in this moment 2019/10/4 + // Start: "123456789040000", + // End: "123456789059999", + // Pattern: "^imsi-12345678904[0-9]{4}$", + // }, + // }, + } + if context.Locality != "" { + profile.Locality = context.Locality + } + return +} + +func (s *nnrfService) SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfile) ( + resouceNrfUri string, retrieveNfInstanceID string, err error, +) { + // Set client and set url + client := s.getNFManagementClient(nrfUri) + + ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + if err != nil { + return "", "", + errors.Errorf("SendRegisterNFInstance error: %+v", err) + } + + var res *http.Response + var nf models.NfProfile + for { + nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, nfInstanceId, profile) + if err != nil || res == nil { + // TODO : add log + fmt.Println(fmt.Errorf("PCF register to NRF Error[%v]", err.Error())) + time.Sleep(2 * time.Second) + continue + } + defer func() { + if resCloseErr := res.Body.Close(); resCloseErr != nil { + logger.ConsumerLog.Errorf("RegisterNFInstance response body cannot close: %+v", resCloseErr) + } + }() + status := res.StatusCode + if status == http.StatusOK { + // NFUpdate + break + } else if status == http.StatusCreated { + // NFRegister + resourceUri := res.Header.Get("Location") + resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")] + retrieveNfInstanceID = resourceUri[strings.LastIndex(resourceUri, "/")+1:] + + oauth2 := false + if nf.CustomInfo != nil { + v, ok := nf.CustomInfo["oauth2"].(bool) + if ok { + oauth2 = v + logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2) + } + } + pcf_context.GetSelf().OAuth2Required = oauth2 + + if oauth2 && pcf_context.GetSelf().NrfCertPem == "" { + logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") + } + break + } else { + fmt.Println("NRF return wrong status code", status) + } + } + return resouceNrfUri, retrieveNfInstanceID, err +} + +func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) { + logger.ConsumerLog.Infof("Send Deregister NFInstance") + + ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + if err != nil { + return pd, err + } + + pcfContext := s.consumer.pcf.Context() + // Set client and set url + client := s.getNFManagementClient(pcfContext.NrfUri) + + var res *http.Response + + res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, pcfContext.NfId) + if err == nil { + return nil, nil + } else if res != nil { + defer func() { + if resCloseErr := res.Body.Close(); resCloseErr != nil { + logger.ConsumerLog.Errorf("DeregisterNFInstance response cannot close: %+v", resCloseErr) + } + }() + if res.Status != err.Error() { + return nil, err + } + problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) + problemDetails = &problem + } else { + err = openapi.ReportError("server no response") + } + return problemDetails, err +} diff --git a/pkg/service/init.go b/pkg/service/init.go index 07c4d03..a6cef23 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -1,12 +1,14 @@ package service import ( + "context" "fmt" "io" "os" "os/signal" "runtime/debug" "syscall" + // "sync" "github.com/antihax/optional" "github.com/gin-contrib/cors" @@ -33,6 +35,10 @@ import ( type PcfApp struct { cfg *factory.Config pcfCtx *pcf_context.PCFContext + ctx context.Context + cancel context.CancelFunc + + consumer *consumer.Consumer } func NewApp(cfg *factory.Config) (*PcfApp, error) { @@ -43,9 +49,32 @@ func NewApp(cfg *factory.Config) (*PcfApp, error) { pcf_context.Init() pcf.pcfCtx = pcf_context.GetSelf() + + //consumer + consumer, err := consumer.NewConsumer(pcf) + if err != nil { + return pcf, err + } + pcf.consumer = consumer return pcf, nil } +func (a *PcfApp) Config() *factory.Config { + return a.cfg +} + +func (a *PcfApp) Context() *pcf_context.PCFContext { + return a.pcfCtx +} + +func (a *PcfApp) CancelContext() context.Context { + return a.ctx +} + +func (a *PcfApp) Consumer() *consumer.Consumer { + return a.consumer +} + func (a *PcfApp) SetLogEnable(enable bool) { logger.MainLog.Infof("Log enable is set to [%v]", enable) if enable && logger.Log.Out == os.Stderr { From e5dd0ae2ddfda052b16023f481dab108483dcec9 Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Mon, 22 Apr 2024 14:32:13 +0000 Subject: [PATCH 02/20] refactor: consumer-finish --- internal/sbi/consumer/amf_service.go | 95 +++++++++ internal/sbi/consumer/consumer.go | 52 +++++ internal/sbi/consumer/nrf_service.go | 300 +++++++++++++++++++++++++++ internal/sbi/consumer/udr_service.go | 135 ++++++++++++ pkg/service/init.go | 29 +++ 5 files changed, 611 insertions(+) create mode 100644 internal/sbi/consumer/amf_service.go create mode 100644 internal/sbi/consumer/consumer.go create mode 100644 internal/sbi/consumer/nrf_service.go create mode 100644 internal/sbi/consumer/udr_service.go diff --git a/internal/sbi/consumer/amf_service.go b/internal/sbi/consumer/amf_service.go new file mode 100644 index 0000000..0cc649e --- /dev/null +++ b/internal/sbi/consumer/amf_service.go @@ -0,0 +1,95 @@ +package consumer + +import ( + "fmt" + "strings" + "sync" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Namf_Communication" + "github.com/free5gc/openapi/models" + pcf_context "github.com/free5gc/pcf/internal/context" + "github.com/free5gc/pcf/internal/logger" + "github.com/free5gc/pcf/pkg/factory" +) + +type namfService struct { + consumer *Consumer + + nfComMu sync.RWMutex + + nfComClients map[string]*Namf_Communication.APIClient +} + +func (s *namfService) getNFCommunicationClient(uri string) *Namf_Communication.APIClient { + if uri == "" { + return nil + } + s.nfComMu.RLock() + client, ok := s.nfComClients[uri] + if ok { + defer s.nfComMu.RUnlock() + return client + } + + configuration := Namf_Communication.NewConfiguration() + configuration.SetBasePath(uri) + client = Namf_Communication.NewAPIClient(configuration) + + s.nfComMu.RUnlock() + s.nfComMu.Lock() + defer s.nfComMu.Unlock() + s.nfComClients[uri] = client + return client +} + +func (s *namfService) AmfStatusChangeSubscribe(amfUri string, guamiList []models.Guami) ( + problemDetails *models.ProblemDetails, err error, +) { + + + logger.ConsumerLog.Debugf("PCF Subscribe to AMF status[%+v]", amfUri) + pcfContext := s.consumer.pcf.Context() + + // Set client and set url + client := s.getNFCommunicationClient(amfUri) + + subscriptionData := models.SubscriptionData{ + AmfStatusUri: fmt.Sprintf("%s"+factory.PcfCallbackResUriPrefix+"/amfstatus", pcfContext.GetIPv4Uri()), + GuamiList: guamiList, + } + ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) + if err != nil { + return pd, err + } + res, httpResp, localErr := client.SubscriptionsCollectionDocumentApi.AMFStatusChangeSubscribe( + ctx, subscriptionData) + defer func() { + if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { + logger.ConsumerLog.Errorf("AMFStatusChangeSubscribe response body cannot close: %+v", + rspCloseErr) + } + }() + if localErr == nil { + locationHeader := httpResp.Header.Get("Location") + logger.ConsumerLog.Debugf("location header: %+v", locationHeader) + + subscriptionID := locationHeader[strings.LastIndex(locationHeader, "/")+1:] + amfStatusSubsData := pcf_context.AMFStatusSubscriptionData{ + AmfUri: amfUri, + AmfStatusUri: res.AmfStatusUri, + GuamiList: res.GuamiList, + } + pcfContext.NewAmfStatusSubscription(subscriptionID, amfStatusSubsData) + } else if httpResp != nil { + if httpResp.Status != localErr.Error() { + err = localErr + return nil, err + } + problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) + problemDetails = &problem + } else { + err = openapi.ReportError("%s: server no response", amfUri) + } + return problemDetails, err +} diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go new file mode 100644 index 0000000..dad356e --- /dev/null +++ b/internal/sbi/consumer/consumer.go @@ -0,0 +1,52 @@ +package consumer + +import ( + "context" + + "github.com/free5gc/pcf/pkg/factory" + "github.com/free5gc/openapi/Nnrf_NFDiscovery" + "github.com/free5gc/openapi/Nnrf_NFManagement" + "github.com/free5gc/openapi/Namf_Communication" + "github.com/free5gc/openapi/Nudr_DataRepository" + + pcf_context "github.com/free5gc/pcf/internal/context" +) + +type pcf interface { + Config() *factory.Config + Context() *pcf_context.PCFContext + CancelContext() context.Context +} + +type Consumer struct { + pcf + + // consumer services + *nnrfService + *namfService + *nudrService +} + +func NewConsumer(pcf pcf) (*Consumer, error) { + c := &Consumer{ + pcf: pcf, + } + + c.nnrfService = &nnrfService{ + consumer: c, + nfMngmntClients: make(map[string]*Nnrf_NFManagement.APIClient), + nfDiscClients: make(map[string]*Nnrf_NFDiscovery.APIClient), + } + + c.namfService = &namfService{ + consumer: c, + nfComClients: make(map[string]*Namf_Communication.APIClient), + } + + c.nudrService = &nudrService{ + consumer: c, + nfDataSubClients: make(map[string]*Nudr_DataRepository.APIClient), + } + + return c, nil +} \ No newline at end of file diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go new file mode 100644 index 0000000..0791e74 --- /dev/null +++ b/internal/sbi/consumer/nrf_service.go @@ -0,0 +1,300 @@ +package consumer + +import ( + "fmt" + "net/http" + "strings" + "time" + "sync" + + "github.com/antihax/optional" + "github.com/pkg/errors" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nnrf_NFDiscovery" + "github.com/free5gc/openapi/Nnrf_NFManagement" + "github.com/free5gc/openapi/models" + pcf_context "github.com/free5gc/pcf/internal/context" + "github.com/free5gc/pcf/internal/logger" + "github.com/free5gc/pcf/internal/util" +) + +type nnrfService struct{ + consumer *Consumer + + nfMngmntMu sync.RWMutex + nfDiscMu sync.RWMutex + + nfMngmntClients map[string]*Nnrf_NFManagement.APIClient + nfDiscClients map[string]*Nnrf_NFDiscovery.APIClient + +} + +func (s *nnrfService) getNFManagementClient(uri string) *Nnrf_NFManagement.APIClient { + if uri == "" { + return nil + } + s.nfMngmntMu.RLock() + client, ok := s.nfMngmntClients[uri] + if ok { + defer s.nfMngmntMu.RUnlock() + return client + } + + configuration := Nnrf_NFManagement.NewConfiguration() + configuration.SetBasePath(uri) + client = Nnrf_NFManagement.NewAPIClient(configuration) + + s.nfMngmntMu.RUnlock() + s.nfMngmntMu.Lock() + defer s.nfMngmntMu.Unlock() + s.nfMngmntClients[uri] = client + return client +} + +func (s *nnrfService) getNFDiscClient(uri string) *Nnrf_NFDiscovery.APIClient{ + if uri == "" { + return nil + } + s.nfDiscMu.RLock() + client, ok := s.nfDiscClients[uri] + if ok { + defer s.nfDiscMu.RUnlock() + return client + } + + configuration := Nnrf_NFDiscovery.NewConfiguration() + configuration.SetBasePath(uri) + client = Nnrf_NFDiscovery.NewAPIClient(configuration) + + s.nfDiscMu.RUnlock() + s.nfDiscMu.Lock() + defer s.nfDiscMu.Unlock() + s.nfDiscClients[uri] = client + return client + +} +func (s *nnrfService) SendSearchNFInstances( + nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( + *models.SearchResult, error, +) { + // Set client and set url + client := s.getNFDiscClient(nrfUri) + + ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) + if err != nil { + return nil, err + } + + result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, ¶m) + if err != nil { + logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err) + } + defer func() { + if resCloseErr := res.Body.Close(); resCloseErr != nil { + logger.ConsumerLog.Errorf("NFInstancesStoreApi response body cannot close: %+v", resCloseErr) + } + }() + if res != nil && res.StatusCode == http.StatusTemporaryRedirect { + return nil, fmt.Errorf("Temporary Redirect For Non NRF Consumer") + } + + return &result, nil +} + +func (s *nnrfService) SendNFInstancesUDR(nrfUri, id string) string { + targetNfType := models.NfType_UDR + requestNfType := models.NfType_PCF + localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ + // DataSet: optional.NewInterface(models.DataSetId_SUBSCRIPTION), + } + // switch types { + // case NFDiscoveryToUDRParamSupi: + // localVarOptionals.Supi = optional.NewString(id) + // case NFDiscoveryToUDRParamExtGroupId: + // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) + // case NFDiscoveryToUDRParamGpsi: + // localVarOptionals.Gpsi = optional.NewString(id) + // } + + result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) + if err != nil { + logger.ConsumerLog.Error(err.Error()) + return "" + } + for _, profile := range result.NfInstances { + if uri := util.SearchNFServiceUri(profile, models.ServiceName_NUDR_DR, models.NfServiceStatus_REGISTERED); uri != "" { + return uri + } + } + return "" +} + +func (s *nnrfService) SendNFInstancesBSF(nrfUri string) string { + targetNfType := models.NfType_BSF + requestNfType := models.NfType_PCF + localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{} + + result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) + if err != nil { + logger.ConsumerLog.Error(err.Error()) + return "" + } + for _, profile := range result.NfInstances { + if uri := util.SearchNFServiceUri(profile, models.ServiceName_NBSF_MANAGEMENT, + models.NfServiceStatus_REGISTERED); uri != "" { + return uri + } + } + return "" +} + +func (s *nnrfService) SendNFInstancesAMF(nrfUri string, guami models.Guami, serviceName models.ServiceName) string { + targetNfType := models.NfType_AMF + requestNfType := models.NfType_PCF + + localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ + Guami: optional.NewInterface(util.MarshToJsonString(guami)), + } + // switch types { + // case NFDiscoveryToUDRParamSupi: + // localVarOptionals.Supi = optional.NewString(id) + // case NFDiscoveryToUDRParamExtGroupId: + // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) + // case NFDiscoveryToUDRParamGpsi: + // localVarOptionals.Gpsi = optional.NewString(id) + // } + + result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) + if err != nil { + logger.ConsumerLog.Error(err.Error()) + return "" + } + for _, profile := range result.NfInstances { + return util.SearchNFServiceUri(profile, serviceName, models.NfServiceStatus_REGISTERED) + } + return "" +} +//management +func (s *nnrfService) BuildNFInstance(context *pcf_context.PCFContext) (profile models.NfProfile, err error) { + profile.NfInstanceId = context.NfId + profile.NfType = models.NfType_PCF + profile.NfStatus = models.NfStatus_REGISTERED + profile.Ipv4Addresses = append(profile.Ipv4Addresses, context.RegisterIPv4) + service := []models.NfService{} + for _, nfService := range context.NfService { + service = append(service, nfService) + } + profile.NfServices = &service + profile.PcfInfo = &models.PcfInfo{ + DnnList: []string{ + "free5gc", + "internet", + }, + // SupiRanges: &[]models.SupiRange{ + // { + // //from TS 29.510 6.1.6.2.9 example2 + // //no need to set supirange in this moment 2019/10/4 + // Start: "123456789040000", + // End: "123456789059999", + // Pattern: "^imsi-12345678904[0-9]{4}$", + // }, + // }, + } + if context.Locality != "" { + profile.Locality = context.Locality + } + return +} + +func (s *nnrfService) SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfile) ( + resouceNrfUri string, retrieveNfInstanceID string, err error, +) { + // Set client and set url + client := s.getNFManagementClient(nrfUri) + + ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + if err != nil { + return "", "", + errors.Errorf("SendRegisterNFInstance error: %+v", err) + } + + var res *http.Response + var nf models.NfProfile + for { + nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, nfInstanceId, profile) + if err != nil || res == nil { + // TODO : add log + fmt.Println(fmt.Errorf("PCF register to NRF Error[%v]", err.Error())) + time.Sleep(2 * time.Second) + continue + } + defer func() { + if resCloseErr := res.Body.Close(); resCloseErr != nil { + logger.ConsumerLog.Errorf("RegisterNFInstance response body cannot close: %+v", resCloseErr) + } + }() + status := res.StatusCode + if status == http.StatusOK { + // NFUpdate + break + } else if status == http.StatusCreated { + // NFRegister + resourceUri := res.Header.Get("Location") + resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")] + retrieveNfInstanceID = resourceUri[strings.LastIndex(resourceUri, "/")+1:] + + oauth2 := false + if nf.CustomInfo != nil { + v, ok := nf.CustomInfo["oauth2"].(bool) + if ok { + oauth2 = v + logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2) + } + } + pcf_context.GetSelf().OAuth2Required = oauth2 + + if oauth2 && pcf_context.GetSelf().NrfCertPem == "" { + logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") + } + break + } else { + fmt.Println("NRF return wrong status code", status) + } + } + return resouceNrfUri, retrieveNfInstanceID, err +} + +func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) { + logger.ConsumerLog.Infof("Send Deregister NFInstance") + + ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + if err != nil { + return pd, err + } + + pcfContext := s.consumer.pcf.Context() + // Set client and set url + client := s.getNFManagementClient(pcfContext.NrfUri) + + var res *http.Response + + res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, pcfContext.NfId) + if err == nil { + return nil, nil + } else if res != nil { + defer func() { + if resCloseErr := res.Body.Close(); resCloseErr != nil { + logger.ConsumerLog.Errorf("DeregisterNFInstance response cannot close: %+v", resCloseErr) + } + }() + if res.Status != err.Error() { + return nil, err + } + problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) + problemDetails = &problem + } else { + err = openapi.ReportError("server no response") + } + return problemDetails, err +} diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go new file mode 100644 index 0000000..f3509d0 --- /dev/null +++ b/internal/sbi/consumer/udr_service.go @@ -0,0 +1,135 @@ +package consumer + +import ( + "strconv" + "strings" + "sync" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/openapi/Nudr_DataRepository" + pcf_context "github.com/free5gc/pcf/internal/context" + "github.com/free5gc/pcf/internal/logger" + "github.com/free5gc/pcf/internal/util" +) + +type nudrService struct { + consumer *Consumer + + nfDataSubMu sync.RWMutex + + nfDataSubClients map[string]*Nudr_DataRepository.APIClient +} + +func (s *nudrService) getDataSubscription(uri string) *Nudr_DataRepository.APIClient { + if uri == "" { + return nil + } + s.nfDataSubMu.RLock() + client, ok := s.nfDataSubClients[uri] + if ok { + defer s.nfDataSubMu.RUnlock() + return client + } + + configuration := Nudr_DataRepository.NewConfiguration() + configuration.SetBasePath(uri) + client = Nudr_DataRepository.NewAPIClient(configuration) + + s.nfDataSubMu.RUnlock() + s.nfDataSubMu.Lock() + defer s.nfDataSubMu.Unlock() + s.nfDataSubClients[uri] = client + return client +} + +func (s *nudrService) CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.SmPolicyContextData) ( + subscriptionID string, problemDetails *models.ProblemDetails, err error, +) { + if ue.UdrUri == "" { + problemDetail := util.GetProblemDetail("Can't find corresponding UDR with UE", util.USER_UNKNOWN) + logger.ConsumerLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) + return "", &problemDetail, nil + } + ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return "", pd, err + } + client := s.getDataSubscription(ue.UdrUri); + trafficInfluSub := s.buildTrafficInfluSub(request) + _, httpResp, localErr := client.InfluenceDataSubscriptionsCollectionApi. + ApplicationDataInfluenceDataSubsToNotifyPost(ctx, trafficInfluSub) + if localErr == nil { + locationHeader := httpResp.Header.Get("Location") + subscriptionID = locationHeader[strings.LastIndex(locationHeader, "/")+1:] + logger.ConsumerLog.Debugf("Influence Data Subscription ID: %s", subscriptionID) + return subscriptionID, nil, nil + } else if httpResp != nil { + defer func() { + if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { + logger.ConsumerLog.Errorf("CreateInfluenceDataSubscription response body cannot close: %+v", + rspCloseErr) + } + }() + if httpResp.Status != localErr.Error() { + err = localErr + return subscriptionID, problemDetails, err + } + problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) + problemDetails = &problem + } else { + err = openapi.ReportError("server no response") + } + return "", problemDetails, err +} + +func (s *nudrService) buildTrafficInfluSub(request models.SmPolicyContextData) models.TrafficInfluSub { + trafficInfluSub := models.TrafficInfluSub{ + Dnns: []string{request.Dnn}, + Snssais: []models.Snssai{*request.SliceInfo}, + InternalGroupIds: request.InterGrpIds, + Supis: []string{request.Supi}, + NotificationUri: pcf_context.GetSelf().GetIPv4Uri() + + pcf_context.InfluenceDataUpdateNotifyUri + "/" + + request.Supi + "/" + strconv.Itoa(int(request.PduSessionId)), + // TODO: support expiry time and resend subscription when expired + } + return trafficInfluSub +} + +func (s *nudrService) RemoveInfluenceDataSubscription(ue *pcf_context.UeContext, subscriptionID string) ( + problemDetails *models.ProblemDetails, err error, +) { + if ue.UdrUri == "" { + problemDetail := util.GetProblemDetail("Can't find corresponding UDR with UE", util.USER_UNKNOWN) + logger.ConsumerLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) + return &problemDetail, nil + } + ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd, err + } + client := s.getDataSubscription(ue.UdrUri) + httpResp, localErr := client.IndividualInfluenceDataSubscriptionDocumentApi. + ApplicationDataInfluenceDataSubsToNotifySubscriptionIdDelete(ctx, subscriptionID) + if localErr == nil { + logger.ConsumerLog.Debugf("Nudr_DataRepository Remove Influence Data Subscription Status %s", + httpResp.Status) + } else if httpResp != nil { + defer func() { + if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { + logger.ConsumerLog.Errorf("RemoveInfluenceDataSubscription response body cannot close: %+v", + rspCloseErr) + } + }() + if httpResp.Status != localErr.Error() { + err = localErr + return problemDetails, err + } + problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) + problemDetails = &problem + } else { + err = openapi.ReportError("server no response") + } + return problemDetails, err +} diff --git a/pkg/service/init.go b/pkg/service/init.go index 07c4d03..a6cef23 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -1,12 +1,14 @@ package service import ( + "context" "fmt" "io" "os" "os/signal" "runtime/debug" "syscall" + // "sync" "github.com/antihax/optional" "github.com/gin-contrib/cors" @@ -33,6 +35,10 @@ import ( type PcfApp struct { cfg *factory.Config pcfCtx *pcf_context.PCFContext + ctx context.Context + cancel context.CancelFunc + + consumer *consumer.Consumer } func NewApp(cfg *factory.Config) (*PcfApp, error) { @@ -43,9 +49,32 @@ func NewApp(cfg *factory.Config) (*PcfApp, error) { pcf_context.Init() pcf.pcfCtx = pcf_context.GetSelf() + + //consumer + consumer, err := consumer.NewConsumer(pcf) + if err != nil { + return pcf, err + } + pcf.consumer = consumer return pcf, nil } +func (a *PcfApp) Config() *factory.Config { + return a.cfg +} + +func (a *PcfApp) Context() *pcf_context.PCFContext { + return a.pcfCtx +} + +func (a *PcfApp) CancelContext() context.Context { + return a.ctx +} + +func (a *PcfApp) Consumer() *consumer.Consumer { + return a.consumer +} + func (a *PcfApp) SetLogEnable(enable bool) { logger.MainLog.Infof("Log enable is set to [%v]", enable) if enable && logger.Log.Out == os.Stderr { From f64594465dbfe63aeb825156a6fbbaf5e7a20948 Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Fri, 3 May 2024 07:37:07 +0000 Subject: [PATCH 03/20] refactor: server part moving service outside --- .gitignore | 1 + internal/logger/logger.go | 2 + internal/sbi/ampolicy/routers.go | 113 ------- .../api_default.go => api_ampolicy.go} | 50 ++- ...y_document_routers.go => api_bdtpolicy.go} | 79 ++++- ...m_policy_notify.go => api_httpcallback.go} | 79 ++++- .../{oam/api_get_am_policy.go => api_oam.go} | 18 +- internal/sbi/api_policyauthorization.go | 319 ++++++++++++++++++ .../api_default.go => api_smpolicy.go} | 35 +- internal/sbi/api_uepolicy.go | 57 ++++ .../api_bdt_policies_collection_routers.go | 76 ----- internal/sbi/bdtpolicy/routers.go | 109 ------ internal/sbi/consumer/communication.go | 60 ---- .../sbi/consumer/influenceDataSubscription.go | 103 ------ internal/sbi/consumer/nf_discovery.go | 118 ------- internal/sbi/consumer/nf_management.go | 143 -------- .../httpcallback/amf_status_change_notify.go | 64 ---- internal/sbi/httpcallback/router.go | 81 ----- internal/sbi/oam/routers.go | 74 ---- .../api_application_sessions_collection.go | 82 ----- .../api_events_subscription_document.go | 100 ------ ...al_application_session_context_document.go | 144 -------- internal/sbi/policyauthorization/routers.go | 127 ------- internal/sbi/server.go | 273 +++++++++++++++ internal/sbi/smpolicy/routers.go | 105 ------ internal/sbi/uepolicy/api_default.go | 30 -- internal/sbi/uepolicy/routers.go | 97 ------ pkg/factory/config.go | 54 +++ pkg/service/init.go | 163 +++------ 29 files changed, 993 insertions(+), 1763 deletions(-) delete mode 100644 internal/sbi/ampolicy/routers.go rename internal/sbi/{ampolicy/api_default.go => api_ampolicy.go} (83%) rename internal/sbi/{bdtpolicy/api_individual_bdt_policy_document_routers.go => api_bdtpolicy.go} (56%) rename internal/sbi/{httpcallback/sm_policy_notify.go => api_httpcallback.go} (59%) rename internal/sbi/{oam/api_get_am_policy.go => api_oam.go} (79%) create mode 100644 internal/sbi/api_policyauthorization.go rename internal/sbi/{smpolicy/api_default.go => api_smpolicy.go} (84%) create mode 100644 internal/sbi/api_uepolicy.go delete mode 100644 internal/sbi/bdtpolicy/api_bdt_policies_collection_routers.go delete mode 100644 internal/sbi/bdtpolicy/routers.go delete mode 100644 internal/sbi/consumer/communication.go delete mode 100644 internal/sbi/consumer/influenceDataSubscription.go delete mode 100644 internal/sbi/consumer/nf_discovery.go delete mode 100644 internal/sbi/consumer/nf_management.go delete mode 100644 internal/sbi/httpcallback/amf_status_change_notify.go delete mode 100644 internal/sbi/httpcallback/router.go delete mode 100644 internal/sbi/oam/routers.go delete mode 100644 internal/sbi/policyauthorization/api_application_sessions_collection.go delete mode 100644 internal/sbi/policyauthorization/api_events_subscription_document.go delete mode 100644 internal/sbi/policyauthorization/api_individual_application_session_context_document.go delete mode 100644 internal/sbi/policyauthorization/routers.go create mode 100644 internal/sbi/server.go delete mode 100644 internal/sbi/smpolicy/routers.go delete mode 100644 internal/sbi/uepolicy/api_default.go delete mode 100644 internal/sbi/uepolicy/routers.go diff --git a/.gitignore b/.gitignore index c294e4d..b457816 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/bin/ # Swap files *.swp diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 6ffbf16..d628c7d 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -14,6 +14,7 @@ var ( CfgLog *logrus.Entry CtxLog *logrus.Entry GinLog *logrus.Entry + SBILog *logrus.Entry AmPolicyLog *logrus.Entry BdtPolicyLog *logrus.Entry ConsumerLog *logrus.Entry @@ -38,6 +39,7 @@ func init() { CfgLog = NfLog.WithField(logger_util.FieldCategory, "CFG") CtxLog = NfLog.WithField(logger_util.FieldCategory, "CTX") GinLog = NfLog.WithField(logger_util.FieldCategory, "GIN") + SBILog = NfLog.WithField(logger_util.FieldCategory, "SBI") AmPolicyLog = NfLog.WithField(logger_util.FieldCategory, "AmPol") BdtPolicyLog = NfLog.WithField(logger_util.FieldCategory, "BdtPol") ConsumerLog = NfLog.WithField(logger_util.FieldCategory, "Consumer") diff --git a/internal/sbi/ampolicy/routers.go b/internal/sbi/ampolicy/routers.go deleted file mode 100644 index f32ed29..0000000 --- a/internal/sbi/ampolicy/routers.go +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Npcf_AMPolicyControl - * - * Access and Mobility Policy Control Service API - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package ampolicy - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/pcf/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -// Route is the information for every URI. -type Route struct { - // Name is the name of this Route. - Name string - // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string - // Pattern is the pattern of the URI. - Pattern string - // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc -} - -// Routes is the list of the generated Route. -type Routes []Route - -// NewRouter returns a new router. -func NewRouter() *gin.Engine { - router := logger_util.NewGinWithLogrus(logger.GinLog) - AddService(router) - return router -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.PcfAMpolicyCtlResUriPrefix) - - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_AM_POLICY_CONTROL) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, pcf_context.GetSelf()) - }) - - for _, route := range routes { - switch route.Method { - case "GET": - group.GET(route.Pattern, route.HandlerFunc) - case "POST": - group.POST(route.Pattern, route.HandlerFunc) - case "PUT": - group.PUT(route.Pattern, route.HandlerFunc) - case "DELETE": - group.DELETE(route.Pattern, route.HandlerFunc) - case "PATCH": - group.PATCH(route.Pattern, route.HandlerFunc) - } - } - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "/", - Index, - }, - - { - "HTTPPoliciesPolAssoIdDelete", - strings.ToUpper("Delete"), - "/policies/:polAssoId", - HTTPPoliciesPolAssoIdDelete, - }, - - { - "HTTPPoliciesPolAssoIdGet", - strings.ToUpper("Get"), - "/policies/:polAssoId", - HTTPPoliciesPolAssoIdGet, - }, - - { - "HTTPPoliciesPolAssoIdUpdatePost", - strings.ToUpper("Post"), - "/policies/:polAssoId/update", - HTTPPoliciesPolAssoIdUpdatePost, - }, - - { - "HTTPPoliciesPost", - strings.ToUpper("Post"), - "/policies", - HTTPPoliciesPost, - }, -} diff --git a/internal/sbi/ampolicy/api_default.go b/internal/sbi/api_ampolicy.go similarity index 83% rename from internal/sbi/ampolicy/api_default.go rename to internal/sbi/api_ampolicy.go index e980b0d..c734619 100644 --- a/internal/sbi/ampolicy/api_default.go +++ b/internal/sbi/api_ampolicy.go @@ -1,13 +1,4 @@ -/* - * Npcf_AMPolicyControl - * - * Access and Mobility Policy Control Service API - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package ampolicy +package sbi import ( "net/http" @@ -22,7 +13,7 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func HTTPPoliciesPolAssoIdDelete(c *gin.Context) { +func (s *Server) HTTPPoliciesPolAssoIdDelete(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["polAssoId"], _ = c.Params.Get("polAssoId") @@ -43,7 +34,7 @@ func HTTPPoliciesPolAssoIdDelete(c *gin.Context) { } // HTTPPoliciesPolAssoIdGet - -func HTTPPoliciesPolAssoIdGet(c *gin.Context) { +func (s *Server) HTTPPoliciesPolAssoIdGet(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["polAssoId"], _ = c.Params.Get("polAssoId") @@ -64,7 +55,7 @@ func HTTPPoliciesPolAssoIdGet(c *gin.Context) { } // HTTPPoliciesPolAssoIdUpdatePost - -func HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { +func (s *Server) HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { var policyAssociationUpdateRequest models.PolicyAssociationUpdateRequest requestBody, err := c.GetRawData() @@ -113,7 +104,7 @@ func HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { } // HTTPPoliciesPost - -func HTTPPoliciesPost(c *gin.Context) { +func (s *Server) HTTPPoliciesPost(c *gin.Context) { var policyAssociationRequest models.PolicyAssociationRequest requestBody, err := c.GetRawData() @@ -171,3 +162,34 @@ func HTTPPoliciesPost(c *gin.Context) { c.Data(rsp.Status, "application/json", responseBody) } } + +func (s *Server) getAmPolicyEndpoints() []Endpoint { + return []Endpoint{ + + { + Method: http.MethodGet, + Pattern: "/policies/:polAssoId", + APIFunc: s.HTTPPoliciesPolAssoIdGet, + }, + { + Method: http.MethodDelete, + Pattern: "/policies/:polAssoId", + APIFunc: s.HTTPPoliciesPolAssoIdDelete, + }, + { + Method: http.MethodGet, + Pattern: "/policies/:polAssoId", + APIFunc: s.HTTPPoliciesPolAssoIdGet, + }, + { + Method: http.MethodPost, + Pattern: "/policies/:polAssoId/update", + APIFunc: s.HTTPPoliciesPolAssoIdUpdatePost, + }, + { + Method: http.MethodPost, + Pattern: "/policies", + APIFunc: s.HTTPPoliciesPost, + }, + } +} diff --git a/internal/sbi/bdtpolicy/api_individual_bdt_policy_document_routers.go b/internal/sbi/api_bdtpolicy.go similarity index 56% rename from internal/sbi/bdtpolicy/api_individual_bdt_policy_document_routers.go rename to internal/sbi/api_bdtpolicy.go index 3f1f061..0943a7a 100644 --- a/internal/sbi/bdtpolicy/api_individual_bdt_policy_document_routers.go +++ b/internal/sbi/api_bdtpolicy.go @@ -10,7 +10,7 @@ * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ -package bdtpolicy +package sbi import ( "net/http" @@ -24,8 +24,81 @@ import ( "github.com/free5gc/util/httpwrapper" ) +func (s *Server) getBdtPolicyEndPoints() []Endpoint { + return []Endpoint{ + { + Method: http.MethodPost, + Pattern: "/bdtpolicies", + APIFunc: s.HTTPCreateBDTPolicy, + }, + { + Method: http.MethodGet, + Pattern: "/bdtpolicies/:bdtPolicyId", + APIFunc: s.HTTPGetBDTPolicy, + }, + { + Method: http.MethodPatch, + Pattern: "/bdtpolicies/:bdtPolicyId", + APIFunc: s.HTTPUpdateBDTPolicy, + }, + } +} + +// api_bdt_policy +// CreateBDTPolicy - Create a new Individual BDT policy +func (s *Server) HTTPCreateBDTPolicy(c *gin.Context) { + var bdtReqData models.BdtReqData + // step 1: retrieve http request body + requestBody, err := c.GetRawData() + if err != nil { + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + logger.BdtPolicyLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&bdtReqData, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.BdtPolicyLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + req := httpwrapper.NewRequest(c.Request, bdtReqData) + rsp := producer.HandleCreateBDTPolicyContextRequest(req) + // step 5: response + for key, val := range rsp.Header { // header response is optional + c.Header(key, val[0]) + } + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.BdtPolicyLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } +} + +// api_individual // GetBDTPolicy - Read an Individual BDT policy -func HTTPGetBDTPolicy(c *gin.Context) { +func (s *Server) HTTPGetBDTPolicy(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["bdtPolicyId"] = c.Params.ByName("bdtPolicyId") @@ -46,7 +119,7 @@ func HTTPGetBDTPolicy(c *gin.Context) { } // UpdateBDTPolicy - Update an Individual BDT policy -func HTTPUpdateBDTPolicy(c *gin.Context) { +func (s *Server) HTTPUpdateBDTPolicy(c *gin.Context) { var bdtPolicyDataPatch models.BdtPolicyDataPatch // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/httpcallback/sm_policy_notify.go b/internal/sbi/api_httpcallback.go similarity index 59% rename from internal/sbi/httpcallback/sm_policy_notify.go rename to internal/sbi/api_httpcallback.go index be985ba..6021883 100644 --- a/internal/sbi/httpcallback/sm_policy_notify.go +++ b/internal/sbi/api_httpcallback.go @@ -1,4 +1,4 @@ -package httpcallback +package sbi import ( "net/http" @@ -12,8 +12,81 @@ import ( "github.com/free5gc/util/httpwrapper" ) +func (s *Server) getHttpCallBackEndpoints() []Endpoint { + return []Endpoint{ + { + Method: http.MethodPost, + Pattern: "/nudr-notify/policy-data/:supi", + APIFunc: s.HTTPUdrPolicyDataChangeNotify, + }, + { + Method: http.MethodPost, + Pattern: "/nudr-notify/influence-data/:supi/:pduSessionId", + APIFunc: s.HTTPUdrInfluenceDataUpdateNotify, + }, + { + Method: http.MethodPost, + Pattern: "/amfstatus", + APIFunc: s.HTTPAmfStatusChangeNotify, + }, + } +} + +// amf_status_change +func (s *Server) HTTPAmfStatusChangeNotify(c *gin.Context) { + var amfStatusChangeNotification models.AmfStatusChangeNotification + + requestBody, err := c.GetRawData() + if err != nil { + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + logger.CallbackLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&amfStatusChangeNotification, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.CallbackLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + req := httpwrapper.NewRequest(c.Request, amfStatusChangeNotification) + + rsp := producer.HandleAmfStatusChangeNotify(req) + + if rsp.Status == http.StatusNoContent { + c.Status(rsp.Status) + } else { + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.CallbackLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } + } +} + +// sm_policy_notify // Nudr-Notify-smpolicy -func HTTPUdrPolicyDataChangeNotify(c *gin.Context) { +func (s *Server) HTTPUdrPolicyDataChangeNotify(c *gin.Context) { var policyDataChangeNotification models.PolicyDataChangeNotification requestBody, err := c.GetRawData() @@ -62,7 +135,7 @@ func HTTPUdrPolicyDataChangeNotify(c *gin.Context) { } // Influence Data Update Notification -func HTTPUdrInfluenceDataUpdateNotify(c *gin.Context) { +func (s *Server) HTTPUdrInfluenceDataUpdateNotify(c *gin.Context) { var trafficInfluDataNotif []models.TrafficInfluDataNotif requestBody, err := c.GetRawData() diff --git a/internal/sbi/oam/api_get_am_policy.go b/internal/sbi/api_oam.go similarity index 79% rename from internal/sbi/oam/api_get_am_policy.go rename to internal/sbi/api_oam.go index 88f9e7b..d4b0272 100644 --- a/internal/sbi/oam/api_get_am_policy.go +++ b/internal/sbi/api_oam.go @@ -1,4 +1,4 @@ -package oam +package sbi import ( "net/http" @@ -12,7 +12,7 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func setCorsHeader(c *gin.Context) { +func (s *Server) setCorsHeader(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set( @@ -21,8 +21,8 @@ func setCorsHeader(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, PATCH, DELETE") } -func HTTPOAMGetAmPolicy(c *gin.Context) { - setCorsHeader(c) +func (s *Server) HTTPOAMGetAmPolicy(c *gin.Context) { + s.setCorsHeader(c) req := httpwrapper.NewRequest(c.Request, nil) req.Params["supi"] = c.Params.ByName("supi") @@ -42,3 +42,13 @@ func HTTPOAMGetAmPolicy(c *gin.Context) { c.Data(rsp.Status, "application/json", responseBody) } } + +func (s *Server) getOamEndpoints() []Endpoint { + return []Endpoint{ + { + Method: http.MethodGet, + Pattern: "/am-policy/:supi", + APIFunc: s.HTTPOAMGetAmPolicy, + }, + } +} diff --git a/internal/sbi/api_policyauthorization.go b/internal/sbi/api_policyauthorization.go new file mode 100644 index 0000000..572cfa1 --- /dev/null +++ b/internal/sbi/api_policyauthorization.go @@ -0,0 +1,319 @@ +/* + * Npcf_PolicyAuthorization Service API + * + * This is the Policy Authorization Service + * + * API version: 1.0.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package sbi + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/pcf/internal/logger" + "github.com/free5gc/pcf/internal/sbi/producer" + "github.com/free5gc/pcf/internal/util" + "github.com/free5gc/util/httpwrapper" +) + +func (s *Server) getPolicyAuthorizationEndpoints() []Endpoint { + return []Endpoint{ + { + Method: http.MethodPost, + Pattern: "/app-sessions", + APIFunc: s.HTTPPostAppSessions, + }, + { + Method: http.MethodDelete, + Pattern: "/app-sessions/:appSessionId/events-subscription", + APIFunc: s.HTTPDeleteEventsSubsc, + }, + { + Method: http.MethodPut, + Pattern: "/app-sessions/:appSessionId/events-subscription", + APIFunc: s.HTTPUpdateEventsSubsc, + }, + { + Method: http.MethodPost, + Pattern: "/app-sessions/:appSessionId/delete", + APIFunc: s.HTTPDeleteAppSession, + }, + { + Method: http.MethodGet, + Pattern: "/app-sessions/:appSessionId", + APIFunc: s.HTTPGetAppSession, + }, + { + Method: http.MethodPatch, + Pattern: "/app-sessions/:appSessionId", + APIFunc: s.HTTPModAppSession, + }, + } +} + +// api_application_session +// HTTPPostAppSessions - Creates a new Individual Application Session Context resource +func (s *Server) HTTPPostAppSessions(c *gin.Context) { + var appSessionContext models.AppSessionContext + + requestBody, err := c.GetRawData() + if err != nil { + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&appSessionContext, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.PolicyAuthLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + ascReqData := appSessionContext.AscReqData + if ascReqData == nil || ascReqData.SuppFeat == "" || ascReqData.NotifUri == "" { + // Check Mandatory IEs + rsp := util.GetProblemDetail("Errorneous/Missing Mandotory IE", util.ERROR_INITIAL_PARAMETERS) + logger.PolicyAuthLog.Errorln(rsp.Detail) + c.JSON(int(rsp.Status), rsp) + return + } + + req := httpwrapper.NewRequest(c.Request, appSessionContext) + rsp := producer.HandlePostAppSessionsContext(req) + + for key, val := range rsp.Header { + c.Header(key, val[0]) + } + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.PolicyAuthLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } +} + +// api_events_subscription +// HTTPDeleteEventsSubsc - deletes the Events Subscription subresource +func (s *Server) HTTPDeleteEventsSubsc(c *gin.Context) { + req := httpwrapper.NewRequest(c.Request, nil) + req.Params["appSessionId"], _ = c.Params.Get("appSessionId") + + rsp := producer.HandleDeleteEventsSubscContext(req) + + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.PolicyAuthLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } +} + +// HTTPUpdateEventsSubsc - creates or modifies an Events Subscription subresource +func (s *Server) HTTPUpdateEventsSubsc(c *gin.Context) { + var eventsSubscReqData models.EventsSubscReqData + + requestBody, err := c.GetRawData() + if err != nil { + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&eventsSubscReqData, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.PolicyAuthLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + if eventsSubscReqData.Events == nil || eventsSubscReqData.NotifUri == "" { + problemDetail := util.GetProblemDetail("Errorneous/Missing Mandotory IE", util.ERROR_REQUEST_PARAMETERS) + logger.PolicyAuthLog.Errorln(problemDetail.Detail) + c.JSON(int(problemDetail.Status), problemDetail) + return + } + + req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) + req.Params["appSessionId"], _ = c.Params.Get("appSessionId") + + rsp := producer.HandleUpdateEventsSubscContext(req) + + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.PolicyAuthLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } +} + +// api_individual +// HTTPDeleteAppSession - Deletes an existing Individual Application Session Context +func (s *Server) HTTPDeleteAppSession(c *gin.Context) { + var eventsSubscReqData *models.EventsSubscReqData + + requestBody, err := c.GetRawData() + if err != nil { + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // EventsSubscReqData is Optional + if len(requestBody) > 0 { + err = openapi.Deserialize(&eventsSubscReqData, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.PolicyAuthLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + } + + req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) + req.Params["appSessionId"], _ = c.Params.Get("appSessionId") + + rsp := producer.HandleDeleteAppSessionContext(req) + + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.PolicyAuthLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } +} + +// HTTPGetAppSession - Reads an existing Individual Application Session Context +func (s *Server) HTTPGetAppSession(c *gin.Context) { + req := httpwrapper.NewRequest(c.Request, nil) + req.Params["appSessionId"], _ = c.Params.Get("appSessionId") + + rsp := producer.HandleGetAppSessionContext(req) + + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.PolicyAuthLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } +} + +// HTTPModAppSession - Modifies an existing Individual Application Session Context +func (s *Server) HTTPModAppSession(c *gin.Context) { + var appSessionContextUpdateData models.AppSessionContextUpdateData + + requestBody, err := c.GetRawData() + if err != nil { + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&appSessionContextUpdateData, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.PolicyAuthLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + req := httpwrapper.NewRequest(c.Request, appSessionContextUpdateData) + req.Params["appSessionId"], _ = c.Params.Get("appSessionId") + + rsp := producer.HandleModAppSessionContext(req) + + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.PolicyAuthLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } +} diff --git a/internal/sbi/smpolicy/api_default.go b/internal/sbi/api_smpolicy.go similarity index 84% rename from internal/sbi/smpolicy/api_default.go rename to internal/sbi/api_smpolicy.go index 417068f..590358e 100644 --- a/internal/sbi/smpolicy/api_default.go +++ b/internal/sbi/api_smpolicy.go @@ -7,7 +7,7 @@ * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ -package smpolicy +package sbi import ( "net/http" @@ -21,8 +21,33 @@ import ( "github.com/free5gc/util/httpwrapper" ) +func (s *Server) getSmPolicyEndpoints() []Endpoint { + return []Endpoint{ + { + Method: http.MethodPost, + Pattern: "/sm-policies", + APIFunc: s.HTTPSmPoliciesPost, + }, + { + Method: http.MethodPost, + Pattern: "/sm-policies/:smPolicyId/delete", + APIFunc: s.HTTPSmPoliciesSmPolicyIdDeletePost, + }, + { + Method: http.MethodGet, + Pattern: "/sm-policies/:smPolicyId", + APIFunc: s.HTTPSmPoliciesSmPolicyIDGet, + }, + { + Method: http.MethodPost, + Pattern: "/sm-policies/:smPolicyId/update", + APIFunc: s.HTTPSmPoliciesSmPolicyIdUpdatePost, + }, + } +} + // SmPoliciesPost - -func HTTPSmPoliciesPost(c *gin.Context) { +func (s *Server) HTTPSmPoliciesPost(c *gin.Context) { var smPolicyContextData models.SmPolicyContextData // step 1: retrieve http request body requestBody, err := c.GetRawData() @@ -74,7 +99,7 @@ func HTTPSmPoliciesPost(c *gin.Context) { } // SmPoliciesSmPolicyIdDeletePost - -func HTTPSmPoliciesSmPolicyIdDeletePost(c *gin.Context) { +func (s *Server) HTTPSmPoliciesSmPolicyIdDeletePost(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") @@ -95,7 +120,7 @@ func HTTPSmPoliciesSmPolicyIdDeletePost(c *gin.Context) { } // SmPoliciesSmPolicyIdGet - -func HTTPSmPoliciesSmPolicyIDGet(c *gin.Context) { +func (s *Server) HTTPSmPoliciesSmPolicyIDGet(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") @@ -116,7 +141,7 @@ func HTTPSmPoliciesSmPolicyIDGet(c *gin.Context) { } // SmPoliciesSmPolicyIdUpdatePost - -func HTTPSmPoliciesSmPolicyIdUpdatePost(c *gin.Context) { +func (s *Server) HTTPSmPoliciesSmPolicyIdUpdatePost(c *gin.Context) { var smPolicyUpdateContextData models.SmPolicyUpdateContextData // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/api_uepolicy.go b/internal/sbi/api_uepolicy.go new file mode 100644 index 0000000..b0f72df --- /dev/null +++ b/internal/sbi/api_uepolicy.go @@ -0,0 +1,57 @@ +/* + * Npcf_UEPolicyControl + * + * UE Policy Control Service API + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package sbi + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (s *Server) getUePolicyEndpoints() []Endpoint { + return []Endpoint{ + { + Method: http.MethodDelete, + Pattern: "/policies/{polAssoId}", + APIFunc: s.PoliciesPolAssoIdDelete, + }, + { + Method: http.MethodGet, + Pattern: "/policies/{polAssoId}", + APIFunc: s.PoliciesPolAssoIdGet, + }, + { + Method: http.MethodPost, + Pattern: "/policies/{polAssoId}/update", + APIFunc: s.PoliciesPolAssoIdUpdatePost, + }, + { + Method: http.MethodPost, + Pattern: "/policies", + APIFunc: s.PoliciesPost, + }, + } +} + +// PoliciesPolAssoIdDelete - +func (s *Server) PoliciesPolAssoIdDelete(c *gin.Context) { +} + +// PoliciesPolAssoIdGet - +func (s *Server) PoliciesPolAssoIdGet(c *gin.Context) { +} + +// PoliciesPolAssoIdUpdatePost - +func (s *Server) PoliciesPolAssoIdUpdatePost(c *gin.Context) { +} + +// PoliciesPost - +func (s *Server) PoliciesPost(c *gin.Context) { +} diff --git a/internal/sbi/bdtpolicy/api_bdt_policies_collection_routers.go b/internal/sbi/bdtpolicy/api_bdt_policies_collection_routers.go deleted file mode 100644 index 7f636d6..0000000 --- a/internal/sbi/bdtpolicy/api_bdt_policies_collection_routers.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Npcf_BDTPolicyControl Service API - * - * The Npcf_BDTPolicyControl Service is used by an NF service consumer to - * retrieve background data transfer policies from the PCF and to update - * the PCF with the background data transfer policy selected by the NF - * service consumer. - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package bdtpolicy - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// CreateBDTPolicy - Create a new Individual BDT policy -func HTTPCreateBDTPolicy(c *gin.Context) { - var bdtReqData models.BdtReqData - // step 1: retrieve http request body - requestBody, err := c.GetRawData() - if err != nil { - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - logger.BdtPolicyLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&bdtReqData, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.BdtPolicyLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, bdtReqData) - rsp := producer.HandleCreateBDTPolicyContextRequest(req) - // step 5: response - for key, val := range rsp.Header { // header response is optional - c.Header(key, val[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.BdtPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } -} diff --git a/internal/sbi/bdtpolicy/routers.go b/internal/sbi/bdtpolicy/routers.go deleted file mode 100644 index 5c1b719..0000000 --- a/internal/sbi/bdtpolicy/routers.go +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Npcf_BDTPolicyControl Service API - * - * The Npcf_BDTPolicyControl Service is used by an NF service consumer to - * retrieve background data transfer policies from the PCF and to update - * the PCF with the background data transfer policy selected by the NF - * service consumer. - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package bdtpolicy - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/pcf/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -// Route is the information for every URI. -type Route struct { - // Name is the name of this Route. - Name string - // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string - // Pattern is the pattern of the URI. - Pattern string - // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc -} - -// Routes is the list of the generated Route. -type Routes []Route - -// NewRouter returns a new router. -func NewRouter() *gin.Engine { - router := logger_util.NewGinWithLogrus(logger.GinLog) - AddService(router) - return router -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.PcfBdtPolicyCtlResUriPrefix) - - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_BDTPOLICYCONTROL) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, pcf_context.GetSelf()) - }) - - for _, route := range routes { - switch route.Method { - case "GET": - group.GET(route.Pattern, route.HandlerFunc) - case "POST": - group.POST(route.Pattern, route.HandlerFunc) - case "PUT": - group.PUT(route.Pattern, route.HandlerFunc) - case "DELETE": - group.DELETE(route.Pattern, route.HandlerFunc) - case "PATCH": - group.PATCH(route.Pattern, route.HandlerFunc) - } - } - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "/", - Index, - }, - - { - "CreateBDTPolicy", - strings.ToUpper("Post"), - "/bdtpolicies", - HTTPCreateBDTPolicy, - }, - - { - "GetBDTPolicy", - strings.ToUpper("Get"), - "/bdtpolicies/:bdtPolicyId", - HTTPGetBDTPolicy, - }, - - { - "UpdateBDTPolicy", - strings.ToUpper("Patch"), - "/bdtpolicies/:bdtPolicyId", - HTTPUpdateBDTPolicy, - }, -} diff --git a/internal/sbi/consumer/communication.go b/internal/sbi/consumer/communication.go deleted file mode 100644 index f7060b8..0000000 --- a/internal/sbi/consumer/communication.go +++ /dev/null @@ -1,60 +0,0 @@ -package consumer - -import ( - "fmt" - "strings" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/pcf/pkg/factory" -) - -func AmfStatusChangeSubscribe(amfUri string, guamiList []models.Guami) ( - problemDetails *models.ProblemDetails, err error, -) { - logger.ConsumerLog.Debugf("PCF Subscribe to AMF status[%+v]", amfUri) - pcfSelf := pcf_context.GetSelf() - client := util.GetNamfClient(amfUri) - - subscriptionData := models.SubscriptionData{ - AmfStatusUri: fmt.Sprintf("%s"+factory.PcfCallbackResUriPrefix+"/amfstatus", pcfSelf.GetIPv4Uri()), - GuamiList: guamiList, - } - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) - if err != nil { - return pd, err - } - res, httpResp, localErr := client.SubscriptionsCollectionDocumentApi.AMFStatusChangeSubscribe( - ctx, subscriptionData) - defer func() { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("AMFStatusChangeSubscribe response body cannot close: %+v", - rspCloseErr) - } - }() - if localErr == nil { - locationHeader := httpResp.Header.Get("Location") - logger.ConsumerLog.Debugf("location header: %+v", locationHeader) - - subscriptionID := locationHeader[strings.LastIndex(locationHeader, "/")+1:] - amfStatusSubsData := pcf_context.AMFStatusSubscriptionData{ - AmfUri: amfUri, - AmfStatusUri: res.AmfStatusUri, - GuamiList: res.GuamiList, - } - pcfSelf.NewAmfStatusSubscription(subscriptionID, amfStatusSubsData) - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return nil, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("%s: server no response", amfUri) - } - return problemDetails, err -} diff --git a/internal/sbi/consumer/influenceDataSubscription.go b/internal/sbi/consumer/influenceDataSubscription.go deleted file mode 100644 index 6a873f9..0000000 --- a/internal/sbi/consumer/influenceDataSubscription.go +++ /dev/null @@ -1,103 +0,0 @@ -package consumer - -import ( - "strconv" - "strings" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/util" -) - -func CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.SmPolicyContextData) ( - subscriptionID string, problemDetails *models.ProblemDetails, err error, -) { - if ue.UdrUri == "" { - problemDetail := util.GetProblemDetail("Can't find corresponding UDR with UE", util.USER_UNKNOWN) - logger.ConsumerLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) - return "", &problemDetail, nil - } - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return "", pd, err - } - udrClient := util.GetNudrClient(ue.UdrUri) - trafficInfluSub := buildTrafficInfluSub(request) - _, httpResp, localErr := udrClient.InfluenceDataSubscriptionsCollectionApi. - ApplicationDataInfluenceDataSubsToNotifyPost(ctx, trafficInfluSub) - if localErr == nil { - locationHeader := httpResp.Header.Get("Location") - subscriptionID = locationHeader[strings.LastIndex(locationHeader, "/")+1:] - logger.ConsumerLog.Debugf("Influence Data Subscription ID: %s", subscriptionID) - return subscriptionID, nil, nil - } else if httpResp != nil { - defer func() { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("CreateInfluenceDataSubscription response body cannot close: %+v", - rspCloseErr) - } - }() - if httpResp.Status != localErr.Error() { - err = localErr - return subscriptionID, problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("server no response") - } - return "", problemDetails, err -} - -func buildTrafficInfluSub(request models.SmPolicyContextData) models.TrafficInfluSub { - trafficInfluSub := models.TrafficInfluSub{ - Dnns: []string{request.Dnn}, - Snssais: []models.Snssai{*request.SliceInfo}, - InternalGroupIds: request.InterGrpIds, - Supis: []string{request.Supi}, - NotificationUri: pcf_context.GetSelf().GetIPv4Uri() + - pcf_context.InfluenceDataUpdateNotifyUri + "/" + - request.Supi + "/" + strconv.Itoa(int(request.PduSessionId)), - // TODO: support expiry time and resend subscription when expired - } - return trafficInfluSub -} - -func RemoveInfluenceDataSubscription(ue *pcf_context.UeContext, subscriptionID string) ( - problemDetails *models.ProblemDetails, err error, -) { - if ue.UdrUri == "" { - problemDetail := util.GetProblemDetail("Can't find corresponding UDR with UE", util.USER_UNKNOWN) - logger.ConsumerLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) - return &problemDetail, nil - } - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd, err - } - udrClient := util.GetNudrClient(ue.UdrUri) - httpResp, localErr := udrClient.IndividualInfluenceDataSubscriptionDocumentApi. - ApplicationDataInfluenceDataSubsToNotifySubscriptionIdDelete(ctx, subscriptionID) - if localErr == nil { - logger.ConsumerLog.Debugf("Nudr_DataRepository Remove Influence Data Subscription Status %s", - httpResp.Status) - } else if httpResp != nil { - defer func() { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("RemoveInfluenceDataSubscription response body cannot close: %+v", - rspCloseErr) - } - }() - if httpResp.Status != localErr.Error() { - err = localErr - return problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("server no response") - } - return problemDetails, err -} diff --git a/internal/sbi/consumer/nf_discovery.go b/internal/sbi/consumer/nf_discovery.go deleted file mode 100644 index 224c589..0000000 --- a/internal/sbi/consumer/nf_discovery.go +++ /dev/null @@ -1,118 +0,0 @@ -package consumer - -import ( - "fmt" - "net/http" - - "github.com/antihax/optional" - - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/util" -) - -func SendSearchNFInstances( - nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( - *models.SearchResult, error, -) { - // Set client and set url - configuration := Nnrf_NFDiscovery.NewConfiguration() - configuration.SetBasePath(nrfUri) - client := Nnrf_NFDiscovery.NewAPIClient(configuration) - - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) - if err != nil { - return nil, err - } - - result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, ¶m) - if err != nil { - logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err) - } - defer func() { - if resCloseErr := res.Body.Close(); resCloseErr != nil { - logger.ConsumerLog.Errorf("NFInstancesStoreApi response body cannot close: %+v", resCloseErr) - } - }() - if res != nil && res.StatusCode == http.StatusTemporaryRedirect { - return nil, fmt.Errorf("Temporary Redirect For Non NRF Consumer") - } - - return &result, nil -} - -func SendNFInstancesUDR(nrfUri, id string) string { - targetNfType := models.NfType_UDR - requestNfType := models.NfType_PCF - localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - // DataSet: optional.NewInterface(models.DataSetId_SUBSCRIPTION), - } - // switch types { - // case NFDiscoveryToUDRParamSupi: - // localVarOptionals.Supi = optional.NewString(id) - // case NFDiscoveryToUDRParamExtGroupId: - // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) - // case NFDiscoveryToUDRParamGpsi: - // localVarOptionals.Gpsi = optional.NewString(id) - // } - - result, err := SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) - if err != nil { - logger.ConsumerLog.Error(err.Error()) - return "" - } - for _, profile := range result.NfInstances { - if uri := util.SearchNFServiceUri(profile, models.ServiceName_NUDR_DR, models.NfServiceStatus_REGISTERED); uri != "" { - return uri - } - } - return "" -} - -func SendNFInstancesBSF(nrfUri string) string { - targetNfType := models.NfType_BSF - requestNfType := models.NfType_PCF - localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{} - - result, err := SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) - if err != nil { - logger.ConsumerLog.Error(err.Error()) - return "" - } - for _, profile := range result.NfInstances { - if uri := util.SearchNFServiceUri(profile, models.ServiceName_NBSF_MANAGEMENT, - models.NfServiceStatus_REGISTERED); uri != "" { - return uri - } - } - return "" -} - -func SendNFInstancesAMF(nrfUri string, guami models.Guami, serviceName models.ServiceName) string { - targetNfType := models.NfType_AMF - requestNfType := models.NfType_PCF - - localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - Guami: optional.NewInterface(util.MarshToJsonString(guami)), - } - // switch types { - // case NFDiscoveryToUDRParamSupi: - // localVarOptionals.Supi = optional.NewString(id) - // case NFDiscoveryToUDRParamExtGroupId: - // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) - // case NFDiscoveryToUDRParamGpsi: - // localVarOptionals.Gpsi = optional.NewString(id) - // } - - result, err := SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) - if err != nil { - logger.ConsumerLog.Error(err.Error()) - return "" - } - for _, profile := range result.NfInstances { - return util.SearchNFServiceUri(profile, serviceName, models.NfServiceStatus_REGISTERED) - } - return "" -} diff --git a/internal/sbi/consumer/nf_management.go b/internal/sbi/consumer/nf_management.go deleted file mode 100644 index e0c00b3..0000000 --- a/internal/sbi/consumer/nf_management.go +++ /dev/null @@ -1,143 +0,0 @@ -package consumer - -import ( - "fmt" - "net/http" - "strings" - "time" - - "github.com/pkg/errors" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nnrf_NFManagement" - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" -) - -func BuildNFInstance(context *pcf_context.PCFContext) (profile models.NfProfile, err error) { - profile.NfInstanceId = context.NfId - profile.NfType = models.NfType_PCF - profile.NfStatus = models.NfStatus_REGISTERED - profile.Ipv4Addresses = append(profile.Ipv4Addresses, context.RegisterIPv4) - service := []models.NfService{} - for _, nfService := range context.NfService { - service = append(service, nfService) - } - profile.NfServices = &service - profile.PcfInfo = &models.PcfInfo{ - DnnList: []string{ - "free5gc", - "internet", - }, - // SupiRanges: &[]models.SupiRange{ - // { - // //from TS 29.510 6.1.6.2.9 example2 - // //no need to set supirange in this moment 2019/10/4 - // Start: "123456789040000", - // End: "123456789059999", - // Pattern: "^imsi-12345678904[0-9]{4}$", - // }, - // }, - } - if context.Locality != "" { - profile.Locality = context.Locality - } - return -} - -func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfile) ( - resouceNrfUri string, retrieveNfInstanceID string, err error, -) { - // Set client and set url - configuration := Nnrf_NFManagement.NewConfiguration() - configuration.SetBasePath(nrfUri) - apiClient := Nnrf_NFManagement.NewAPIClient(configuration) - - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) - if err != nil { - return "", "", - errors.Errorf("SendRegisterNFInstance error: %+v", err) - } - - var res *http.Response - var nf models.NfProfile - for { - nf, res, err = apiClient.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, nfInstanceId, profile) - if err != nil || res == nil { - // TODO : add log - fmt.Println(fmt.Errorf("PCF register to NRF Error[%v]", err.Error())) - time.Sleep(2 * time.Second) - continue - } - defer func() { - if resCloseErr := res.Body.Close(); resCloseErr != nil { - logger.ConsumerLog.Errorf("RegisterNFInstance response body cannot close: %+v", resCloseErr) - } - }() - status := res.StatusCode - if status == http.StatusOK { - // NFUpdate - break - } else if status == http.StatusCreated { - // NFRegister - resourceUri := res.Header.Get("Location") - resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")] - retrieveNfInstanceID = resourceUri[strings.LastIndex(resourceUri, "/")+1:] - - oauth2 := false - if nf.CustomInfo != nil { - v, ok := nf.CustomInfo["oauth2"].(bool) - if ok { - oauth2 = v - logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2) - } - } - pcf_context.GetSelf().OAuth2Required = oauth2 - - if oauth2 && pcf_context.GetSelf().NrfCertPem == "" { - logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") - } - break - } else { - fmt.Println("NRF return wrong status code", status) - } - } - return resouceNrfUri, retrieveNfInstanceID, err -} - -func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) { - logger.ConsumerLog.Infof("Send Deregister NFInstance") - - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) - if err != nil { - return pd, err - } - - pcfSelf := pcf_context.GetSelf() - // Set client and set url - configuration := Nnrf_NFManagement.NewConfiguration() - configuration.SetBasePath(pcfSelf.NrfUri) - client := Nnrf_NFManagement.NewAPIClient(configuration) - - var res *http.Response - - res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, pcfSelf.NfId) - if err == nil { - return nil, nil - } else if res != nil { - defer func() { - if resCloseErr := res.Body.Close(); resCloseErr != nil { - logger.ConsumerLog.Errorf("DeregisterNFInstance response cannot close: %+v", resCloseErr) - } - }() - if res.Status != err.Error() { - return nil, err - } - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("server no response") - } - return problemDetails, err -} diff --git a/internal/sbi/httpcallback/amf_status_change_notify.go b/internal/sbi/httpcallback/amf_status_change_notify.go deleted file mode 100644 index ce4ba71..0000000 --- a/internal/sbi/httpcallback/amf_status_change_notify.go +++ /dev/null @@ -1,64 +0,0 @@ -package httpcallback - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -func HTTPAmfStatusChangeNotify(c *gin.Context) { - var amfStatusChangeNotification models.AmfStatusChangeNotification - - requestBody, err := c.GetRawData() - if err != nil { - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - logger.CallbackLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&amfStatusChangeNotification, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.CallbackLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, amfStatusChangeNotification) - - rsp := producer.HandleAmfStatusChangeNotify(req) - - if rsp.Status == http.StatusNoContent { - c.Status(rsp.Status) - } else { - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.CallbackLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } - } -} diff --git a/internal/sbi/httpcallback/router.go b/internal/sbi/httpcallback/router.go deleted file mode 100644 index 435e770..0000000 --- a/internal/sbi/httpcallback/router.go +++ /dev/null @@ -1,81 +0,0 @@ -package httpcallback - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -// Route is the information for every URI. -type Route struct { - // Name is the name of this Route. - Name string - // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string - // Pattern is the pattern of the URI. - Pattern string - // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc -} - -// Routes is the list of the generated Route. -type Routes []Route - -// NewRouter returns a new router. -func NewRouter() *gin.Engine { - router := logger_util.NewGinWithLogrus(logger.GinLog) - AddService(router) - return router -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.PcfCallbackResUriPrefix) - - for _, route := range routes { - switch route.Method { - case "POST": - group.POST(route.Pattern, route.HandlerFunc) - } - } - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "/", - Index, - }, - - { - "HTTPUdrPolicyDataChangeNotify", - strings.ToUpper("Post"), - "/nudr-notify/policy-data/:supi", - HTTPUdrPolicyDataChangeNotify, - }, - - { - "HTTPUdrInfluenceDataUpdateNotify", - strings.ToUpper("Post"), - "/nudr-notify/influence-data/:supi/:pduSessionId", - HTTPUdrInfluenceDataUpdateNotify, - }, - - { - "HTTPAmfStatusChangeNotify", - strings.ToUpper("Post"), - "/amfstatus", - HTTPAmfStatusChangeNotify, - }, -} diff --git a/internal/sbi/oam/routers.go b/internal/sbi/oam/routers.go deleted file mode 100644 index 22091f5..0000000 --- a/internal/sbi/oam/routers.go +++ /dev/null @@ -1,74 +0,0 @@ -package oam - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/pcf/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -// Route is the information for every URI. -type Route struct { - // Name is the name of this Route. - Name string - // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string - // Pattern is the pattern of the URI. - Pattern string - // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc -} - -// Routes is the list of the generated Route. -type Routes []Route - -// NewRouter returns a new router. -func NewRouter() *gin.Engine { - router := logger_util.NewGinWithLogrus(logger.GinLog) - AddService(router) - return router -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.PcfOamResUriPrefix) - - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_OAM) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, pcf_context.GetSelf()) - }) - - for _, route := range routes { - switch route.Method { - case "GET": - group.GET(route.Pattern, route.HandlerFunc) - } - } - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - http.MethodGet, - "/", - Index, - }, - - { - "Get UE AM Policy Data", - http.MethodGet, - "/am-policy/:supi", - HTTPOAMGetAmPolicy, - }, -} diff --git a/internal/sbi/policyauthorization/api_application_sessions_collection.go b/internal/sbi/policyauthorization/api_application_sessions_collection.go deleted file mode 100644 index 3da7033..0000000 --- a/internal/sbi/policyauthorization/api_application_sessions_collection.go +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Npcf_PolicyAuthorization Service API - * - * This is the Policy Authorization Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package policyauthorization - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" - "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" -) - -// HTTPPostAppSessions - Creates a new Individual Application Session Context resource -func HTTPPostAppSessions(c *gin.Context) { - var appSessionContext models.AppSessionContext - - requestBody, err := c.GetRawData() - if err != nil { - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&appSessionContext, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.PolicyAuthLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - ascReqData := appSessionContext.AscReqData - if ascReqData == nil || ascReqData.SuppFeat == "" || ascReqData.NotifUri == "" { - // Check Mandatory IEs - rsp := util.GetProblemDetail("Errorneous/Missing Mandotory IE", util.ERROR_INITIAL_PARAMETERS) - logger.PolicyAuthLog.Errorln(rsp.Detail) - c.JSON(int(rsp.Status), rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, appSessionContext) - rsp := producer.HandlePostAppSessionsContext(req) - - for key, val := range rsp.Header { - c.Header(key, val[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } -} diff --git a/internal/sbi/policyauthorization/api_events_subscription_document.go b/internal/sbi/policyauthorization/api_events_subscription_document.go deleted file mode 100644 index ef76473..0000000 --- a/internal/sbi/policyauthorization/api_events_subscription_document.go +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Npcf_PolicyAuthorization Service API - * - * This is the Policy Authorization Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package policyauthorization - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" - "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" -) - -// HTTPDeleteEventsSubsc - deletes the Events Subscription subresource -func HTTPDeleteEventsSubsc(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := producer.HandleDeleteEventsSubscContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } -} - -// HTTPUpdateEventsSubsc - creates or modifies an Events Subscription subresource -func HTTPUpdateEventsSubsc(c *gin.Context) { - var eventsSubscReqData models.EventsSubscReqData - - requestBody, err := c.GetRawData() - if err != nil { - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&eventsSubscReqData, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.PolicyAuthLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - if eventsSubscReqData.Events == nil || eventsSubscReqData.NotifUri == "" { - problemDetail := util.GetProblemDetail("Errorneous/Missing Mandotory IE", util.ERROR_REQUEST_PARAMETERS) - logger.PolicyAuthLog.Errorln(problemDetail.Detail) - c.JSON(int(problemDetail.Status), problemDetail) - return - } - - req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := producer.HandleUpdateEventsSubscContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } -} diff --git a/internal/sbi/policyauthorization/api_individual_application_session_context_document.go b/internal/sbi/policyauthorization/api_individual_application_session_context_document.go deleted file mode 100644 index 42398dd..0000000 --- a/internal/sbi/policyauthorization/api_individual_application_session_context_document.go +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Npcf_PolicyAuthorization Service API - * - * This is the Policy Authorization Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package policyauthorization - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// HTTPDeleteAppSession - Deletes an existing Individual Application Session Context -func HTTPDeleteAppSession(c *gin.Context) { - var eventsSubscReqData *models.EventsSubscReqData - - requestBody, err := c.GetRawData() - if err != nil { - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // EventsSubscReqData is Optional - if len(requestBody) > 0 { - err = openapi.Deserialize(&eventsSubscReqData, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.PolicyAuthLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - } - - req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := producer.HandleDeleteAppSessionContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } -} - -// HTTPGetAppSession - Reads an existing Individual Application Session Context -func HTTPGetAppSession(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := producer.HandleGetAppSessionContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } -} - -// HTTPModAppSession - Modifies an existing Individual Application Session Context -func HTTPModAppSession(c *gin.Context) { - var appSessionContextUpdateData models.AppSessionContextUpdateData - - requestBody, err := c.GetRawData() - if err != nil { - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - logger.PolicyAuthLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&appSessionContextUpdateData, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.PolicyAuthLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, appSessionContextUpdateData) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := producer.HandleModAppSessionContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } -} diff --git a/internal/sbi/policyauthorization/routers.go b/internal/sbi/policyauthorization/routers.go deleted file mode 100644 index 6e35aac..0000000 --- a/internal/sbi/policyauthorization/routers.go +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Npcf_PolicyAuthorization Service API - * - * This is the Policy Authorization Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package policyauthorization - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/pcf/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -// Route is the information for every URI. -type Route struct { - // Name is the name of this Route. - Name string - // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string - // Pattern is the pattern of the URI. - Pattern string - // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc -} - -// Routes is the list of the generated Route. -type Routes []Route - -// NewRouter returns a new router. -func NewRouter() *gin.Engine { - router := logger_util.NewGinWithLogrus(logger.GinLog) - AddService(router) - return router -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.PcfPolicyAuthResUriPrefix) - - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_POLICYAUTHORIZATION) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, pcf_context.GetSelf()) - }) - - for _, route := range routes { - switch route.Method { - case "GET": - group.GET(route.Pattern, route.HandlerFunc) - case "POST": - group.POST(route.Pattern, route.HandlerFunc) - case "PUT": - group.PUT(route.Pattern, route.HandlerFunc) - case "DELETE": - group.DELETE(route.Pattern, route.HandlerFunc) - case "PATCH": - group.PATCH(route.Pattern, route.HandlerFunc) - } - } - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "/", - Index, - }, - - { - "HTTPPostAppSessions", - strings.ToUpper("Post"), - "/app-sessions", - HTTPPostAppSessions, - }, - - { - "HTTPDeleteEventsSubsc", - strings.ToUpper("Delete"), - "/app-sessions/:appSessionId/events-subscription", - HTTPDeleteEventsSubsc, - }, - - { - "HTTPUpdateEventsSubsc", - strings.ToUpper("Put"), - "/app-sessions/:appSessionId/events-subscription", - HTTPUpdateEventsSubsc, - }, - - { - "HTTPDeleteAppSession", - strings.ToUpper("Post"), - "/app-sessions/:appSessionId/delete", - HTTPDeleteAppSession, - }, - - { - "HTTPGetAppSession", - strings.ToUpper("Get"), - "/app-sessions/:appSessionId", - HTTPGetAppSession, - }, - - { - "HTTPModAppSession", - strings.ToUpper("Patch"), - "/app-sessions/:appSessionId", - HTTPModAppSession, - }, -} diff --git a/internal/sbi/server.go b/internal/sbi/server.go new file mode 100644 index 0000000..4a36924 --- /dev/null +++ b/internal/sbi/server.go @@ -0,0 +1,273 @@ +package sbi + +import ( + "context" + "fmt" + "log" + "net/http" + "runtime/debug" + "sync" + "time" + + "github.com/gin-contrib/cors" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/free5gc/openapi" + // "github.com/free5gc/openapi/models" + pcf_context "github.com/free5gc/pcf/internal/context" + "github.com/free5gc/pcf/internal/logger" + "github.com/free5gc/pcf/internal/sbi/consumer" + + // "github.com/free5gc/pcf/internal/sbi/processor" + "github.com/free5gc/pcf/pkg/factory" + "github.com/free5gc/util/httpwrapper" +) + +const ( + CorsConfigMaxAge = 86400 +) + +type Endpoint struct { + Method string + Pattern string + APIFunc gin.HandlerFunc +} + +func applyEndpoints(group *gin.RouterGroup, endpoints []Endpoint) { + for _, endpoint := range endpoints { + switch endpoint.Method { + case "GET": + group.GET(endpoint.Pattern, endpoint.APIFunc) + case "POST": + group.POST(endpoint.Pattern, endpoint.APIFunc) + case "PUT": + group.PUT(endpoint.Pattern, endpoint.APIFunc) + case "PATCH": + group.PATCH(endpoint.Pattern, endpoint.APIFunc) + case "DELETE": + group.DELETE(endpoint.Pattern, endpoint.APIFunc) + } + } +} + +type pcf interface { + Config() *factory.Config + Context() *pcf_context.PCFContext + CancelContext() context.Context + // Processor() *processor.Processor + Consumer() *consumer.Consumer +} + +type Server struct { + pcf + + httpServer *http.Server + router *gin.Engine + // processor *processor.Processor +} + +func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { + s := &Server{ + pcf: pcf, + } + + smPolicyEndpoints := s.getSmPolicyEndpoints() + smPolicyGroup := s.router.Group(factory.PcfSMpolicyCtlResUriPrefix) + applyEndpoints(smPolicyGroup, smPolicyEndpoints) + + amPolicyEndpoints := s.getAmPolicyEndpoints() + amPolicyGroup := s.router.Group(factory.PcfAMpolicyCtlResUriPrefix) + applyEndpoints(amPolicyGroup, amPolicyEndpoints) + + bdtPolicyEndpoints := s.getBdtPolicyEndPoints() + bdtPolicyGroup := s.router.Group(factory.PcfBdtPolicyCtlResUriPrefix) + applyEndpoints(bdtPolicyGroup, bdtPolicyEndpoints) + + httpcallbackEndpoints := s.getHttpCallBackEndpoints() + httpcallbackGroup := s.router.Group(factory.PcfCallbackResUriPrefix) + applyEndpoints(httpcallbackGroup, httpcallbackEndpoints) + + oamEndpoints := s.getOamEndpoints() + oamGroup := s.router.Group(factory.PcfOamResUriPrefix) + applyEndpoints(oamGroup, oamEndpoints) + + policyAuthorizationEndpoints := s.getPolicyAuthorizationEndpoints() + policyAuthorizationGroup := s.router.Group(factory.PcfPolicyAuthResUriPrefix) + applyEndpoints(policyAuthorizationGroup, policyAuthorizationEndpoints) + + uePolicyEndpoints := s.getUePolicyEndpoints() + uePolicyGroup := s.router.Group(factory.PcfUePolicyCtlResUriPrefix) + applyEndpoints(uePolicyGroup, uePolicyEndpoints) + + s.router.Use(cors.New(cors.Config{ + AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, + AllowHeaders: []string{ + "Origin", "Content-Length", "Content-Type", "User-Agent", + "Referrer", "Host", "Token", "X-Requested-With", + }, + ExposeHeaders: []string{"Content-Length"}, + AllowCredentials: true, + AllowAllOrigins: true, + MaxAge: CorsConfigMaxAge, + })) + + cfg := s.Config() + bindAddr := cfg.GetSbiBindingAddr() + logger.SBILog.Infof("Binding addr: [%s]", bindAddr) + var err error + if s.httpServer, err = httpwrapper.NewHttp2Server(bindAddr, tlsKeyLogPath, s.router); err != nil { + logger.InitLog.Errorf("Initialize HTTP server failed: %v", err) + return nil, err + } + s.httpServer.ErrorLog = log.New(logger.SBILog.WriterLevel(logrus.ErrorLevel), "HTTP2: ", 0) + + return s, nil +} + +func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { + wg.Add(1) + go s.startServer(wg) + return nil +} + +func (s *Server) Stop(traceCtx context.Context) { + const defaultShutdownTimeout time.Duration = 2 * time.Second + + if s.httpServer != nil { + logger.SBILog.Infof("Stop SBI server (listen on %s)", s.httpServer.Addr) + toCtx, cancel := context.WithTimeout(context.Background(), defaultShutdownTimeout) + defer cancel() + if err := s.httpServer.Shutdown(toCtx); err != nil { + logger.SBILog.Errorf("Could not close SBI server: %#v", err) + } + } +} + +func (s *Server) startServer(wg *sync.WaitGroup) { + defer func() { + if p := recover(); p != nil { + // Print stack for panic to log. Fatalf() will let program exit. + logger.SBILog.Fatalf("panic: %v\n%s", p, string(debug.Stack())) + } + + wg.Done() + }() + + logger.SBILog.Infof("Start SBI server (listen on %s)", s.httpServer.Addr) + + var err error + cfg := s.Config() + scheme := cfg.GetSbiScheme() + if scheme == "http" { + err = s.httpServer.ListenAndServe() + } else if scheme == "https" { + err = s.httpServer.ListenAndServeTLS( + cfg.GetCertPemPath(), + cfg.GetCertKeyPath()) + } else { + err = fmt.Errorf("No support this scheme[%s]", scheme) + } + + if err != nil && err != http.ErrServerClosed { + logger.SBILog.Errorf("SBI server error: %v", err) + } + logger.SBILog.Warnf("SBI server (listen on %s) stopped", s.httpServer.Addr) +} + +func checkContentTypeIsJSON(gc *gin.Context) (string, error) { + var err error + contentType := gc.GetHeader("Content-Type") + if openapi.KindOfMediaType(contentType) != openapi.MediaKindJSON { + err = fmt.Errorf("Wrong content type %q", contentType) + } + + if err != nil { + logger.SBILog.Error(err) + gc.JSON(http.StatusInternalServerError, + openapi.ProblemDetailsMalformedReqSyntax(err.Error())) + return "", err + } + + return contentType, nil +} + +func (s *Server) deserializeData(gc *gin.Context, data interface{}, contentType string) error { + reqBody, err := gc.GetRawData() + if err != nil { + logger.SBILog.Errorf("Get Request Body error: %v", err) + gc.JSON(http.StatusInternalServerError, + openapi.ProblemDetailsSystemFailure(err.Error())) + return err + } + + err = openapi.Deserialize(data, reqBody, contentType) + if err != nil { + logger.SBILog.Errorf("Deserialize Request Body error: %v", err) + gc.JSON(http.StatusBadRequest, + openapi.ProblemDetailsMalformedReqSyntax(err.Error())) + return err + } + + return nil +} + +func (s *Server) bindData(gc *gin.Context, data interface{}) error { + err := gc.Bind(data) + if err != nil { + logger.SBILog.Errorf("Bind Request Body error: %v", err) + gc.JSON(http.StatusBadRequest, + openapi.ProblemDetailsMalformedReqSyntax(err.Error())) + return err + } + + return nil +} + +func (s *Server) buildAndSendHttpResponse( + gc *gin.Context, + hdlRsp *processor.HandlerResponse, + multipart bool, +) { + if hdlRsp.Status == 0 { + // No Response to send + return + } + + rsp := httpwrapper.NewResponse(hdlRsp.Status, hdlRsp.Headers, hdlRsp.Body) + + buildHttpResponseHeader(gc, rsp) + + var rspBody []byte + var contentType string + var err error + if multipart { + rspBody, contentType, err = openapi.MultipartSerialize(rsp.Body) + } else { + // TODO: support other JSON content-type + rspBody, err = openapi.Serialize(rsp.Body, "application/json") + contentType = "application/json" + } + + if err != nil { + logger.SBILog.Errorln(err) + gc.JSON(http.StatusInternalServerError, openapi.ProblemDetailsSystemFailure(err.Error())) + } else { + gc.Data(rsp.Status, contentType, rspBody) + } +} + +func buildHttpResponseHeader(gc *gin.Context, rsp *httpwrapper.Response) { + for k, v := range rsp.Header { + // Concatenate all values of the Header with ',' + allValues := "" + for i, vv := range v { + if i == 0 { + allValues += vv + } else { + allValues += "," + vv + } + } + gc.Header(k, allValues) + } +} diff --git a/internal/sbi/smpolicy/routers.go b/internal/sbi/smpolicy/routers.go deleted file mode 100644 index 1c05dec..0000000 --- a/internal/sbi/smpolicy/routers.go +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Npcf_SMPolicyControl - * - * Session Management Policy Control Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package smpolicy - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -// Route is the information for every URI. -type Route struct { - // Name is the name of this Route. - Name string - // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string - // Pattern is the pattern of the URI. - Pattern string - // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc -} - -// Routes is the list of the generated Route. -type Routes []Route - -// NewRouter returns a new router. -func NewRouter() *gin.Engine { - router := logger_util.NewGinWithLogrus(logger.GinLog) - AddService(router) - return router -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.PcfSMpolicyCtlResUriPrefix) - - for _, route := range routes { - switch route.Method { - case "GET": - group.GET(route.Pattern, route.HandlerFunc) - case "POST": - group.POST(route.Pattern, route.HandlerFunc) - case "PUT": - group.PUT(route.Pattern, route.HandlerFunc) - case "DELETE": - group.DELETE(route.Pattern, route.HandlerFunc) - case "PATCH": - group.PATCH(route.Pattern, route.HandlerFunc) - } - } - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "/", - Index, - }, - - { - "SmPoliciesPost", - strings.ToUpper("Post"), - "/sm-policies", - HTTPSmPoliciesPost, - }, - - { - "SmPoliciesSmPolicyIdDeletePost", - strings.ToUpper("Post"), - "/sm-policies/:smPolicyId/delete", - HTTPSmPoliciesSmPolicyIdDeletePost, - }, - - { - "SmPoliciesSmPolicyIdGet", - strings.ToUpper("Get"), - "/sm-policies/:smPolicyId", - HTTPSmPoliciesSmPolicyIDGet, - }, - - { - "SmPoliciesSmPolicyIdUpdatePost", - strings.ToUpper("Post"), - "/sm-policies/:smPolicyId/update", - HTTPSmPoliciesSmPolicyIdUpdatePost, - }, -} diff --git a/internal/sbi/uepolicy/api_default.go b/internal/sbi/uepolicy/api_default.go deleted file mode 100644 index a1ba9f1..0000000 --- a/internal/sbi/uepolicy/api_default.go +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Npcf_UEPolicyControl - * - * UE Policy Control Service API - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uepolicy - -import ( - "github.com/gin-gonic/gin" -) - -// PoliciesPolAssoIdDelete - -func PoliciesPolAssoIdDelete(c *gin.Context) { -} - -// PoliciesPolAssoIdGet - -func PoliciesPolAssoIdGet(c *gin.Context) { -} - -// PoliciesPolAssoIdUpdatePost - -func PoliciesPolAssoIdUpdatePost(c *gin.Context) { -} - -// PoliciesPost - -func PoliciesPost(c *gin.Context) { -} diff --git a/internal/sbi/uepolicy/routers.go b/internal/sbi/uepolicy/routers.go deleted file mode 100644 index 10644a9..0000000 --- a/internal/sbi/uepolicy/routers.go +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Npcf_UEPolicyControl - * - * UE Policy Control Service API - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uepolicy - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -type Route struct { - // Name is the name of this Route. - Name string - // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string - // Pattern is the pattern of the URI. - Pattern string - // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc -} - -type Routes []Route - -func NewRouter() *gin.Engine { - router := logger_util.NewGinWithLogrus(logger.GinLog) - AddService(router) - return router -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.PcfUePolicyCtlResUriPrefix) - - for _, route := range routes { - switch route.Method { - case "GET": - group.GET(route.Pattern, route.HandlerFunc) - case "POST": - group.POST(route.Pattern, route.HandlerFunc) - case "PATCH": - group.PATCH(route.Pattern, route.HandlerFunc) - } - } - return group -} - -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "", - Index, - }, - - { - "PoliciesPolAssoIdDelete", - strings.ToUpper("Delete"), - "/policies/{polAssoId}", - PoliciesPolAssoIdDelete, - }, - - { - "PoliciesPolAssoIdGet", - strings.ToUpper("Get"), - "/policies/{polAssoId}", - PoliciesPolAssoIdGet, - }, - - { - "PoliciesPolAssoIdUpdatePost", - strings.ToUpper("Post"), - "/policies/{polAssoId}/update", - PoliciesPolAssoIdUpdatePost, - }, - - { - "PoliciesPost", - strings.ToUpper("Post"), - "/policies", - PoliciesPost, - }, -} diff --git a/pkg/factory/config.go b/pkg/factory/config.go index 433e70c..d4dfab6 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -6,6 +6,7 @@ package factory import ( "fmt" + "os" "strconv" "sync" @@ -227,6 +228,59 @@ func appendInvalid(err error) error { return error(errs) } +func (c *Config) GetSbiBindingIP() string { + c.RLock() + defer c.RUnlock() + bindIP := "0.0.0.0" + if c.Configuration == nil || c.Configuration.Sbi == nil { + return bindIP + } + if c.Configuration.Sbi.BindingIPv4 != "" { + if bindIP = os.Getenv(c.Configuration.Sbi.BindingIPv4); bindIP != "" { + logger.CfgLog.Infof("Parsing ServerIPv4 [%s] from ENV Variable", bindIP) + } else { + bindIP = c.Configuration.Sbi.BindingIPv4 + } + } + return bindIP +} + +func (c *Config) GetSbiPort() int { + c.RLock() + defer c.RUnlock() + if c.Configuration != nil && c.Configuration.Sbi != nil && c.Configuration.Sbi.Port != 0 { + return c.Configuration.Sbi.Port + } + return PcfSbiDefaultPort +} + +func (c *Config) GetSbiBindingAddr() string { + c.RLock() + defer c.RUnlock() + return c.GetSbiBindingIP() + ":" + strconv.Itoa(c.GetSbiPort()) +} + +func (c *Config) GetSbiScheme() string { + c.RLock() + defer c.RUnlock() + if c.Configuration != nil && c.Configuration.Sbi != nil && c.Configuration.Sbi.Scheme != "" { + return c.Configuration.Sbi.Scheme + } + return PcfSbiDefaultScheme +} + +func (c *Config) GetCertPemPath() string { + c.RLock() + defer c.RUnlock() + return c.Configuration.Sbi.Tls.Pem +} + +func (c *Config) GetCertKeyPath() string { + c.RLock() + defer c.RUnlock() + return c.Configuration.Sbi.Tls.Key +} + func (c *Config) GetVersion() string { c.RLock() defer c.RUnlock() diff --git a/pkg/service/init.go b/pkg/service/init.go index a6cef23..7c478df 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -2,34 +2,18 @@ package service import ( "context" - "fmt" "io" "os" - "os/signal" "runtime/debug" - "syscall" - // "sync" + "sync" - "github.com/antihax/optional" - "github.com/gin-contrib/cors" "github.com/sirupsen/logrus" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/ampolicy" - "github.com/free5gc/pcf/internal/sbi/bdtpolicy" + "github.com/free5gc/pcf/internal/sbi" "github.com/free5gc/pcf/internal/sbi/consumer" - "github.com/free5gc/pcf/internal/sbi/httpcallback" - "github.com/free5gc/pcf/internal/sbi/oam" - "github.com/free5gc/pcf/internal/sbi/policyauthorization" - "github.com/free5gc/pcf/internal/sbi/smpolicy" - "github.com/free5gc/pcf/internal/sbi/uepolicy" - "github.com/free5gc/pcf/internal/util" "github.com/free5gc/pcf/pkg/factory" - "github.com/free5gc/util/httpwrapper" - logger_util "github.com/free5gc/util/logger" ) type PcfApp struct { @@ -38,18 +22,42 @@ type PcfApp struct { ctx context.Context cancel context.CancelFunc - consumer *consumer.Consumer + consumer *consumer.Consumer + // processor *processor.Processor + sbiServer *sbi.Server + wg sync.WaitGroup } -func NewApp(cfg *factory.Config) (*PcfApp, error) { - pcf := &PcfApp{cfg: cfg} +func NewApp( + ctx context.Context, + cfg *factory.Config, + tlsKeyLogPath string, +) (*PcfApp, error) { + pcf := &PcfApp{ + cfg: cfg, + wg: sync.WaitGroup{}, + } pcf.SetLogEnable(cfg.GetLogEnable()) pcf.SetLogLevel(cfg.GetLogLevel()) pcf.SetReportCaller(cfg.GetLogReportCaller()) + //這段要嗎? + // pcf.ctx, pcf.cancel = context.WithCancel(ctx) + // err := pcf_context.InitPcfContext() + // if err != nil { + // logger.InitLog.Errorln(err) + // return pcf, err + // } pcf_context.Init() pcf.pcfCtx = pcf_context.GetSelf() + //processor + // p, err := processor.NewProcessor(pcf) + // if err != nil { + // return pcf, err + // } + // pcf.processor = p + //consumer consumer, err := consumer.NewConsumer(pcf) if err != nil { @@ -119,106 +127,35 @@ func (a *PcfApp) SetReportCaller(reportCaller bool) { func (a *PcfApp) Start(tlsKeyLogPath string) { logger.InitLog.Infoln("Server started") - router := logger_util.NewGinWithLogrus(logger.GinLog) - - bdtpolicy.AddService(router) - smpolicy.AddService(router) - ampolicy.AddService(router) - uepolicy.AddService(router) - policyauthorization.AddService(router) - httpcallback.AddService(router) - oam.AddService(router) - - router.Use(cors.New(cors.Config{ - AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, - AllowHeaders: []string{ - "Origin", "Content-Length", "Content-Type", "User-Agent", - "Referrer", "Host", "Token", "X-Requested-With", - }, - ExposeHeaders: []string{"Content-Length"}, - AllowCredentials: true, - AllowAllOrigins: true, - MaxAge: 86400, - })) - - pemPath := factory.PcfDefaultCertPemPath - keyPath := factory.PcfDefaultPrivateKeyPath - sbi := factory.PcfConfig.Configuration.Sbi - if sbi.Tls != nil { - pemPath = sbi.Tls.Pem - keyPath = sbi.Tls.Key - } - - self := a.pcfCtx - pcf_context.InitpcfContext(self) - addr := fmt.Sprintf("%s:%d", self.BindingIPv4, self.SBIPort) + a.wg.Add(1) - profile, err := consumer.BuildNFInstance(self) - if err != nil { - logger.InitLog.Error("Build PCF Profile Error") - } - _, self.NfId, err = consumer.SendRegisterNFInstance(self.NrfUri, self.NfId, profile) - if err != nil { - logger.InitLog.Errorf("PCF register to NRF Error[%s]", err.Error()) + go a.listenShutdownEvent() + if err := a.sbiServer.Run(context.Background(), &a.wg); err != nil { + logger.InitLog.Fatalf("Run SBI server failed: %+v", err) } - param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NUDR_DR}), - } - resp, err := consumer.SendSearchNFInstances(self.NrfUri, models.NfType_UDR, models.NfType_PCF, param) - for _, nfProfile := range resp.NfInstances { - udruri := util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDR_DR, models.NfServiceStatus_REGISTERED) - if udruri != "" { - self.SetDefaultUdrURI(udruri) - break +} +func (a *PcfApp) listenShutdownEvent() { + defer func() { + if p := recover(); p != nil { + // Print stack for panic to log. Fatalf() will let program exit. + logger.InitLog.Fatalf("panic: %v\n%s", p, string(debug.Stack())) } - } - if err != nil { - logger.InitLog.Errorln(err) - } - - signalChannel := make(chan os.Signal, 1) - signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) - go func() { - defer func() { - if p := recover(); p != nil { - // Print stack for panic to log. Fatalf() will let program exit. - logger.InitLog.Fatalf("panic: %v\n%s", p, string(debug.Stack())) - } - }() - - <-signalChannel - a.Terminate() - os.Exit(0) + a.wg.Done() }() - server, err := httpwrapper.NewHttp2Server(addr, tlsKeyLogPath, router) - if server == nil { - logger.InitLog.Errorf("Initialize HTTP server failed: %+v", err) - return - } - - if err != nil { - logger.InitLog.Warnf("Initialize HTTP server: +%v", err) - } - - serverScheme := factory.PcfConfig.Configuration.Sbi.Scheme - if serverScheme == "http" { - err = server.ListenAndServe() - } else if serverScheme == "https" { - err = server.ListenAndServeTLS(pemPath, keyPath) - } + <-a.ctx.Done() - if err != nil { - logger.InitLog.Fatalf("HTTP server setup failed: %+v", err) + if a.sbiServer != nil { + a.sbiServer.Stop(context.Background()) + a.Terminate() } } - func (a *PcfApp) Terminate() { logger.InitLog.Infof("Terminating PCF...") // deregister with NRF - problemDetails, err := consumer.SendDeregisterNFInstance() + problemDetails, err := a.consumer.SendDeregisterNFInstance() if problemDetails != nil { logger.InitLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails) } else if err != nil { @@ -228,3 +165,13 @@ func (a *PcfApp) Terminate() { } logger.InitLog.Infof("PCF terminated") } + +func (a *PcfApp) WaitRoutineStopped() { + a.wg.Wait() + logger.MainLog.Infof("PCF App is terminated") +} + +func (a *PcfApp) Stop() { + a.cancel() + a.WaitRoutineStopped() +} From 4d4a2d5c730d3247b7f4fb1d1ffa8e8c5f83e5ea Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Fri, 3 May 2024 09:29:01 +0000 Subject: [PATCH 04/20] fix: rename endpoint to route --- internal/sbi/api_ampolicy.go | 4 +-- internal/sbi/api_bdtpolicy.go | 4 +-- internal/sbi/api_httpcallback.go | 4 +-- internal/sbi/api_oam.go | 4 +-- internal/sbi/api_policyauthorization.go | 4 +-- internal/sbi/api_smpolicy.go | 4 +-- internal/sbi/api_uepolicy.go | 4 +-- internal/sbi/server.go | 48 ++++++++++++------------- 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/internal/sbi/api_ampolicy.go b/internal/sbi/api_ampolicy.go index c734619..2493dc6 100644 --- a/internal/sbi/api_ampolicy.go +++ b/internal/sbi/api_ampolicy.go @@ -163,8 +163,8 @@ func (s *Server) HTTPPoliciesPost(c *gin.Context) { } } -func (s *Server) getAmPolicyEndpoints() []Endpoint { - return []Endpoint{ +func (s *Server) getAmPolicyRoutes() []Route { + return []Route{ { Method: http.MethodGet, diff --git a/internal/sbi/api_bdtpolicy.go b/internal/sbi/api_bdtpolicy.go index 0943a7a..2a4f3b5 100644 --- a/internal/sbi/api_bdtpolicy.go +++ b/internal/sbi/api_bdtpolicy.go @@ -24,8 +24,8 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func (s *Server) getBdtPolicyEndPoints() []Endpoint { - return []Endpoint{ +func (s *Server) getBdtPolicyRoutes() []Route { + return []Route{ { Method: http.MethodPost, Pattern: "/bdtpolicies", diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index 6021883..6ee411c 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -12,8 +12,8 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func (s *Server) getHttpCallBackEndpoints() []Endpoint { - return []Endpoint{ +func (s *Server) getHttpCallBackRoutes() []Route { + return []Route{ { Method: http.MethodPost, Pattern: "/nudr-notify/policy-data/:supi", diff --git a/internal/sbi/api_oam.go b/internal/sbi/api_oam.go index d4b0272..4ead79b 100644 --- a/internal/sbi/api_oam.go +++ b/internal/sbi/api_oam.go @@ -43,8 +43,8 @@ func (s *Server) HTTPOAMGetAmPolicy(c *gin.Context) { } } -func (s *Server) getOamEndpoints() []Endpoint { - return []Endpoint{ +func (s *Server) getOamRoutes() []Route { + return []Route{ { Method: http.MethodGet, Pattern: "/am-policy/:supi", diff --git a/internal/sbi/api_policyauthorization.go b/internal/sbi/api_policyauthorization.go index 572cfa1..3fc0f08 100644 --- a/internal/sbi/api_policyauthorization.go +++ b/internal/sbi/api_policyauthorization.go @@ -22,8 +22,8 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func (s *Server) getPolicyAuthorizationEndpoints() []Endpoint { - return []Endpoint{ +func (s *Server) getPolicyAuthorizationRoutes() []Route { + return []Route{ { Method: http.MethodPost, Pattern: "/app-sessions", diff --git a/internal/sbi/api_smpolicy.go b/internal/sbi/api_smpolicy.go index 590358e..cadff99 100644 --- a/internal/sbi/api_smpolicy.go +++ b/internal/sbi/api_smpolicy.go @@ -21,8 +21,8 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func (s *Server) getSmPolicyEndpoints() []Endpoint { - return []Endpoint{ +func (s *Server) getSmPolicyRoutes() []Route { + return []Route{ { Method: http.MethodPost, Pattern: "/sm-policies", diff --git a/internal/sbi/api_uepolicy.go b/internal/sbi/api_uepolicy.go index b0f72df..52cfab4 100644 --- a/internal/sbi/api_uepolicy.go +++ b/internal/sbi/api_uepolicy.go @@ -15,8 +15,8 @@ import ( "github.com/gin-gonic/gin" ) -func (s *Server) getUePolicyEndpoints() []Endpoint { - return []Endpoint{ +func (s *Server) getUePolicyRoutes() []Route { + return []Route{ { Method: http.MethodDelete, Pattern: "/policies/{polAssoId}", diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 4a36924..bd05af5 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -19,7 +19,7 @@ import ( "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/sbi/consumer" - // "github.com/free5gc/pcf/internal/sbi/processor" + "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/pcf/pkg/factory" "github.com/free5gc/util/httpwrapper" ) @@ -28,25 +28,25 @@ const ( CorsConfigMaxAge = 86400 ) -type Endpoint struct { +type Route struct { Method string Pattern string APIFunc gin.HandlerFunc } -func applyEndpoints(group *gin.RouterGroup, endpoints []Endpoint) { - for _, endpoint := range endpoints { - switch endpoint.Method { +func applyRoutes(group *gin.RouterGroup, routes []Route) { + for _, route := range routes { + switch route.Method { case "GET": - group.GET(endpoint.Pattern, endpoint.APIFunc) + group.GET(route.Pattern, route.APIFunc) case "POST": - group.POST(endpoint.Pattern, endpoint.APIFunc) + group.POST(route.Pattern, route.APIFunc) case "PUT": - group.PUT(endpoint.Pattern, endpoint.APIFunc) + group.PUT(route.Pattern, route.APIFunc) case "PATCH": - group.PATCH(endpoint.Pattern, endpoint.APIFunc) + group.PATCH(route.Pattern, route.APIFunc) case "DELETE": - group.DELETE(endpoint.Pattern, endpoint.APIFunc) + group.DELETE(route.Pattern, route.APIFunc) } } } @@ -72,33 +72,33 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { pcf: pcf, } - smPolicyEndpoints := s.getSmPolicyEndpoints() + smPolicyRoutes := s.getSmPolicyRoutes() smPolicyGroup := s.router.Group(factory.PcfSMpolicyCtlResUriPrefix) - applyEndpoints(smPolicyGroup, smPolicyEndpoints) + applyRoutes(smPolicyGroup, smPolicyRoutes) - amPolicyEndpoints := s.getAmPolicyEndpoints() + amPolicyRoutes := s.getAmPolicyRoutes() amPolicyGroup := s.router.Group(factory.PcfAMpolicyCtlResUriPrefix) - applyEndpoints(amPolicyGroup, amPolicyEndpoints) + applyRoutes(amPolicyGroup, amPolicyRoutes) - bdtPolicyEndpoints := s.getBdtPolicyEndPoints() + bdtPolicyRoutes := s.getBdtPolicyRoutes() bdtPolicyGroup := s.router.Group(factory.PcfBdtPolicyCtlResUriPrefix) - applyEndpoints(bdtPolicyGroup, bdtPolicyEndpoints) + applyRoutes(bdtPolicyGroup, bdtPolicyRoutes) - httpcallbackEndpoints := s.getHttpCallBackEndpoints() + httpcallbackRoutes := s.getHttpCallBackRoutes() httpcallbackGroup := s.router.Group(factory.PcfCallbackResUriPrefix) - applyEndpoints(httpcallbackGroup, httpcallbackEndpoints) + applyRoutes(httpcallbackGroup, httpcallbackRoutes) - oamEndpoints := s.getOamEndpoints() + oamRoutes := s.getOamRoutes() oamGroup := s.router.Group(factory.PcfOamResUriPrefix) - applyEndpoints(oamGroup, oamEndpoints) + applyRoutes(oamGroup, oamRoutes) - policyAuthorizationEndpoints := s.getPolicyAuthorizationEndpoints() + policyAuthorizationRoutes := s.getPolicyAuthorizationRoutes() policyAuthorizationGroup := s.router.Group(factory.PcfPolicyAuthResUriPrefix) - applyEndpoints(policyAuthorizationGroup, policyAuthorizationEndpoints) + applyRoutes(policyAuthorizationGroup, policyAuthorizationRoutes) - uePolicyEndpoints := s.getUePolicyEndpoints() + uePolicyRoutes := s.getUePolicyRoutes() uePolicyGroup := s.router.Group(factory.PcfUePolicyCtlResUriPrefix) - applyEndpoints(uePolicyGroup, uePolicyEndpoints) + applyRoutes(uePolicyGroup, uePolicyRoutes) s.router.Use(cors.New(cors.Config{ AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, From 571d2252f417d33c609bc7fe33426fac74dad694 Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Fri, 3 May 2024 10:05:28 +0000 Subject: [PATCH 05/20] refactor: add App interface and change producer to processor --- .../sbi/{producer => processor}/ampolicy.go | 19 ++++++------ .../sbi/{producer => processor}/bdtpolicy.go | 23 +++++++------- .../sbi/{producer => processor}/callback.go | 2 +- internal/sbi/{producer => processor}/oam.go | 2 +- .../policyauthorization.go | 22 ++++++------- internal/sbi/processor/processor.go | 31 +++++++++++++++++++ .../sbi/{producer => processor}/smpolicy.go | 23 +++++++------- pkg/app/app.go | 18 +++++++++++ 8 files changed, 93 insertions(+), 47 deletions(-) rename internal/sbi/{producer => processor}/ampolicy.go (95%) rename internal/sbi/{producer => processor}/bdtpolicy.go (92%) rename internal/sbi/{producer => processor}/callback.go (99%) rename internal/sbi/{producer => processor}/oam.go (99%) rename internal/sbi/{producer => processor}/policyauthorization.go (98%) create mode 100644 internal/sbi/processor/processor.go rename internal/sbi/{producer => processor}/smpolicy.go (98%) create mode 100644 pkg/app/app.go diff --git a/internal/sbi/producer/ampolicy.go b/internal/sbi/processor/ampolicy.go similarity index 95% rename from internal/sbi/producer/ampolicy.go rename to internal/sbi/processor/ampolicy.go index 5e816fb..f4d5d19 100644 --- a/internal/sbi/producer/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -1,4 +1,4 @@ -package producer +package processor import ( "fmt" @@ -11,7 +11,6 @@ import ( "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/consumer" "github.com/free5gc/pcf/internal/util" "github.com/free5gc/util/httpwrapper" ) @@ -179,13 +178,13 @@ func UpdatePostPoliciesPolAssoIdProcedure(polAssoId string, } // Create AM Policy -func HandlePostPolicies(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandlePostPolicies(request *httpwrapper.Request) *httpwrapper.Response { logger.AmPolicyLog.Infof("Handle AM Policy Create Request") polAssoId := request.Params["polAssoId"] policyAssociationRequest := request.Body.(models.PolicyAssociationRequest) - response, locationHeader, problemDetails := PostPoliciesProcedure(polAssoId, policyAssociationRequest) + response, locationHeader, problemDetails := p.PostPoliciesProcedure(polAssoId, policyAssociationRequest) headers := http.Header{ "Location": {locationHeader}, } @@ -201,7 +200,7 @@ func HandlePostPolicies(request *httpwrapper.Request) *httpwrapper.Response { return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) } -func PostPoliciesProcedure(polAssoId string, +func (p *Processor) PostPoliciesProcedure(polAssoId string, policyAssociationRequest models.PolicyAssociationRequest, ) (*models.PolicyAssociation, string, *models.ProblemDetails) { var response models.PolicyAssociation @@ -220,7 +219,7 @@ func PostPoliciesProcedure(polAssoId string, ue = newUe } } - udrUri := getUdrUri(ue) + udrUri := p.getUdrUri(ue) if udrUri == "" { // Can't find any UDR support this Ue pcfSelf.UePool.Delete(ue.Supi) @@ -301,9 +300,9 @@ func PostPoliciesProcedure(polAssoId string, if needSubscribe { logger.AmPolicyLog.Debugf("Subscribe AMF status change[GUAMI: %+v]", *policyAssociationRequest.Guami) - amfUri := consumer.SendNFInstancesAMF(pcfSelf.NrfUri, *policyAssociationRequest.Guami, models.ServiceName_NAMF_COMM) + amfUri := p.consumer.SendNFInstancesAMF(pcfSelf.NrfUri, *policyAssociationRequest.Guami, models.ServiceName_NAMF_COMM) if amfUri != "" { - problemDetails, err := consumer.AmfStatusChangeSubscribe(amfUri, []models.Guami{*policyAssociationRequest.Guami}) + problemDetails, err := p.consumer.AmfStatusChangeSubscribe(amfUri, []models.Guami{*policyAssociationRequest.Guami}) if err != nil { logger.AmPolicyLog.Errorf("Subscribe AMF status change error[%+v]", err) } else if problemDetails != nil { @@ -430,9 +429,9 @@ func SendAMPolicyTerminationRequestNotification(ue *pcf_context.UeContext, } // returns UDR Uri of Ue, if ue.UdrUri dose not exist, query NRF to get supported Udr Uri -func getUdrUri(ue *pcf_context.UeContext) string { +func (p *Processor) getUdrUri(ue *pcf_context.UeContext) string { if ue.UdrUri != "" { return ue.UdrUri } - return consumer.SendNFInstancesUDR(pcf_context.GetSelf().NrfUri, ue.Supi) + return p.consumer.SendNFInstancesUDR(pcf_context.GetSelf().NrfUri, ue.Supi) } diff --git a/internal/sbi/producer/bdtpolicy.go b/internal/sbi/processor/bdtpolicy.go similarity index 92% rename from internal/sbi/producer/bdtpolicy.go rename to internal/sbi/processor/bdtpolicy.go index 7bb935e..c236103 100644 --- a/internal/sbi/producer/bdtpolicy.go +++ b/internal/sbi/processor/bdtpolicy.go @@ -1,4 +1,4 @@ -package producer +package processor import ( "fmt" @@ -13,7 +13,6 @@ import ( "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/consumer" "github.com/free5gc/pcf/internal/util" "github.com/free5gc/util/httpwrapper" ) @@ -59,7 +58,7 @@ func getBDTPolicyContextProcedure(bdtPolicyID string) ( } // UpdateBDTPolicy - Update an Individual BDT policy (choose policy data) -func HandleUpdateBDTPolicyContextProcedure(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleUpdateBDTPolicyContextProcedure(request *httpwrapper.Request) *httpwrapper.Response { // step 1: log logger.BdtPolicyLog.Infof("Handle UpdateBDTPolicyContext") @@ -68,7 +67,7 @@ func HandleUpdateBDTPolicyContextProcedure(request *httpwrapper.Request) *httpwr bdtPolicyID := request.Params["bdtPolicyId"] // step 3: handle the message - response, problemDetails := updateBDTPolicyContextProcedure(requestDataType, bdtPolicyID) + response, problemDetails := p.updateBDTPolicyContextProcedure(requestDataType, bdtPolicyID) // step 4: process the return value from step 3 if response != nil { @@ -84,7 +83,7 @@ func HandleUpdateBDTPolicyContextProcedure(request *httpwrapper.Request) *httpwr return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) } -func updateBDTPolicyContextProcedure(request models.BdtPolicyDataPatch, bdtPolicyID string) ( +func (p *Processor) updateBDTPolicyContextProcedure(request models.BdtPolicyDataPatch, bdtPolicyID string) ( response *models.BdtPolicy, problemDetails *models.ProblemDetails, ) { logger.BdtPolicyLog.Infoln("Handle BDTPolicyUpdate") @@ -117,7 +116,7 @@ func updateBDTPolicyContextProcedure(request models.BdtPolicyDataPatch, bdtPolic param := Nudr_DataRepository.PolicyDataBdtDataBdtReferenceIdPutParamOpts{ BdtData: optional.NewInterface(bdtData), } - client := util.GetNudrClient(getDefaultUdrUri(pcfSelf)) + client := util.GetNudrClient(p.getDefaultUdrUri(pcfSelf)) ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return nil, pd @@ -145,7 +144,7 @@ func updateBDTPolicyContextProcedure(request models.BdtPolicyDataPatch, bdtPolic } // CreateBDTPolicy - Create a new Individual BDT policy -func HandleCreateBDTPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleCreateBDTPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { // step 1: log logger.BdtPolicyLog.Infof("Handle CreateBDTPolicyContext") @@ -158,7 +157,7 @@ func HandleCreateBDTPolicyContextRequest(request *httpwrapper.Request) *httpwrap } // step 3: handle the message - header, response, problemDetails := createBDTPolicyContextProcedure(&requestMsg) + header, response, problemDetails := p.createBDTPolicyContextProcedure(&requestMsg) // step 4: process the return value from step 3 if response != nil { @@ -171,14 +170,14 @@ func HandleCreateBDTPolicyContextRequest(request *httpwrapper.Request) *httpwrap } } -func createBDTPolicyContextProcedure(request *models.BdtReqData) ( +func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) ( header http.Header, response *models.BdtPolicy, problemDetails *models.ProblemDetails, ) { response = &models.BdtPolicy{} logger.BdtPolicyLog.Traceln("Handle BDT Policy Create") pcfSelf := pcf_context.GetSelf() - udrUri := getDefaultUdrUri(pcfSelf) + udrUri := p.getDefaultUdrUri(pcfSelf) if udrUri == "" { // Can't find any UDR support this Ue problemDetails = &models.ProblemDetails{ @@ -282,7 +281,7 @@ func createBDTPolicyContextProcedure(request *models.BdtReqData) ( return header, response, problemDetails } -func getDefaultUdrUri(context *pcf_context.PCFContext) string { +func (p *Processor) getDefaultUdrUri(context *pcf_context.PCFContext) string { context.DefaultUdrURILock.RLock() defer context.DefaultUdrURILock.RUnlock() if context.DefaultUdrURI != "" { @@ -291,7 +290,7 @@ func getDefaultUdrUri(context *pcf_context.PCFContext) string { param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NUDR_DR}), } - resp, err := consumer.SendSearchNFInstances(context.NrfUri, models.NfType_UDR, models.NfType_PCF, param) + resp, err := p.consumer.SendSearchNFInstances(context.NrfUri, models.NfType_UDR, models.NfType_PCF, param) if err != nil { return "" } diff --git a/internal/sbi/producer/callback.go b/internal/sbi/processor/callback.go similarity index 99% rename from internal/sbi/producer/callback.go rename to internal/sbi/processor/callback.go index 29ab9dc..fc85ea6 100644 --- a/internal/sbi/producer/callback.go +++ b/internal/sbi/processor/callback.go @@ -1,4 +1,4 @@ -package producer +package processor import ( "fmt" diff --git a/internal/sbi/producer/oam.go b/internal/sbi/processor/oam.go similarity index 99% rename from internal/sbi/producer/oam.go rename to internal/sbi/processor/oam.go index d74dfa1..414b525 100644 --- a/internal/sbi/producer/oam.go +++ b/internal/sbi/processor/oam.go @@ -1,4 +1,4 @@ -package producer +package processor import ( "net/http" diff --git a/internal/sbi/producer/policyauthorization.go b/internal/sbi/processor/policyauthorization.go similarity index 98% rename from internal/sbi/producer/policyauthorization.go rename to internal/sbi/processor/policyauthorization.go index 7ecfd04..9f25d18 100644 --- a/internal/sbi/producer/policyauthorization.go +++ b/internal/sbi/processor/policyauthorization.go @@ -1,4 +1,4 @@ -package producer +package processor import ( "fmt" @@ -128,12 +128,12 @@ func handleMediaSubComponent(smPolicy *pcf_context.UeSmPolicyData, medComp *mode // Subscription to resources allocation outcome (DONE) // Invocation of Multimedia Priority Services (TODO) // Support of content versioning (TODO) -func HandlePostAppSessionsContext(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandlePostAppSessionsContext(request *httpwrapper.Request) *httpwrapper.Response { logger.PolicyAuthLog.Traceln("Handle Create AppSessions") appSessCtx := request.Body.(models.AppSessionContext) - response, locationHeader, problemDetails := postAppSessCtxProcedure(&appSessCtx) + response, locationHeader, problemDetails := p.postAppSessCtxProcedure(&appSessCtx) if response != nil { headers := http.Header{ @@ -150,7 +150,7 @@ func HandlePostAppSessionsContext(request *httpwrapper.Request) *httpwrapper.Res return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) } -func postAppSessCtxProcedure(appSessCtx *models.AppSessionContext) (*models.AppSessionContext, +func (p *Processor) postAppSessCtxProcedure(appSessCtx *models.AppSessionContext) (*models.AppSessionContext, string, *models.ProblemDetails, ) { ascReqData := appSessCtx.AscReqData @@ -158,7 +158,7 @@ func postAppSessCtxProcedure(appSessCtx *models.AppSessionContext) (*models.AppS // Initial BDT policy indication(the only one which is not related to session) if ascReqData.BdtRefId != "" { - if err := handleBDTPolicyInd(pcfSelf, appSessCtx); err != nil { + if err := p.handleBDTPolicyInd(pcfSelf, appSessCtx); err != nil { problemDetail := util.GetProblemDetail(err.Error(), util.ERROR_REQUEST_PARAMETERS) return nil, "", &problemDetail } @@ -531,12 +531,12 @@ func GetAppSessionContextProcedure(appSessID string) (*models.ProblemDetails, *m } // HandleModAppSession - Modifies an existing Individual Application Session Context -func HandleModAppSessionContext(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleModAppSessionContext(request *httpwrapper.Request) *httpwrapper.Response { appSessID := request.Params["appSessionId"] ascUpdateData := request.Body.(models.AppSessionContextUpdateData) logger.PolicyAuthLog.Infof("Handle Modify AppSessions, AppSessionId[%s]", appSessID) - problemDetails, response := ModAppSessionContextProcedure(appSessID, ascUpdateData) + problemDetails, response := p.ModAppSessionContextProcedure(appSessID, ascUpdateData) if problemDetails == nil { return httpwrapper.NewResponse(http.StatusOK, nil, response) } else { @@ -544,7 +544,7 @@ func HandleModAppSessionContext(request *httpwrapper.Request) *httpwrapper.Respo } } -func ModAppSessionContextProcedure(appSessID string, +func (p *Processor) ModAppSessionContextProcedure(appSessID string, ascUpdateData models.AppSessionContextUpdateData, ) (*models.ProblemDetails, *models.AppSessionContext) { pcfSelf := pcf_context.GetSelf() @@ -559,7 +559,7 @@ func ModAppSessionContextProcedure(appSessID string, appSessCtx := appSession.AppSessionContext if ascUpdateData.BdtRefId != "" { appSessCtx.AscReqData.BdtRefId = ascUpdateData.BdtRefId - if err := handleBDTPolicyInd(pcfSelf, appSessCtx); err != nil { + if err := p.handleBDTPolicyInd(pcfSelf, appSessCtx); err != nil { problemDetail := util.GetProblemDetail(err.Error(), util.ERROR_REQUEST_PARAMETERS) return &problemDetail, nil } @@ -1113,7 +1113,7 @@ func SendAppSessionTermination(appSession *pcf_context.AppSessionData, request m } // Handle Create/ Modify Background Data Transfer Policy Indication -func handleBDTPolicyInd(pcfSelf *pcf_context.PCFContext, +func (p *Processor) handleBDTPolicyInd(pcfSelf *pcf_context.PCFContext, appSessCtx *models.AppSessionContext, ) (err error) { req := appSessCtx.AscReqData @@ -1135,7 +1135,7 @@ func handleBDTPolicyInd(pcfSelf *pcf_context.PCFContext, return err } - client := util.GetNudrClient(getDefaultUdrUri(pcfSelf)) + client := util.GetNudrClient(p.getDefaultUdrUri(pcfSelf)) bdtData, resp, err1 := client.DefaultApi.PolicyDataBdtDataBdtReferenceIdGet(ctx, req.BdtRefId) if err1 != nil { return fmt.Errorf("UDR Get BdtData error[%s]", err1.Error()) diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go new file mode 100644 index 0000000..358a88d --- /dev/null +++ b/internal/sbi/processor/processor.go @@ -0,0 +1,31 @@ +package processor + +import ( + "github.com/free5gc/pcf/internal/sbi/consumer" + "github.com/free5gc/pcf/pkg/app" +) + +type Processor struct { + app.App + + consumer *consumer.Consumer +} + +type HandlerResponse struct { + Status int + Headers map[string][]string + Body interface{} +} + +func NewProcessor(pcf app.App, consumer *consumer.Consumer) (*Processor, error) { + p := &Processor{ + App: pcf, + consumer: consumer, + } + + return p, nil +} + +func (p *Processor) Consumer() *consumer.Consumer { + return p.consumer +} diff --git a/internal/sbi/producer/smpolicy.go b/internal/sbi/processor/smpolicy.go similarity index 98% rename from internal/sbi/producer/smpolicy.go rename to internal/sbi/processor/smpolicy.go index 2a38936..3c1a25f 100644 --- a/internal/sbi/producer/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -1,4 +1,4 @@ -package producer +package processor import ( "fmt" @@ -14,7 +14,6 @@ import ( "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/consumer" "github.com/free5gc/pcf/internal/util" "github.com/free5gc/util/flowdesc" "github.com/free5gc/util/httpwrapper" @@ -28,14 +27,14 @@ const ( ) // SmPoliciesPost - -func HandleCreateSmPolicyRequest(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleCreateSmPolicyRequest(request *httpwrapper.Request) *httpwrapper.Response { // step 1: log logger.SmPolicyLog.Infof("Handle CreateSmPolicy") // step 2: retrieve request requestDataType := request.Body.(models.SmPolicyContextData) // step 3: handle the message - header, response, problemDetails := createSMPolicyProcedure(requestDataType) + header, response, problemDetails := p.createSMPolicyProcedure(requestDataType) // step 4: process the return value from step 3 if response != nil { @@ -70,7 +69,7 @@ func newQosDataWithQosFlowMap(qosFlow map[string]interface{}) *models.QosData { return qosData } -func createSMPolicyProcedure(request models.SmPolicyContextData) ( +func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) ( header http.Header, response *models.SmPolicyDecision, problemDetails *models.ProblemDetails, ) { var err error @@ -94,7 +93,7 @@ func createSMPolicyProcedure(request models.SmPolicyContextData) ( logger.SmPolicyLog.Warnf("Supi[%s] is not supported in PCF", request.Supi) return nil, nil, &problemDetail } - udrUri := getUdrUri(ue) + udrUri := p.getUdrUri(ue) if udrUri == "" { problemDetail := util.GetProblemDetail("Can't find corresponding UDR with UE", util.USER_UNKNOWN) logger.SmPolicyLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) @@ -441,7 +440,7 @@ func createSMPolicyProcedure(request models.SmPolicyContextData) ( } // Subscribe to Traffic Influence Data in UDR - subscriptionID, problemDetail, err := consumer.CreateInfluenceDataSubscription(ue, request) + subscriptionID, problemDetail, err := p.consumer.CreateInfluenceDataSubscription(ue, request) if problemDetail != nil { logger.SmPolicyLog.Errorf("Subscribe UDR Influence Data Failed Problem[%+v]", problemDetail) } else if err != nil { @@ -464,7 +463,7 @@ func createSMPolicyProcedure(request models.SmPolicyContextData) ( } // TODO: Record BSF URI instead of discovering from NRF every time - bsfUri := consumer.SendNFInstancesBSF(pcf_context.GetSelf().NrfUri) + bsfUri := p.consumer.SendNFInstancesBSF(pcf_context.GetSelf().NrfUri) if bsfUri != "" { bsfClient := util.GetNbsfClient(bsfUri) @@ -496,7 +495,7 @@ func createSMPolicyProcedure(request models.SmPolicyContextData) ( } // SmPoliciessmPolicyIDDeletePost - -func HandleDeleteSmPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleDeleteSmPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { // step 1: log logger.SmPolicyLog.Infof("Handle DeleteSmPolicyContext") @@ -504,7 +503,7 @@ func HandleDeleteSmPolicyContextRequest(request *httpwrapper.Request) *httpwrapp smPolicyID := request.Params["smPolicyId"] // step 3: handle the message - problemDetails := deleteSmPolicyContextProcedure(smPolicyID) + problemDetails := p.deleteSmPolicyContextProcedure(smPolicyID) // step 4: process the return value from step 3 if problemDetails != nil { @@ -515,7 +514,7 @@ func HandleDeleteSmPolicyContextRequest(request *httpwrapper.Request) *httpwrapp } } -func deleteSmPolicyContextProcedure(smPolicyID string) *models.ProblemDetails { +func (p *Processor) deleteSmPolicyContextProcedure(smPolicyID string) *models.ProblemDetails { logger.AmPolicyLog.Traceln("Handle SM Policy Delete") ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyID) @@ -528,7 +527,7 @@ func deleteSmPolicyContextProcedure(smPolicyID string) *models.ProblemDetails { pcfSelf := pcf_context.GetSelf() smPolicy := ue.SmPolicyData[smPolicyID] - problemDetail, err := consumer.RemoveInfluenceDataSubscription(ue, smPolicy.SubscriptionID) + problemDetail, err := p.consumer.RemoveInfluenceDataSubscription(ue, smPolicy.SubscriptionID) if problemDetail != nil { logger.SmPolicyLog.Errorf("Remove UDR Influence Data Subscription Failed Problem[%+v]", problemDetail) } else if err != nil { diff --git a/pkg/app/app.go b/pkg/app/app.go new file mode 100644 index 0000000..e1b0d62 --- /dev/null +++ b/pkg/app/app.go @@ -0,0 +1,18 @@ +package app + +import ( + pcf_context "github.com/free5gc/pcf/internal/context" + "github.com/free5gc/pcf/pkg/factory" +) + +type App interface { + SetLogEnable(enable bool) + SetLogLevel(level string) + SetReportCaller(reportCaller bool) + + Start() + Terminate() + + Context() *pcf_context.PCFContext + Config() *factory.Config +} From 0cd51cfdfe76c7e006d80de1caa86311e28a66f6 Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Fri, 3 May 2024 13:43:04 +0000 Subject: [PATCH 06/20] refactor: add processor in server --- cmd/main.go | 33 ++++++++++++++++++++++++- internal/sbi/api_ampolicy.go | 10 ++++---- internal/sbi/api_bdtpolicy.go | 8 +++--- internal/sbi/api_httpcallback.go | 8 +++--- internal/sbi/api_oam.go | 4 +-- internal/sbi/api_policyauthorization.go | 14 +++++------ internal/sbi/api_smpolicy.go | 10 ++++---- internal/sbi/server.go | 4 +-- 8 files changed, 61 insertions(+), 30 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 1c03345..4702341 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -12,10 +12,15 @@ package main import ( + "context" "fmt" "os" + "os/signal" "path/filepath" "runtime/debug" + "sync" + "syscall" + "time" "github.com/urfave/cli" @@ -64,13 +69,39 @@ func action(cliCtx *cli.Context) error { logger.MainLog.Infoln(cliCtx.App.Name) logger.MainLog.Infoln("PCF version: ", version.GetVersion()) + ctx, cancel := context.WithCancel(context.Background()) + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + wg := new(sync.WaitGroup) + wg.Add(1) + go func() { + defer wg.Done() + <-sigCh // Wait for interrupt signal to gracefully shutdown UPF + + logger.MainLog.Warnln("Terminating... (Wait 2s for other NFs to deregister)") + time.Sleep(2 * time.Second) // Waiting for other NFs to deregister + cancel() // Notify each goroutine and wait them stopped + if PCF != nil { + PCF.WaitRoutineStopped() + } + }() + + defer func() { + select { + case sigCh <- nil: // Send signal in case of returning with error + default: + } + wg.Wait() + logger.MainLog.Infof("PCF Stopped...") + }() + cfg, err := factory.ReadConfig(cliCtx.String("config")) if err != nil { return err } factory.PcfConfig = cfg - pcf, err := service.NewApp(cfg) + pcf, err := service.NewApp(ctx, cfg, tlsKeyLogPath) if err != nil { return err } diff --git a/internal/sbi/api_ampolicy.go b/internal/sbi/api_ampolicy.go index 2493dc6..973792d 100644 --- a/internal/sbi/api_ampolicy.go +++ b/internal/sbi/api_ampolicy.go @@ -8,7 +8,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" + "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/pcf/internal/util" "github.com/free5gc/util/httpwrapper" ) @@ -17,7 +17,7 @@ func (s *Server) HTTPPoliciesPolAssoIdDelete(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["polAssoId"], _ = c.Params.Get("polAssoId") - rsp := producer.HandleDeletePoliciesPolAssoId(req) + rsp := processor.HandleDeletePoliciesPolAssoId(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -38,7 +38,7 @@ func (s *Server) HTTPPoliciesPolAssoIdGet(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["polAssoId"], _ = c.Params.Get("polAssoId") - rsp := producer.HandleGetPoliciesPolAssoId(req) + rsp := processor.HandleGetPoliciesPolAssoId(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -87,7 +87,7 @@ func (s *Server) HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, policyAssociationUpdateRequest) req.Params["polAssoId"], _ = c.Params.Get("polAssoId") - rsp := producer.HandleUpdatePostPoliciesPolAssoId(req) + rsp := processor.HandleUpdatePostPoliciesPolAssoId(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -143,7 +143,7 @@ func (s *Server) HTTPPoliciesPost(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, policyAssociationRequest) req.Params["polAssoId"], _ = c.Params.Get("polAssoId") - rsp := producer.HandlePostPolicies(req) + rsp := s.processor.HandlePostPolicies(req) for key, val := range rsp.Header { c.Header(key, val[0]) diff --git a/internal/sbi/api_bdtpolicy.go b/internal/sbi/api_bdtpolicy.go index 2a4f3b5..9880836 100644 --- a/internal/sbi/api_bdtpolicy.go +++ b/internal/sbi/api_bdtpolicy.go @@ -20,7 +20,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" + "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/util/httpwrapper" ) @@ -77,7 +77,7 @@ func (s *Server) HTTPCreateBDTPolicy(c *gin.Context) { } req := httpwrapper.NewRequest(c.Request, bdtReqData) - rsp := producer.HandleCreateBDTPolicyContextRequest(req) + rsp := s.processor.HandleCreateBDTPolicyContextRequest(req) // step 5: response for key, val := range rsp.Header { // header response is optional c.Header(key, val[0]) @@ -102,7 +102,7 @@ func (s *Server) HTTPGetBDTPolicy(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["bdtPolicyId"] = c.Params.ByName("bdtPolicyId") - rsp := producer.HandleGetBDTPolicyContextRequest(req) + rsp := processor.HandleGetBDTPolicyContextRequest(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -152,7 +152,7 @@ func (s *Server) HTTPUpdateBDTPolicy(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, bdtPolicyDataPatch) req.Params["bdtPolicyId"] = c.Params.ByName("bdtPolicyId") - rsp := producer.HandleUpdateBDTPolicyContextProcedure(req) + rsp := s.processor.HandleUpdateBDTPolicyContextProcedure(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index 6ee411c..2f0fe29 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -8,7 +8,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" + "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/util/httpwrapper" ) @@ -64,7 +64,7 @@ func (s *Server) HTTPAmfStatusChangeNotify(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, amfStatusChangeNotification) - rsp := producer.HandleAmfStatusChangeNotify(req) + rsp := processor.HandleAmfStatusChangeNotify(req) if rsp.Status == http.StatusNoContent { c.Status(rsp.Status) @@ -118,7 +118,7 @@ func (s *Server) HTTPUdrPolicyDataChangeNotify(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, policyDataChangeNotification) req.Params["supi"] = c.Params.ByName("supi") - rsp := producer.HandlePolicyDataChangeNotify(req) + rsp := processor.HandlePolicyDataChangeNotify(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -168,7 +168,7 @@ func (s *Server) HTTPUdrInfluenceDataUpdateNotify(c *gin.Context) { req.Params["supi"] = c.Params.ByName("supi") req.Params["pduSessionId"] = c.Params.ByName("pduSessionId") - rsp := producer.HandleInfluenceDataUpdateNotify(req) + rsp := processor.HandleInfluenceDataUpdateNotify(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { diff --git a/internal/sbi/api_oam.go b/internal/sbi/api_oam.go index 4ead79b..e3c2caa 100644 --- a/internal/sbi/api_oam.go +++ b/internal/sbi/api_oam.go @@ -8,7 +8,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" + "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/util/httpwrapper" ) @@ -27,7 +27,7 @@ func (s *Server) HTTPOAMGetAmPolicy(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["supi"] = c.Params.ByName("supi") - rsp := producer.HandleOAMGetAmPolicyRequest(req) + rsp := processor.HandleOAMGetAmPolicyRequest(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { diff --git a/internal/sbi/api_policyauthorization.go b/internal/sbi/api_policyauthorization.go index 3fc0f08..4a03e81 100644 --- a/internal/sbi/api_policyauthorization.go +++ b/internal/sbi/api_policyauthorization.go @@ -17,7 +17,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" + "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/pcf/internal/util" "github.com/free5gc/util/httpwrapper" ) @@ -98,7 +98,7 @@ func (s *Server) HTTPPostAppSessions(c *gin.Context) { } req := httpwrapper.NewRequest(c.Request, appSessionContext) - rsp := producer.HandlePostAppSessionsContext(req) + rsp := s.processor.HandlePostAppSessionsContext(req) for key, val := range rsp.Header { c.Header(key, val[0]) @@ -123,7 +123,7 @@ func (s *Server) HTTPDeleteEventsSubsc(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - rsp := producer.HandleDeleteEventsSubscContext(req) + rsp := processor.HandleDeleteEventsSubscContext(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -179,7 +179,7 @@ func (s *Server) HTTPUpdateEventsSubsc(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - rsp := producer.HandleUpdateEventsSubscContext(req) + rsp := processor.HandleUpdateEventsSubscContext(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -232,7 +232,7 @@ func (s *Server) HTTPDeleteAppSession(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - rsp := producer.HandleDeleteAppSessionContext(req) + rsp := processor.HandleDeleteAppSessionContext(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -253,7 +253,7 @@ func (s *Server) HTTPGetAppSession(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - rsp := producer.HandleGetAppSessionContext(req) + rsp := processor.HandleGetAppSessionContext(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -302,7 +302,7 @@ func (s *Server) HTTPModAppSession(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, appSessionContextUpdateData) req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - rsp := producer.HandleModAppSessionContext(req) + rsp := s.processor.HandleModAppSessionContext(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { diff --git a/internal/sbi/api_smpolicy.go b/internal/sbi/api_smpolicy.go index cadff99..bf303d8 100644 --- a/internal/sbi/api_smpolicy.go +++ b/internal/sbi/api_smpolicy.go @@ -17,7 +17,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/producer" + "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/util/httpwrapper" ) @@ -78,7 +78,7 @@ func (s *Server) HTTPSmPoliciesPost(c *gin.Context) { } req := httpwrapper.NewRequest(c.Request, smPolicyContextData) - rsp := producer.HandleCreateSmPolicyRequest(req) + rsp := s.processor.HandleCreateSmPolicyRequest(req) // step 5: response for key, val := range rsp.Header { // header response is optional @@ -103,7 +103,7 @@ func (s *Server) HTTPSmPoliciesSmPolicyIdDeletePost(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") - rsp := producer.HandleDeleteSmPolicyContextRequest(req) + rsp := s.processor.HandleDeleteSmPolicyContextRequest(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -124,7 +124,7 @@ func (s *Server) HTTPSmPoliciesSmPolicyIDGet(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, nil) req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") - rsp := producer.HandleGetSmPolicyContextRequest(req) + rsp := processor.HandleGetSmPolicyContextRequest(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { @@ -174,7 +174,7 @@ func (s *Server) HTTPSmPoliciesSmPolicyIdUpdatePost(c *gin.Context) { req := httpwrapper.NewRequest(c.Request, smPolicyUpdateContextData) req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") - rsp := producer.HandleUpdateSmPolicyContextRequest(req) + rsp := processor.HandleUpdateSmPolicyContextRequest(req) responseBody, err := openapi.Serialize(rsp.Body, "application/json") if err != nil { diff --git a/internal/sbi/server.go b/internal/sbi/server.go index bd05af5..7baba8a 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -55,7 +55,7 @@ type pcf interface { Config() *factory.Config Context() *pcf_context.PCFContext CancelContext() context.Context - // Processor() *processor.Processor + Processor() *processor.Processor Consumer() *consumer.Consumer } @@ -64,7 +64,7 @@ type Server struct { httpServer *http.Server router *gin.Engine - // processor *processor.Processor + processor *processor.Processor } func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { From 8ed17b3cab2e27037deac3123120f102d1d7b304 Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Wed, 8 May 2024 10:19:22 +0000 Subject: [PATCH 07/20] fix: modified RegisterNFInstance function in consumer and server --- internal/sbi/consumer/nrf_service.go | 21 +++++++++++---------- internal/sbi/server.go | 12 ++++++++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 8ba6d76..1083293 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -1,6 +1,7 @@ package consumer import ( + "context" "fmt" "net/http" "strings" @@ -206,26 +207,25 @@ func (s *nnrfService) BuildNFInstance(context *pcf_context.PCFContext) (profile } return } - -func (s *nnrfService) SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfile) ( +func (s *nnrfService) SendRegisterNFInstance(ctx context.Context) ( resouceNrfUri string, retrieveNfInstanceID string, err error, ) { // Set client and set url - client := s.getNFManagementClient(nrfUri) + pcfContext := s.consumer.Context() - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + client := s.getNFManagementClient(pcfContext.NrfUri) + nfProfile, err := s.BuildNFInstance(pcfContext) if err != nil { return "", "", - errors.Errorf("SendRegisterNFInstance error: %+v", err) + errors.Wrap(err, "RegisterNFInstance buildNfProfile()") } - var res *http.Response var nf models.NfProfile + var res *http.Response for { - nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, nfInstanceId, profile) + nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), pcfContext.NfId, nfProfile) if err != nil || res == nil { - // TODO : add log - fmt.Println(fmt.Errorf("PCF register to NRF Error[%v]", err.Error())) + logger.ConsumerLog.Errorf("CHF register to NRF Error[%v]", err) time.Sleep(2 * time.Second) continue } @@ -253,12 +253,13 @@ func (s *nnrfService) SendRegisterNFInstance(nrfUri, nfInstanceId string, profil } } pcf_context.GetSelf().OAuth2Required = oauth2 - if oauth2 && pcf_context.GetSelf().NrfCertPem == "" { logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") } + break } else { + fmt.Println(fmt.Errorf("handler returned wrong status code %d", status)) fmt.Println("NRF return wrong status code", status) } } diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 7baba8a..be5fc58 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -18,10 +18,10 @@ import ( pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/sbi/consumer" - "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/pcf/pkg/factory" "github.com/free5gc/util/httpwrapper" + logger_util "github.com/free5gc/util/logger" ) const ( @@ -69,7 +69,8 @@ type Server struct { func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { s := &Server{ - pcf: pcf, + pcf: pcf, + router: logger_util.NewGinWithLogrus(logger.GinLog), } smPolicyRoutes := s.getSmPolicyRoutes() @@ -126,8 +127,15 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { } func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { + var err error + _, s.Context().NfId, err = s.Consumer().SendRegisterNFInstance(context.Background()) + if err != nil { + logger.InitLog.Errorf("CHF register to NRF Error[%s]", err.Error()) + } + wg.Add(1) go s.startServer(wg) + return nil } From c26afc818473ed83a7c6a40105cda396c1711a4e Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Mon, 13 May 2024 08:47:27 +0000 Subject: [PATCH 08/20] refactor: oam processor --- internal/sbi/api_oam.go | 43 ++++++++++++++++------------------- internal/sbi/processor/oam.go | 32 +++++++++++++++++++------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/internal/sbi/api_oam.go b/internal/sbi/api_oam.go index e3c2caa..5627e8b 100644 --- a/internal/sbi/api_oam.go +++ b/internal/sbi/api_oam.go @@ -4,12 +4,6 @@ import ( "net/http" "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/processor" - "github.com/free5gc/util/httpwrapper" ) func (s *Server) setCorsHeader(c *gin.Context) { @@ -24,23 +18,26 @@ func (s *Server) setCorsHeader(c *gin.Context) { func (s *Server) HTTPOAMGetAmPolicy(c *gin.Context) { s.setCorsHeader(c) - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - - rsp := processor.HandleOAMGetAmPolicyRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.OamLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + supi := c.Params.ByName("supi") + s.Processor().HandleOAMGetAmPolicyRequest(c, supi) + + // req := httpwrapper.NewRequest(c.Request, nil) + // req.Params["supi"] = c.Params.ByName("supi") + + // rsp := processor.HandleOAMGetAmPolicyRequest(req) + + // responseBody, err := openapi.Serialize(rsp.Body, "application/json") + // if err != nil { + // logger.OamLog.Errorln(err) + // problemDetails := models.ProblemDetails{ + // Status: http.StatusInternalServerError, + // Cause: "SYSTEM_FAILURE", + // Detail: err.Error(), + // } + // c.JSON(http.StatusInternalServerError, problemDetails) + // } else { + // c.Data(rsp.Status, "application/json", responseBody) + // } } func (s *Server) getOamRoutes() []Route { diff --git a/internal/sbi/processor/oam.go b/internal/sbi/processor/oam.go index 414b525..48fc815 100644 --- a/internal/sbi/processor/oam.go +++ b/internal/sbi/processor/oam.go @@ -4,10 +4,11 @@ import ( "net/http" "strconv" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/util/httpwrapper" ) type UEAmPolicy struct { @@ -23,28 +24,43 @@ type UEAmPolicy struct { type UEAmPolicys []UEAmPolicy -func HandleOAMGetAmPolicyRequest(request *httpwrapper.Request) *httpwrapper.Response { +func HandleOAMGetAmPolicyRequest( + c *gin.Context, + supi string) { // step 1: log logger.OamLog.Infof("Handle OAMGetAmPolicy") // step 2: retrieve request - supi := request.Params["supi"] // step 3: handle the message response, problemDetails := OAMGetAmPolicyProcedure(supi) - // step 4: process the return value from step 3 if response != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusOK, nil, response) + c.JSON(http.StatusOK, response) + return } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) + return } + problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) + + // step 4: process the return value from step 3 + // if response != nil { + // // status code is based on SPEC, and option headers + // return httpwrapper.NewResponse(http.StatusOK, nil, response) + // } else if problemDetails != nil { + // return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + // } + // problemDetails = &models.ProblemDetails{ + // Status: http.StatusForbidden, + // Cause: "UNSPECIFIED", + // } + // return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) } func OAMGetAmPolicyProcedure(supi string) (response *UEAmPolicys, problemDetails *models.ProblemDetails) { From dff8933e09354a96161c6d20e443136c94e727be Mon Sep 17 00:00:00 2001 From: HanHongChen Date: Mon, 13 May 2024 13:13:51 +0000 Subject: [PATCH 09/20] refactor: processor-ampolicy finish --- internal/sbi/api_ampolicy.go | 121 ++++++++++++++--------------- internal/sbi/processor/ampolicy.go | 76 +++++++++--------- internal/sbi/processor/oam.go | 2 +- 3 files changed, 98 insertions(+), 101 deletions(-) diff --git a/internal/sbi/api_ampolicy.go b/internal/sbi/api_ampolicy.go index 973792d..97f7328 100644 --- a/internal/sbi/api_ampolicy.go +++ b/internal/sbi/api_ampolicy.go @@ -8,50 +8,38 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" ) func (s *Server) HTTPPoliciesPolAssoIdDelete(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["polAssoId"], _ = c.Params.Get("polAssoId") + polAssoId := c.Param("polAssoId") - rsp := processor.HandleDeletePoliciesPolAssoId(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.AmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + if polAssoId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleDeletePoliciesPolAssoId(c, polAssoId) } // HTTPPoliciesPolAssoIdGet - func (s *Server) HTTPPoliciesPolAssoIdGet(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["polAssoId"], _ = c.Params.Get("polAssoId") - - rsp := processor.HandleGetPoliciesPolAssoId(req) + polAssoId := c.Param("polAssoId") - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.AmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + if polAssoId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleGetPoliciesPolAssoId(c, polAssoId) } // HTTPPoliciesPolAssoIdUpdatePost - @@ -84,23 +72,19 @@ func (s *Server) HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, policyAssociationUpdateRequest) - req.Params["polAssoId"], _ = c.Params.Get("polAssoId") + polAssoId := c.Param("polAssoId") - rsp := processor.HandleUpdatePostPoliciesPolAssoId(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.AmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + if polAssoId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleUpdatePostPoliciesPolAssoId(c, polAssoId, policyAssociationUpdateRequest) + } // HTTPPoliciesPost - @@ -140,27 +124,40 @@ func (s *Server) HTTPPoliciesPost(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, policyAssociationRequest) - req.Params["polAssoId"], _ = c.Params.Get("polAssoId") + polAssoId := c.Param("polAssoId") - rsp := s.processor.HandlePostPolicies(req) - - for key, val := range rsp.Header { - c.Header(key, val[0]) - } - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.AmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + if polAssoId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandlePostPolicies(c, polAssoId, policyAssociationRequest) + + // req := httpwrapper.NewRequest(c.Request, policyAssociationRequest) + // req.Params["polAssoId"], _ = c.Params.Get("polAssoId") + + // rsp := s.processor.HandlePostPolicies(req) + + // for key, val := range rsp.Header { + // c.Header(key, val[0]) + // } + + // responseBody, err := openapi.Serialize(rsp.Body, "application/json") + // if err != nil { + // logger.AmPolicyLog.Errorln(err) + // problemDetails := models.ProblemDetails{ + // Status: http.StatusInternalServerError, + // Cause: "SYSTEM_FAILURE", + // Detail: err.Error(), + // } + // c.JSON(http.StatusInternalServerError, problemDetails) + // } else { + // c.Data(rsp.Status, "application/json", responseBody) + // } } func (s *Server) getAmPolicyRoutes() []Route { diff --git a/internal/sbi/processor/ampolicy.go b/internal/sbi/processor/ampolicy.go index f4d5d19..fd89fa4 100644 --- a/internal/sbi/processor/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -5,6 +5,7 @@ import ( "net/http" "reflect" + "github.com/gin-gonic/gin" "github.com/mohae/deepcopy" "github.com/free5gc/openapi" @@ -12,49 +13,43 @@ import ( pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" ) -func HandleDeletePoliciesPolAssoId(request *httpwrapper.Request) *httpwrapper.Response { - logger.AmPolicyLog.Infof("Handle AM Policy Association Delete") - - polAssoId := request.Params["polAssoId"] +func (p *Processor) HandleDeletePoliciesPolAssoId( + c *gin.Context, + polAssoId string) { - problemDetails := DeletePoliciesPolAssoIdProcedure(polAssoId) - if problemDetails == nil { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } else { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } -} + logger.AmPolicyLog.Infof("Handle AM Policy Association Delete") -func DeletePoliciesPolAssoIdProcedure(polAssoId string) *models.ProblemDetails { ue := pcf_context.GetSelf().PCFUeFindByPolicyId(polAssoId) if ue == nil || ue.AMPolicyData[polAssoId] == nil { problemDetails := util.GetProblemDetail("polAssoId not found in PCF", util.CONTEXT_NOT_FOUND) - return &problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } + delete(ue.AMPolicyData, polAssoId) - return nil + c.JSON(http.StatusNoContent, nil) } // PoliciesPolAssoIdGet - -func HandleGetPoliciesPolAssoId(request *httpwrapper.Request) *httpwrapper.Response { - logger.AmPolicyLog.Infof("Handle AM Policy Association Get") +func (p *Processor) HandleGetPoliciesPolAssoId( + c *gin.Context, + polAssoId string) { - polAssoId := request.Params["polAssoId"] + logger.AmPolicyLog.Infof("Handle AM Policy Association Get") response, problemDetails := GetPoliciesPolAssoIdProcedure(polAssoId) if response != nil { - return httpwrapper.NewResponse(http.StatusOK, nil, response) + c.JSON(http.StatusOK, response) } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } + problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", } - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } func GetPoliciesPolAssoIdProcedure(polAssoId string) (*models.PolicyAssociation, *models.ProblemDetails) { @@ -85,23 +80,25 @@ func GetPoliciesPolAssoIdProcedure(polAssoId string) (*models.PolicyAssociation, return &rsp, nil } -func HandleUpdatePostPoliciesPolAssoId(request *httpwrapper.Request) *httpwrapper.Response { - logger.AmPolicyLog.Infof("Handle AM Policy Association Update") +func (p *Processor) HandleUpdatePostPoliciesPolAssoId( + c *gin.Context, + polAssoId string, + policyAssociationUpdateRequest models.PolicyAssociationUpdateRequest) { - polAssoId := request.Params["polAssoId"] - policyAssociationUpdateRequest := request.Body.(models.PolicyAssociationUpdateRequest) + logger.AmPolicyLog.Infof("Handle AM Policy Association Update") response, problemDetails := UpdatePostPoliciesPolAssoIdProcedure(polAssoId, policyAssociationUpdateRequest) if response != nil { - return httpwrapper.NewResponse(http.StatusOK, nil, response) + c.JSON(http.StatusOK, response) } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } + problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", } - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } func UpdatePostPoliciesPolAssoIdProcedure(polAssoId string, @@ -178,26 +175,29 @@ func UpdatePostPoliciesPolAssoIdProcedure(polAssoId string, } // Create AM Policy -func (p *Processor) HandlePostPolicies(request *httpwrapper.Request) *httpwrapper.Response { - logger.AmPolicyLog.Infof("Handle AM Policy Create Request") +func (p *Processor) HandlePostPolicies( + c *gin.Context, + polAssoId string, + policyAssociationRequest models.PolicyAssociationRequest, +) { - polAssoId := request.Params["polAssoId"] - policyAssociationRequest := request.Body.(models.PolicyAssociationRequest) + logger.AmPolicyLog.Infof("Handle AM Policy Create Request") response, locationHeader, problemDetails := p.PostPoliciesProcedure(polAssoId, policyAssociationRequest) - headers := http.Header{ - "Location": {locationHeader}, - } if response != nil { - return httpwrapper.NewResponse(http.StatusCreated, headers, response) + // TODO: set gin header + c.Header("Location", locationHeader) + c.JSON(http.StatusCreated, response) } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } + problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", } - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) + } func (p *Processor) PostPoliciesProcedure(polAssoId string, diff --git a/internal/sbi/processor/oam.go b/internal/sbi/processor/oam.go index 48fc815..5e810d8 100644 --- a/internal/sbi/processor/oam.go +++ b/internal/sbi/processor/oam.go @@ -24,7 +24,7 @@ type UEAmPolicy struct { type UEAmPolicys []UEAmPolicy -func HandleOAMGetAmPolicyRequest( +func (p *Processor) HandleOAMGetAmPolicyRequest( c *gin.Context, supi string) { // step 1: log From 1f6d3c89c8f0a958cb513f82bfe0e10fe3da0cb5 Mon Sep 17 00:00:00 2001 From: chh Date: Tue, 14 May 2024 12:09:00 +0000 Subject: [PATCH 10/20] refactor: processor finish --- internal/sbi/api_ampolicy.go | 22 -- internal/sbi/api_bdtpolicy.go | 73 +--- internal/sbi/api_httpcallback.go | 63 +--- internal/sbi/api_oam.go | 18 - internal/sbi/api_policyauthorization.go | 142 +++---- internal/sbi/api_smpolicy.go | 89 +---- internal/sbi/processor/ampolicy.go | 21 +- internal/sbi/processor/bdtpolicy.go | 159 +++----- internal/sbi/processor/callback.go | 57 ++- internal/sbi/processor/oam.go | 43 +-- internal/sbi/processor/policyauthorization.go | 356 ++++++++---------- internal/sbi/processor/smpolicy.go | 246 +++++------- 12 files changed, 449 insertions(+), 840 deletions(-) diff --git a/internal/sbi/api_ampolicy.go b/internal/sbi/api_ampolicy.go index 97f7328..dbdc2ee 100644 --- a/internal/sbi/api_ampolicy.go +++ b/internal/sbi/api_ampolicy.go @@ -87,7 +87,6 @@ func (s *Server) HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { } -// HTTPPoliciesPost - func (s *Server) HTTPPoliciesPost(c *gin.Context) { var policyAssociationRequest models.PolicyAssociationRequest @@ -137,27 +136,6 @@ func (s *Server) HTTPPoliciesPost(c *gin.Context) { s.Processor().HandlePostPolicies(c, polAssoId, policyAssociationRequest) - // req := httpwrapper.NewRequest(c.Request, policyAssociationRequest) - // req.Params["polAssoId"], _ = c.Params.Get("polAssoId") - - // rsp := s.processor.HandlePostPolicies(req) - - // for key, val := range rsp.Header { - // c.Header(key, val[0]) - // } - - // responseBody, err := openapi.Serialize(rsp.Body, "application/json") - // if err != nil { - // logger.AmPolicyLog.Errorln(err) - // problemDetails := models.ProblemDetails{ - // Status: http.StatusInternalServerError, - // Cause: "SYSTEM_FAILURE", - // Detail: err.Error(), - // } - // c.JSON(http.StatusInternalServerError, problemDetails) - // } else { - // c.Data(rsp.Status, "application/json", responseBody) - // } } func (s *Server) getAmPolicyRoutes() []Route { diff --git a/internal/sbi/api_bdtpolicy.go b/internal/sbi/api_bdtpolicy.go index 9880836..b45a447 100644 --- a/internal/sbi/api_bdtpolicy.go +++ b/internal/sbi/api_bdtpolicy.go @@ -20,8 +20,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/processor" - "github.com/free5gc/util/httpwrapper" + "github.com/free5gc/pcf/internal/util" ) func (s *Server) getBdtPolicyRoutes() []Route { @@ -44,8 +43,6 @@ func (s *Server) getBdtPolicyRoutes() []Route { } } -// api_bdt_policy -// CreateBDTPolicy - Create a new Individual BDT policy func (s *Server) HTTPCreateBDTPolicy(c *gin.Context) { var bdtReqData models.BdtReqData // step 1: retrieve http request body @@ -76,46 +73,21 @@ func (s *Server) HTTPCreateBDTPolicy(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, bdtReqData) - rsp := s.processor.HandleCreateBDTPolicyContextRequest(req) - // step 5: response - for key, val := range rsp.Header { // header response is optional - c.Header(key, val[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.BdtPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + s.Processor().HandleCreateBDTPolicyContextRequest(c, bdtReqData) + } -// api_individual -// GetBDTPolicy - Read an Individual BDT policy func (s *Server) HTTPGetBDTPolicy(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["bdtPolicyId"] = c.Params.ByName("bdtPolicyId") - - rsp := processor.HandleGetBDTPolicyContextRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.BdtPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + bdtPolicyId := c.Params.ByName("bdtPolicyId") + if bdtPolicyId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + s.Processor().HandleGetBDTPolicyContextRequest(c, bdtPolicyId) } // UpdateBDTPolicy - Update an Individual BDT policy @@ -149,21 +121,14 @@ func (s *Server) HTTPUpdateBDTPolicy(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, bdtPolicyDataPatch) - req.Params["bdtPolicyId"] = c.Params.ByName("bdtPolicyId") - - rsp := s.processor.HandleUpdateBDTPolicyContextProcedure(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.BdtPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + bdtPolicyId := c.Params.ByName("bdtPolicyId") + if bdtPolicyId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + s.Processor().HandleUpdateBDTPolicyContextProcedure(c, bdtPolicyId, bdtPolicyDataPatch) } diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index 2f0fe29..f1ddb79 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -8,8 +8,6 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/processor" - "github.com/free5gc/util/httpwrapper" ) func (s *Server) getHttpCallBackRoutes() []Route { @@ -62,26 +60,7 @@ func (s *Server) HTTPAmfStatusChangeNotify(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, amfStatusChangeNotification) - - rsp := processor.HandleAmfStatusChangeNotify(req) - - if rsp.Status == http.StatusNoContent { - c.Status(rsp.Status) - } else { - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.CallbackLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } - } + s.Processor().HandleAmfStatusChangeNotify(c, amfStatusChangeNotification) } // sm_policy_notify @@ -115,23 +94,8 @@ func (s *Server) HTTPUdrPolicyDataChangeNotify(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, policyDataChangeNotification) - req.Params["supi"] = c.Params.ByName("supi") - - rsp := processor.HandlePolicyDataChangeNotify(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.CallbackLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + supi := c.Params.ByName("supi") + s.Processor().HandlePolicyDataChangeNotify(c, supi, policyDataChangeNotification) } // Influence Data Update Notification @@ -164,22 +128,7 @@ func (s *Server) HTTPUdrInfluenceDataUpdateNotify(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, trafficInfluDataNotif) - req.Params["supi"] = c.Params.ByName("supi") - req.Params["pduSessionId"] = c.Params.ByName("pduSessionId") - - rsp := processor.HandleInfluenceDataUpdateNotify(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.CallbackLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + supi := c.Params.ByName("supi") + pduSessionId := c.Params.ByName("pduSessionId") + s.Processor().HandleInfluenceDataUpdateNotify(c, supi, pduSessionId, trafficInfluDataNotif) } diff --git a/internal/sbi/api_oam.go b/internal/sbi/api_oam.go index 5627e8b..177be54 100644 --- a/internal/sbi/api_oam.go +++ b/internal/sbi/api_oam.go @@ -20,24 +20,6 @@ func (s *Server) HTTPOAMGetAmPolicy(c *gin.Context) { supi := c.Params.ByName("supi") s.Processor().HandleOAMGetAmPolicyRequest(c, supi) - - // req := httpwrapper.NewRequest(c.Request, nil) - // req.Params["supi"] = c.Params.ByName("supi") - - // rsp := processor.HandleOAMGetAmPolicyRequest(req) - - // responseBody, err := openapi.Serialize(rsp.Body, "application/json") - // if err != nil { - // logger.OamLog.Errorln(err) - // problemDetails := models.ProblemDetails{ - // Status: http.StatusInternalServerError, - // Cause: "SYSTEM_FAILURE", - // Detail: err.Error(), - // } - // c.JSON(http.StatusInternalServerError, problemDetails) - // } else { - // c.Data(rsp.Status, "application/json", responseBody) - // } } func (s *Server) getOamRoutes() []Route { diff --git a/internal/sbi/api_policyauthorization.go b/internal/sbi/api_policyauthorization.go index 4a03e81..cbf6f36 100644 --- a/internal/sbi/api_policyauthorization.go +++ b/internal/sbi/api_policyauthorization.go @@ -17,9 +17,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/processor" "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" ) func (s *Server) getPolicyAuthorizationRoutes() []Route { @@ -97,46 +95,24 @@ func (s *Server) HTTPPostAppSessions(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, appSessionContext) - rsp := s.processor.HandlePostAppSessionsContext(req) - - for key, val := range rsp.Header { - c.Header(key, val[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + s.Processor().HandlePostAppSessionsContext(c, appSessionContext) } // api_events_subscription // HTTPDeleteEventsSubsc - deletes the Events Subscription subresource func (s *Server) HTTPDeleteEventsSubsc(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := processor.HandleDeleteEventsSubscContext(req) - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + appSessionId := c.Params.ByName("appSessionId") + if appSessionId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleDeleteEventsSubscContext(c, appSessionId) } // HTTPUpdateEventsSubsc - creates or modifies an Events Subscription subresource @@ -176,27 +152,19 @@ func (s *Server) HTTPUpdateEventsSubsc(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := processor.HandleUpdateEventsSubscContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + appSessionId := c.Params.ByName("appSessionId") + if appSessionId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleUpdateEventsSubscContext(c, appSessionId, eventsSubscReqData) } -// api_individual -// HTTPDeleteAppSession - Deletes an existing Individual Application Session Context func (s *Server) HTTPDeleteAppSession(c *gin.Context) { var eventsSubscReqData *models.EventsSubscReqData @@ -229,44 +197,32 @@ func (s *Server) HTTPDeleteAppSession(c *gin.Context) { } } - req := httpwrapper.NewRequest(c.Request, eventsSubscReqData) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := processor.HandleDeleteAppSessionContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + appSessionId := c.Params.ByName("appSessionId") + if appSessionId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleDeleteAppSessionContext(c, appSessionId, eventsSubscReqData) } // HTTPGetAppSession - Reads an existing Individual Application Session Context func (s *Server) HTTPGetAppSession(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := processor.HandleGetAppSessionContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + appSessionId := c.Params.ByName("appSessionId") + if appSessionId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleGetAppSessionContext(c, appSessionId) } // HTTPModAppSession - Modifies an existing Individual Application Session Context @@ -299,21 +255,15 @@ func (s *Server) HTTPModAppSession(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, appSessionContextUpdateData) - req.Params["appSessionId"], _ = c.Params.Get("appSessionId") - - rsp := s.processor.HandleModAppSessionContext(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PolicyAuthLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + appSessionId := c.Params.ByName("appSessionId") + if appSessionId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + + s.Processor().HandleModAppSessionContext(c, appSessionId, appSessionContextUpdateData) } diff --git a/internal/sbi/api_smpolicy.go b/internal/sbi/api_smpolicy.go index bf303d8..0ac65b6 100644 --- a/internal/sbi/api_smpolicy.go +++ b/internal/sbi/api_smpolicy.go @@ -17,8 +17,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" - "github.com/free5gc/pcf/internal/sbi/processor" - "github.com/free5gc/util/httpwrapper" + "github.com/free5gc/pcf/internal/util" ) func (s *Server) getSmPolicyRoutes() []Route { @@ -77,70 +76,37 @@ func (s *Server) HTTPSmPoliciesPost(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, smPolicyContextData) - rsp := s.processor.HandleCreateSmPolicyRequest(req) - - // step 5: response - for key, val := range rsp.Header { // header response is optional - c.Header(key, val[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + s.Processor().HandleCreateSmPolicyRequest(c, smPolicyContextData) } // SmPoliciesSmPolicyIdDeletePost - func (s *Server) HTTPSmPoliciesSmPolicyIdDeletePost(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") - - rsp := s.processor.HandleDeleteSmPolicyContextRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + smPolicyId := c.Params.ByName("smPolicyId") + if smPolicyId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + s.Processor().HandleDeleteSmPolicyContextRequest(c, smPolicyId) } // SmPoliciesSmPolicyIdGet - func (s *Server) HTTPSmPoliciesSmPolicyIDGet(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") - - rsp := processor.HandleGetSmPolicyContextRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + smPolicyId := c.Params.ByName("smPolicyId") + if smPolicyId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + c.JSON(http.StatusBadRequest, problemDetails) + return } + s.Processor().HandleGetSmPolicyContextRequest(c, smPolicyId) } -// SmPoliciesSmPolicyIdUpdatePost - func (s *Server) HTTPSmPoliciesSmPolicyIdUpdatePost(c *gin.Context) { var smPolicyUpdateContextData models.SmPolicyUpdateContextData // step 1: retrieve http request body @@ -171,21 +137,6 @@ func (s *Server) HTTPSmPoliciesSmPolicyIdUpdatePost(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, smPolicyUpdateContextData) - req.Params["smPolicyId"] = c.Params.ByName("smPolicyId") - - rsp := processor.HandleUpdateSmPolicyContextRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SmPolicyLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + smPolicyId := c.Params.ByName("smPolicyId") + s.Processor().HandleUpdateSmPolicyContextRequest(c, smPolicyId, smPolicyUpdateContextData) } diff --git a/internal/sbi/processor/ampolicy.go b/internal/sbi/processor/ampolicy.go index fd89fa4..783a649 100644 --- a/internal/sbi/processor/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -38,25 +38,12 @@ func (p *Processor) HandleGetPoliciesPolAssoId( logger.AmPolicyLog.Infof("Handle AM Policy Association Get") - response, problemDetails := GetPoliciesPolAssoIdProcedure(polAssoId) - if response != nil { - c.JSON(http.StatusOK, response) - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - } - - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(int(problemDetails.Status), problemDetails) -} - -func GetPoliciesPolAssoIdProcedure(polAssoId string) (*models.PolicyAssociation, *models.ProblemDetails) { + // response, problemDetails := GetPoliciesPolAssoIdProcedure(polAssoId) ue := pcf_context.GetSelf().PCFUeFindByPolicyId(polAssoId) if ue == nil || ue.AMPolicyData[polAssoId] == nil { problemDetails := util.GetProblemDetail("polAssoId not found in PCF", util.CONTEXT_NOT_FOUND) - return nil, &problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } amPolicyData := ue.AMPolicyData[polAssoId] rsp := models.PolicyAssociation{ @@ -77,7 +64,7 @@ func GetPoliciesPolAssoIdProcedure(polAssoId string) (*models.PolicyAssociation, } } } - return &rsp, nil + c.JSON(http.StatusOK, rsp) } func (p *Processor) HandleUpdatePostPoliciesPolAssoId( diff --git a/internal/sbi/processor/bdtpolicy.go b/internal/sbi/processor/bdtpolicy.go index c236103..0066c31 100644 --- a/internal/sbi/processor/bdtpolicy.go +++ b/internal/sbi/processor/bdtpolicy.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/antihax/optional" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/mohae/deepcopy" @@ -14,78 +15,39 @@ import ( pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" ) -func HandleGetBDTPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleGetBDTPolicyContextRequest( + c *gin.Context, + bdtPolicyID string) { // step 1: log logger.BdtPolicyLog.Infof("Handle GetBDTPolicyContext") - // step 2: retrieve request - bdtPolicyID := request.Params["bdtPolicyId"] - - // step 3: handle the message - response, problemDetails := getBDTPolicyContextProcedure(bdtPolicyID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) -} - -func getBDTPolicyContextProcedure(bdtPolicyID string) ( - response *models.BdtPolicy, problemDetails *models.ProblemDetails, -) { + // step 2: handle the message logger.BdtPolicyLog.Traceln("Handle BDT Policy GET") // check bdtPolicyID from pcfUeContext if value, ok := pcf_context.GetSelf().BdtPolicyPool.Load(bdtPolicyID); ok { bdtPolicy := value.(*models.BdtPolicy) - return bdtPolicy, nil + c.JSON(http.StatusOK, bdtPolicy) + return } else { // not found - problemDetail := util.GetProblemDetail("Can't find bdtPolicyID related resource", util.CONTEXT_NOT_FOUND) - logger.BdtPolicyLog.Warnf(problemDetail.Detail) - return nil, &problemDetail + problemDetails := util.GetProblemDetail("Can't find bdtPolicyID related resource", util.CONTEXT_NOT_FOUND) + logger.BdtPolicyLog.Warnf(problemDetails.Detail) + c.JSON(int(problemDetails.Status), problemDetails) + return } } // UpdateBDTPolicy - Update an Individual BDT policy (choose policy data) -func (p *Processor) HandleUpdateBDTPolicyContextProcedure(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleUpdateBDTPolicyContextProcedure( + c *gin.Context, + bdtPolicyID string, + bdtPolicyDataPatch models.BdtPolicyDataPatch) { // step 1: log logger.BdtPolicyLog.Infof("Handle UpdateBDTPolicyContext") - // step 2: retrieve request - requestDataType := request.Body.(models.BdtPolicyDataPatch) - bdtPolicyID := request.Params["bdtPolicyId"] - - // step 3: handle the message - response, problemDetails := p.updateBDTPolicyContextProcedure(requestDataType, bdtPolicyID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) -} - -func (p *Processor) updateBDTPolicyContextProcedure(request models.BdtPolicyDataPatch, bdtPolicyID string) ( - response *models.BdtPolicy, problemDetails *models.ProblemDetails, -) { + // step 2: handle the message logger.BdtPolicyLog.Infoln("Handle BDTPolicyUpdate") // check bdtPolicyID from pcfUeContext pcfSelf := pcf_context.GetSelf() @@ -97,14 +59,15 @@ func (p *Processor) updateBDTPolicyContextProcedure(request models.BdtPolicyData // not found problemDetail := util.GetProblemDetail("Can't find bdtPolicyID related resource", util.CONTEXT_NOT_FOUND) logger.BdtPolicyLog.Warnf(problemDetail.Detail) - return nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } for _, policy := range bdtPolicy.BdtPolData.TransfPolicies { - if policy.TransPolicyId == request.SelTransPolicyId { + if policy.TransPolicyId == bdtPolicyDataPatch.SelTransPolicyId { polData := bdtPolicy.BdtPolData polReq := bdtPolicy.BdtReqData - polData.SelTransPolicyId = request.SelTransPolicyId + polData.SelTransPolicyId = bdtPolicyDataPatch.SelTransPolicyId bdtData := models.BdtData{ AspId: polReq.AspId, TransPolicy: policy, @@ -119,7 +82,8 @@ func (p *Processor) updateBDTPolicyContextProcedure(request models.BdtPolicyData client := util.GetNudrClient(p.getDefaultUdrUri(pcfSelf)) ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } rsp, err := client.DefaultApi.PolicyDataBdtDataBdtReferenceIdPut(ctx, bdtData.BdtRefId, ¶m) if err != nil { @@ -131,49 +95,40 @@ func (p *Processor) updateBDTPolicyContextProcedure(request models.BdtPolicyData } }() logger.BdtPolicyLog.Tracef("bdtPolicyID[%s] has Updated with SelTransPolicyId[%d]", - bdtPolicyID, request.SelTransPolicyId) - return bdtPolicy, nil + bdtPolicyID, bdtPolicyDataPatch.SelTransPolicyId) + c.JSON(http.StatusOK, bdtPolicy) + return } } problemDetail := util.GetProblemDetail( fmt.Sprintf("Can't find TransPolicyId[%d] in TransfPolicies with bdtPolicyID[%s]", - request.SelTransPolicyId, bdtPolicyID), + bdtPolicyDataPatch.SelTransPolicyId, bdtPolicyID), util.CONTEXT_NOT_FOUND) logger.BdtPolicyLog.Warnf(problemDetail.Detail) - return nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) } // CreateBDTPolicy - Create a new Individual BDT policy -func (p *Processor) HandleCreateBDTPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleCreateBDTPolicyContextRequest( + c *gin.Context, + requestMsg models.BdtReqData) { // step 1: log logger.BdtPolicyLog.Infof("Handle CreateBDTPolicyContext") + var problemDetails *models.ProblemDetails + // step 2: retrieve request and check mandatory contents - requestMsg := request.Body.(models.BdtReqData) + // requestMsg := request.Body.(models.BdtReqData) if requestMsg.AspId == "" || requestMsg.DesTimeInt == nil || requestMsg.NumOfUes == 0 || requestMsg.VolPerUe == nil { logger.BdtPolicyLog.Errorf("Required BdtReqData not found: AspId[%+v], DesTimeInt[%+v], NumOfUes[%+v], VolPerUe[%+v]", requestMsg.AspId, requestMsg.DesTimeInt, requestMsg.NumOfUes, requestMsg.VolPerUe) - return httpwrapper.NewResponse(http.StatusNotFound, nil, nil) + c.JSON(http.StatusNotFound, nil) + return } - // step 3: handle the message - header, response, problemDetails := p.createBDTPolicyContextProcedure(&requestMsg) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusCreated, header, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNotFound, nil, nil) - } -} + // // step 3: handle the message -func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) ( - header http.Header, response *models.BdtPolicy, problemDetails *models.ProblemDetails, -) { - response = &models.BdtPolicy{} + response := &models.BdtPolicy{} logger.BdtPolicyLog.Traceln("Handle BDT Policy Create") pcfSelf := pcf_context.GetSelf() @@ -185,7 +140,8 @@ func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) Detail: "Can't find any UDR which supported to this PCF", } logger.BdtPolicyLog.Warnf(problemDetails.Detail) - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } pcfSelf.DefaultUdrURI = udrUri pcfSelf.SetDefaultUdrURI(udrUri) @@ -193,7 +149,8 @@ func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) // Query BDT DATA array from UDR ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } client := util.GetNudrClient(udrUri) @@ -204,7 +161,8 @@ func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) Detail: "Query to UDR failed", } logger.BdtPolicyLog.Warnf("Query to UDR failed") - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { @@ -212,12 +170,12 @@ func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) } }() // TODO: decide BDT Policy from other bdt policy data - response.BdtReqData = deepcopy.Copy(request).(*models.BdtReqData) + response.BdtReqData = deepcopy.Copy(requestMsg).(*models.BdtReqData) var bdtData *models.BdtData var bdtPolicyData models.BdtPolicyData for _, data := range bdtDatas { // If ASP has exist, use its background data policy - if request.AspId == data.AspId { + if requestMsg.AspId == data.AspId { bdtData = &data break } @@ -226,17 +184,17 @@ func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) if bdtData != nil { // found // modify policy according to new request - bdtData.TransPolicy.RecTimeInt = request.DesTimeInt + bdtData.TransPolicy.RecTimeInt = requestMsg.DesTimeInt } else { // use default bdt policy, TODO: decide bdt transfer data policy bdtData = &models.BdtData{ - AspId: request.AspId, + AspId: requestMsg.AspId, BdtRefId: uuid.New().String(), - TransPolicy: getDefaultTransferPolicy(1, *request.DesTimeInt), + TransPolicy: getDefaultTransferPolicy(1, *requestMsg.DesTimeInt), } } - if request.NwAreaInfo != nil { - bdtData.NwAreaInfo = *request.NwAreaInfo + if requestMsg.NwAreaInfo != nil { + bdtData.NwAreaInfo = *requestMsg.NwAreaInfo } bdtPolicyData.SelTransPolicyId = bdtData.TransPolicy.TransPolicyId // no support feature in subclause 5.8 of TS29554 @@ -250,7 +208,8 @@ func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) Detail: "Allocate bdtPolicyID failed", } logger.BdtPolicyLog.Warnf("Allocate bdtPolicyID failed") - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } pcfSelf.BdtPolicyPool.Store(bdtPolicyID, response) @@ -274,11 +233,17 @@ func (p *Processor) createBDTPolicyContextProcedure(request *models.BdtReqData) }() locationHeader := util.GetResourceUri(models.ServiceName_NPCF_BDTPOLICYCONTROL, bdtPolicyID) - header = http.Header{ - "Location": {locationHeader}, - } logger.BdtPolicyLog.Tracef("BDT Policy Id[%s] Create", bdtPolicyID) - return header, response, problemDetails + + if response != nil { + // status code is based on SPEC, and option headers + c.Header("Location", locationHeader) + c.JSON(http.StatusCreated, response) + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + } else { + c.JSON(http.StatusNotFound, nil) + } } func (p *Processor) getDefaultUdrUri(context *pcf_context.PCFContext) string { diff --git a/internal/sbi/processor/callback.go b/internal/sbi/processor/callback.go index fc85ea6..9476d2c 100644 --- a/internal/sbi/processor/callback.go +++ b/internal/sbi/processor/callback.go @@ -9,68 +9,57 @@ import ( pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" + "github.com/gin-gonic/gin" ) -func HandleAmfStatusChangeNotify(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleAmfStatusChangeNotify( + c *gin.Context, + amfStatusChangeNotification models.AmfStatusChangeNotification) { logger.CallbackLog.Warnf("[PCF] Handle Amf Status Change Notify is not implemented.") - notification := request.Body.(models.AmfStatusChangeNotification) + // TODO: handle AMF Status Change Notify + logger.CallbackLog.Debugf("receive AMF status change notification[%+v]", amfStatusChangeNotification) - AmfStatusChangeNotifyProcedure(notification) - - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) + c.JSON(http.StatusNoContent, nil) } -// TODO: handle AMF Status Change Notify -func AmfStatusChangeNotifyProcedure(notification models.AmfStatusChangeNotification) { - logger.CallbackLog.Debugf("receive AMF status change notification[%+v]", notification) -} +func (p *Processor) HandlePolicyDataChangeNotify( + c *gin.Context, + supi string, + policyDataChangeNotification models.PolicyDataChangeNotification) { -func HandlePolicyDataChangeNotify(request *httpwrapper.Request) *httpwrapper.Response { logger.CallbackLog.Warnf("[PCF] Handle Policy Data Change Notify is not implemented.") - notification := request.Body.(models.PolicyDataChangeNotification) - supi := request.Params["supi"] + PolicyDataChangeNotifyProcedure(supi, policyDataChangeNotification) - PolicyDataChangeNotifyProcedure(supi, notification) - - return httpwrapper.NewResponse(http.StatusNotImplemented, nil, nil) + c.JSON(http.StatusNotImplemented, nil) } // TODO: handle Policy Data Change Notify func PolicyDataChangeNotifyProcedure(supi string, notification models.PolicyDataChangeNotification) { } -func HandleInfluenceDataUpdateNotify(request *httpwrapper.Request) *httpwrapper.Response { - logger.CallbackLog.Infof("[PCF] Handle Influence Data Update Notify") - - notifications := request.Body.([]models.TrafficInfluDataNotif) - supi := request.Params["supi"] - pduSessionId := request.Params["pduSessionId"] +func (p *Processor) HandleInfluenceDataUpdateNotify( + c *gin.Context, + supi string, + pduSessionId string, + trafficInfluDataNotif []models.TrafficInfluDataNotif) { - if problemDetails := InfluenceDataUpdateNotifyProcedure(supi, pduSessionId, notifications); problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} + logger.CallbackLog.Infof("[PCF] Handle Influence Data Update Notify") -func InfluenceDataUpdateNotifyProcedure(supi, pduSessionId string, - notifications []models.TrafficInfluDataNotif, -) *models.ProblemDetails { smPolicyID := fmt.Sprintf("%s-%s", supi, pduSessionId) ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyID) if ue == nil || ue.SmPolicyData[smPolicyID] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.CallbackLog.Errorf(problemDetail.Detail) - return &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } smPolicy := ue.SmPolicyData[smPolicyID] decision := smPolicy.PolicyDecision influenceDataToPccRule := smPolicy.InfluenceDataToPccRule precedence := getAvailablePrecedence(smPolicy.PolicyDecision.PccRules) - for _, notification := range notifications { + for _, notification := range trafficInfluDataNotif { influenceID := getInfluenceID(notification.ResUri) if influenceID == "" { continue @@ -107,7 +96,7 @@ func InfluenceDataUpdateNotifyProcedure(supi, pduSessionId string, SmPolicyDecision: decision, } go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, &smPolicyNotification) - return nil + c.JSON(http.StatusNoContent, nil) } func getInfluenceID(resUri string) string { diff --git a/internal/sbi/processor/oam.go b/internal/sbi/processor/oam.go index 5e810d8..702ad8a 100644 --- a/internal/sbi/processor/oam.go +++ b/internal/sbi/processor/oam.go @@ -30,42 +30,10 @@ func (p *Processor) HandleOAMGetAmPolicyRequest( // step 1: log logger.OamLog.Infof("Handle OAMGetAmPolicy") - // step 2: retrieve request - // step 3: handle the message - response, problemDetails := OAMGetAmPolicyProcedure(supi) - - if response != nil { - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } - - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(int(problemDetails.Status), problemDetails) - - // step 4: process the return value from step 3 - // if response != nil { - // // status code is based on SPEC, and option headers - // return httpwrapper.NewResponse(http.StatusOK, nil, response) - // } else if problemDetails != nil { - // return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - // } - // problemDetails = &models.ProblemDetails{ - // Status: http.StatusForbidden, - // Cause: "UNSPECIFIED", - // } - // return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) -} -func OAMGetAmPolicyProcedure(supi string) (response *UEAmPolicys, problemDetails *models.ProblemDetails) { logger.OamLog.Infof("Handle OAM Get Am Policy") - response = &UEAmPolicys{} + response := &UEAmPolicys{} pcfSelf := context.GetSelf() if val, exists := pcfSelf.UePool.Load(supi); exists { @@ -85,12 +53,15 @@ func OAMGetAmPolicyProcedure(supi string) (response *UEAmPolicys, problemDetails } *response = append(*response, ueAmPolicy) } - return response, nil + c.JSON(http.StatusOK, response) + return } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "CONTEXT_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } + } diff --git a/internal/sbi/processor/policyauthorization.go b/internal/sbi/processor/policyauthorization.go index 9f25d18..2559776 100644 --- a/internal/sbi/processor/policyauthorization.go +++ b/internal/sbi/processor/policyauthorization.go @@ -7,13 +7,13 @@ import ( "time" "github.com/cydev/zero" + "github.com/gin-gonic/gin" "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" - "github.com/free5gc/util/httpwrapper" ) const ( @@ -128,26 +128,26 @@ func handleMediaSubComponent(smPolicy *pcf_context.UeSmPolicyData, medComp *mode // Subscription to resources allocation outcome (DONE) // Invocation of Multimedia Priority Services (TODO) // Support of content versioning (TODO) -func (p *Processor) HandlePostAppSessionsContext(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandlePostAppSessionsContext( + c *gin.Context, + appSessionContext models.AppSessionContext) { logger.PolicyAuthLog.Traceln("Handle Create AppSessions") - appSessCtx := request.Body.(models.AppSessionContext) - - response, locationHeader, problemDetails := p.postAppSessCtxProcedure(&appSessCtx) + response, locationHeader, problemDetails := p.postAppSessCtxProcedure(&appSessionContext) if response != nil { - headers := http.Header{ - "Location": {locationHeader}, - } - return httpwrapper.NewResponse(http.StatusCreated, headers, response) + c.Header("Location", locationHeader) + c.JSON(http.StatusCreated, response) + return } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) + return } problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", } - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(http.StatusForbidden, problemDetails) } func (p *Processor) postAppSessCtxProcedure(appSessCtx *models.AppSessionContext) (*models.AppSessionContext, @@ -434,30 +434,22 @@ func (p *Processor) postAppSessCtxProcedure(appSessCtx *models.AppSessionContext } // HandleDeleteAppSession - Deletes an existing Individual Application Session Context -func HandleDeleteAppSessionContext(request *httpwrapper.Request) *httpwrapper.Response { - eventsSubscReqData := request.Body.(*models.EventsSubscReqData) - appSessID := request.Params["appSessionId"] - logger.PolicyAuthLog.Infof("Handle Del AppSessions, AppSessionId[%s]", appSessID) - - problemDetails := DeleteAppSessionContextProcedure(appSessID, eventsSubscReqData) - if problemDetails == nil { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } else { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } -} +func (p *Processor) HandleDeleteAppSessionContext( + c *gin.Context, + appSessionId string, + eventsSubscReqData *models.EventsSubscReqData) { + + logger.PolicyAuthLog.Infof("Handle Del AppSessions, AppSessionId[%s]", appSessionId) -func DeleteAppSessionContextProcedure(appSessID string, - eventsSubscReqData *models.EventsSubscReqData, -) *models.ProblemDetails { pcfSelf := pcf_context.GetSelf() var appSession *pcf_context.AppSessionData - if val, ok := pcfSelf.AppSessionPool.Load(appSessID); ok { + if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) } if appSession == nil { problemDetail := util.GetProblemDetail("can't find app session", util.APPLICATION_SESSION_CONTEXT_NOT_FOUND) - return &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } if eventsSubscReqData != nil { logger.PolicyAuthLog.Warnf("Delete AppSessions does not support with Event Subscription") @@ -471,9 +463,9 @@ func DeleteAppSessionContextProcedure(appSessID string, } } - delete(smPolicy.AppSessions, appSessID) + delete(smPolicy.AppSessions, appSessionId) - logger.PolicyAuthLog.Infof("App Session Id[%s] Del", appSessID) + logger.PolicyAuthLog.Infof("App Session Id[%s] Del", appSessionId) // TODO: AccUsageReport // if appSession.AccUsage != nil { @@ -487,7 +479,7 @@ func DeleteAppSessionContextProcedure(appSessID string, // } else { // } - pcfSelf.AppSessionPool.Delete(appSessID) + pcfSelf.AppSessionPool.Delete(appSessionId) smPolicy.ArrangeExistEventSubscription() @@ -499,77 +491,69 @@ func DeleteAppSessionContextProcedure(appSessID string, } go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) logger.PolicyAuthLog.Tracef("Send SM Policy[%s] Update Notification", smPolicyID) - return nil + c.JSON(http.StatusNoContent, nil) } // HandleGetAppSession - Reads an existing Individual Application Session Context -func HandleGetAppSessionContext(request *httpwrapper.Request) *httpwrapper.Response { - appSessID := request.Params["appSessionId"] - logger.PolicyAuthLog.Infof("Handle Get AppSessions, AppSessionId[%s]", appSessID) +func (p *Processor) HandleGetAppSessionContext( + c *gin.Context, + appSessionId string) { - problemDetails, response := GetAppSessionContextProcedure(appSessID) - if problemDetails == nil { - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } -} + logger.PolicyAuthLog.Infof("Handle Get AppSessions, AppSessionId[%s]", appSessionId) -func GetAppSessionContextProcedure(appSessID string) (*models.ProblemDetails, *models.AppSessionContext) { pcfSelf := pcf_context.GetSelf() var appSession *pcf_context.AppSessionData - if val, ok := pcfSelf.AppSessionPool.Load(appSessID); ok { + if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) } if appSession == nil { problemDetail := util.GetProblemDetail("can't find app session", util.APPLICATION_SESSION_CONTEXT_NOT_FOUND) - return &problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } - logger.PolicyAuthLog.Tracef("App Session Id[%s] Get", appSessID) - return nil, appSession.AppSessionContext + logger.PolicyAuthLog.Tracef("App Session Id[%s] Get", appSessionId) + c.JSON(http.StatusOK, appSession.AppSessionContext) + } // HandleModAppSession - Modifies an existing Individual Application Session Context -func (p *Processor) HandleModAppSessionContext(request *httpwrapper.Request) *httpwrapper.Response { - appSessID := request.Params["appSessionId"] - ascUpdateData := request.Body.(models.AppSessionContextUpdateData) - logger.PolicyAuthLog.Infof("Handle Modify AppSessions, AppSessionId[%s]", appSessID) - - problemDetails, response := p.ModAppSessionContextProcedure(appSessID, ascUpdateData) - if problemDetails == nil { - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } -} +func (p *Processor) HandleModAppSessionContext( + c *gin.Context, + appSessionId string, + appSessionContextUpdateData models.AppSessionContextUpdateData) { + + // appSessID := request.Params["appSessionId"] + // ascUpdateData := request.Body.(models.AppSessionContextUpdateData) + logger.PolicyAuthLog.Infof("Handle Modify AppSessions, AppSessionId[%s]", appSessionId) -func (p *Processor) ModAppSessionContextProcedure(appSessID string, - ascUpdateData models.AppSessionContextUpdateData, -) (*models.ProblemDetails, *models.AppSessionContext) { pcfSelf := pcf_context.GetSelf() var appSession *pcf_context.AppSessionData - if val, ok := pcfSelf.AppSessionPool.Load(appSessID); ok { + if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) } if appSession == nil { problemDetail := util.GetProblemDetail("can't find app session", util.APPLICATION_SESSION_CONTEXT_NOT_FOUND) - return &problemDetail, nil + c.JSON((int)(problemDetail.Status), problemDetail) + return } appSessCtx := appSession.AppSessionContext - if ascUpdateData.BdtRefId != "" { - appSessCtx.AscReqData.BdtRefId = ascUpdateData.BdtRefId + if appSessionContextUpdateData.BdtRefId != "" { + appSessCtx.AscReqData.BdtRefId = appSessionContextUpdateData.BdtRefId if err := p.handleBDTPolicyInd(pcfSelf, appSessCtx); err != nil { problemDetail := util.GetProblemDetail(err.Error(), util.ERROR_REQUEST_PARAMETERS) - return &problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } - logger.PolicyAuthLog.Tracef("App Session Id[%s] Updated", appSessID) - return nil, appSessCtx + logger.PolicyAuthLog.Tracef("App Session Id[%s] Updated", appSessionId) + c.JSON(http.StatusOK, appSessCtx) + return } smPolicy := appSession.SmPolicyData if smPolicy == nil { problemDetail := util.GetProblemDetail("Can't find related PDU Session", util.REQUESTED_SERVICE_NOT_AUTHORIZED) - return &problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } // InfluenceOnTrafficRouting = 1 in 29514 & Traffic Steering Control support = 1 in 29512 traffRoutSupp := util.CheckSuppFeat(appSessCtx.AscRespData.SuppFeat, @@ -579,9 +563,9 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, eventSubs := make(map[models.AfEvent]models.AfNotifMethod) updateSMpolicy := false - if ascUpdateData.MedComponents != nil { + if appSessionContextUpdateData.MedComponents != nil { precedence := getAvailablePrecedence(smPolicy.PolicyDecision.PccRules) - for compN, medCompRm := range ascUpdateData.MedComponents { + for compN, medCompRm := range appSessionContextUpdateData.MedComponents { medComp := transferMedCompRmToMedComp(&medCompRm) removeMediaComp(appSession, compN) if zero.IsZero(medComp) { @@ -601,7 +585,8 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, for _, medSubComp := range medComp.MedSubComps { if tempPccRule, problemDetail := handleMediaSubComponent(smPolicy, medComp, &medSubComp, var5qi); problemDetail != nil { - return problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } else { pccRule = tempPccRule } @@ -614,13 +599,14 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, // if medComp.AfAppId has value -> find pccRule by reqData.AfAppId, otherwise create a new pcc rule appID = medComp.AfAppId routeReq = medComp.AfRoutReq - } else if ascUpdateData.AfAppId != "" { - appID = ascUpdateData.AfAppId + } else if appSessionContextUpdateData.AfAppId != "" { + appID = appSessionContextUpdateData.AfAppId routeReq = medComp.AfRoutReq } else { problemDetail := util.GetProblemDetail("Media Component needs flows of subComp or afAppId", util.REQUESTED_SERVICE_NOT_AUTHORIZED) - return &problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } pccRule = util.GetPccRuleByAfAppId(smPolicy.PolicyDecision.PccRules, appID) @@ -634,7 +620,8 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, var ul, dl bool qosData, ul, dl = updateQosInMedComp(qosData, medComp) if problemDetail := modifyRemainBitRate(smPolicy, &qosData, ul, dl); problemDetail != nil { - return problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } } util.SetPccRuleRelatedData(smPolicy.PolicyDecision, pccRule, nil, &qosData, nil, nil) @@ -651,7 +638,8 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, var ul, dl bool qosData, ul, dl = updateQosInMedComp(*smPolicy.PolicyDecision.QosDecs[qosID], medComp) if problemDetail := modifyRemainBitRate(smPolicy, &qosData, ul, dl); problemDetail != nil { - return problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } smPolicy.PolicyDecision.QosDecs[qosData.QosId] = &qosData } @@ -669,9 +657,9 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, // Update of traffic routing information // TODO: check ascUpdateData.AfAppId with appSessCtx.AscReqData.AfAppId (now ascUpdateData.AfAppId is empty) - if ascUpdateData.AfRoutReq != nil && traffRoutSupp { - logger.PolicyAuthLog.Infof("Update Traffic Routing info - [%+v]", ascUpdateData.AfRoutReq) - appSessCtx.AscReqData.AfRoutReq = transferAfRoutReqRmToAfRoutReq(ascUpdateData.AfRoutReq) + if appSessionContextUpdateData.AfRoutReq != nil && traffRoutSupp { + logger.PolicyAuthLog.Infof("Update Traffic Routing info - [%+v]", appSessionContextUpdateData.AfRoutReq) + appSessCtx.AscReqData.AfRoutReq = transferAfRoutReqRmToAfRoutReq(appSessionContextUpdateData.AfRoutReq) // Update SmPolicyDecision pccRule := provisioningOfTrafficRoutingInfo(smPolicy, appSessCtx.AscReqData.AfAppId, appSessCtx.AscReqData.AfRoutReq, "") @@ -685,8 +673,8 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, relatedPccRuleIds[key] = pccRuleID } - if ascUpdateData.EvSubsc != nil { - for _, subs := range ascUpdateData.EvSubsc.Events { + if appSessionContextUpdateData.EvSubsc != nil { + for _, subs := range appSessionContextUpdateData.EvSubsc.Events { if subs.NotifMethod == "" { // default value "EVENT_DETECTION" subs.NotifMethod = models.AfNotifMethod_EVENT_DETECTION @@ -730,13 +718,13 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, if appSessCtx.AscReqData.EvSubsc == nil { appSessCtx.AscReqData.EvSubsc = new(models.EventsSubscReqData) } - appSessCtx.AscReqData.EvSubsc.Events = ascUpdateData.EvSubsc.Events - if ascUpdateData.EvSubsc.NotifUri != "" { - appSessCtx.AscReqData.EvSubsc.NotifUri = ascUpdateData.EvSubsc.NotifUri - appSession.EventUri = ascUpdateData.EvSubsc.NotifUri + appSessCtx.AscReqData.EvSubsc.Events = appSessionContextUpdateData.EvSubsc.Events + if appSessionContextUpdateData.EvSubsc.NotifUri != "" { + appSessCtx.AscReqData.EvSubsc.NotifUri = appSessionContextUpdateData.EvSubsc.NotifUri + appSession.EventUri = appSessionContextUpdateData.EvSubsc.NotifUri } - if ascUpdateData.EvSubsc.UsgThres != nil { - appSessCtx.AscReqData.EvSubsc.UsgThres = threshRmToThresh(ascUpdateData.EvSubsc.UsgThres) + if appSessionContextUpdateData.EvSubsc.UsgThres != nil { + appSessCtx.AscReqData.EvSubsc.UsgThres = threshRmToThresh(appSessionContextUpdateData.EvSubsc.UsgThres) } } else { // remove eventSubs @@ -746,20 +734,22 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, } // Moification provisioning of sponsored connectivity information - if ascUpdateData.AspId != "" && ascUpdateData.SponId != "" { - umID := util.GetUmId(ascUpdateData.AspId, ascUpdateData.SponId) + if appSessionContextUpdateData.AspId != "" && appSessionContextUpdateData.SponId != "" { + umID := util.GetUmId(appSessionContextUpdateData.AspId, appSessionContextUpdateData.SponId) var umData *models.UsageMonitoringData if tempUmData, err := extractUmData(umID, eventSubs, - threshRmToThresh(ascUpdateData.EvSubsc.UsgThres)); err != nil { + threshRmToThresh(appSessionContextUpdateData.EvSubsc.UsgThres)); err != nil { problemDetail := util.GetProblemDetail(err.Error(), util.REQUESTED_SERVICE_NOT_AUTHORIZED) - return &problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } else { umData = tempUmData } - if err := handleSponsoredConnectivityInformation(smPolicy, relatedPccRuleIds, ascUpdateData.AspId, - ascUpdateData.SponId, ascUpdateData.SponStatus, umData, &updateSMpolicy); err != nil { + if err := handleSponsoredConnectivityInformation(smPolicy, relatedPccRuleIds, appSessionContextUpdateData.AspId, + appSessionContextUpdateData.SponId, appSessionContextUpdateData.SponStatus, umData, &updateSMpolicy); err != nil { problemDetail := util.GetProblemDetail(err.Error(), util.REQUESTED_SERVICE_NOT_AUTHORIZED) - return &problemDetail, nil + c.JSON(int(problemDetail.Status), problemDetail) + return } } @@ -798,7 +788,7 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, } // TODO: MPS Service - logger.PolicyAuthLog.Tracef("App Session Id[%s] Updated", appSessID) + logger.PolicyAuthLog.Tracef("App Session Id[%s] Updated", appSessionId) smPolicy.ArrangeExistEventSubscription() @@ -812,32 +802,29 @@ func (p *Processor) ModAppSessionContextProcedure(appSessID string, go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) logger.PolicyAuthLog.Tracef("Send SM Policy[%s] Update Notification", smPolicyID) } - return nil, appSessCtx + c.JSON(http.StatusOK, appSessCtx) } // HandleDeleteEventsSubsc - deletes the Events Subscription subresource -func HandleDeleteEventsSubscContext(request *httpwrapper.Request) *httpwrapper.Response { - appSessID := request.Params["appSessID"] - logger.PolicyAuthLog.Tracef("Handle Del AppSessions Events Subsc, AppSessionId[%s]", appSessID) +func (p *Processor) HandleDeleteEventsSubscContext( + c *gin.Context, + appSessionId string) { + // appSessID := request.Params["appSessID"] + logger.PolicyAuthLog.Tracef("Handle Del AppSessions Events Subsc, AppSessionId[%s]", appSessionId) - problemDetails := DeleteEventsSubscContextProcedure(appSessID) - if problemDetails == nil { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } else { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } -} + // problemDetails := DeleteEventsSubscContextProcedure(appSessionId) -func DeleteEventsSubscContextProcedure(appSessID string) *models.ProblemDetails { pcfSelf := pcf_context.GetSelf() var appSession *pcf_context.AppSessionData - if val, ok := pcfSelf.AppSessionPool.Load(appSessID); ok { + if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) } if appSession == nil { problemDetail := util.GetProblemDetail("can't find app session", util.APPLICATION_SESSION_CONTEXT_NOT_FOUND) - return &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } + appSession.Events = nil appSession.EventUri = "" appSession.AppSessionContext.EvsNotif = nil @@ -845,7 +832,7 @@ func DeleteEventsSubscContextProcedure(appSessID string) *models.ProblemDetails // changed := appSession.SmPolicyData.ArrangeExistEventSubscription() - logger.PolicyAuthLog.Tracef("App Session Id[%s] Del Events Subsc success", appSessID) + logger.PolicyAuthLog.Tracef("App Session Id[%s] Del Events Subsc success", appSessionId) smPolicy := appSession.SmPolicyData // Send Notification to SMF @@ -858,92 +845,31 @@ func DeleteEventsSubscContextProcedure(appSessID string) *models.ProblemDetails go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) logger.PolicyAuthLog.Tracef("Send SM Policy[%s] Update Notification", smPolicyID) } - return nil + c.JSON(http.StatusNoContent, nil) } // HandleUpdateEventsSubsc - creates or modifies an Events Subscription subresource -func HandleUpdateEventsSubscContext(request *httpwrapper.Request) *httpwrapper.Response { - EventsSubscReqData := request.Body.(models.EventsSubscReqData) - appSessID := request.Params["appSessID"] - logger.PolicyAuthLog.Tracef("Handle Put AppSessions Events Subsc, AppSessionId[%s]", appSessID) - - response, locationHeader, status, problemDetails := UpdateEventsSubscContextProcedure(appSessID, EventsSubscReqData) - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else if status == http.StatusCreated { - headers := http.Header{ - "Location": {locationHeader}, - } - return httpwrapper.NewResponse(http.StatusCreated, headers, response) - } else if status == http.StatusOK { - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else if status == http.StatusNoContent { - return httpwrapper.NewResponse(http.StatusNoContent, nil, response) - } - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) -} - -func SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, request models.EventsNotification) { - logger.PolicyAuthLog.Tracef("Send App Session Event Notification") - if appSession == nil { - logger.PolicyAuthLog.Warnln("Send App Session Event Notification Error[appSession is nil]") - return - } - uri := appSession.EventUri +func (p *Processor) HandleUpdateEventsSubscContext( + c *gin.Context, + appSessionId string, + eventsSubscReqData models.EventsSubscReqData) { - if uri != "" { - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_POLICYAUTHORIZATION, models.NfType_PCF) - if err != nil { - return - } + // EventsSubscReqData := request.Body.(models.EventsSubscReqData) + // appSessID := request.Params["appSessID"] + logger.PolicyAuthLog.Tracef("Handle Put AppSessions Events Subsc, AppSessionId[%s]", appSessionId) - request.EvSubsUri = fmt.Sprintf("%s/events-subscription", - util.GetResourceUri(models.ServiceName_NPCF_POLICYAUTHORIZATION, appSession.AppSessionId)) - client := util.GetNpcfPolicyAuthorizationCallbackClient() - httpResponse, err := client.PolicyAuthorizationEventNotificationApi.PolicyAuthorizationEventNotification( - ctx, uri, request) - if err != nil { - if httpResponse != nil { - logger.PolicyAuthLog.Warnf("Send App Session Event Notification Error[%s]", httpResponse.Status) - } else { - logger.PolicyAuthLog.Warnf("Send App Session Event Notification Failed[%s]", err.Error()) - } - return - } else if httpResponse == nil { - logger.PolicyAuthLog.Warnln("Send App Session Event Notification Failed[HTTP Response is nil]") - return - } - defer func() { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.PolicyAuthLog.Errorf( - "PolicyAuthorizationEventNotification response body cannot close: %+v", - rspCloseErr) - } - }() - if httpResponse.StatusCode != http.StatusOK && httpResponse.StatusCode != http.StatusNoContent { - logger.PolicyAuthLog.Warnf("Send App Session Event Notification Failed") - } else { - logger.PolicyAuthLog.Tracef("Send App Session Event Notification Success") - } - } -} + // response, locationHeader, status, problemDetails := UpdateEventsSubscContextProcedure(appSessionId, eventsSubscReqData) -func UpdateEventsSubscContextProcedure(appSessID string, eventsSubscReqData models.EventsSubscReqData) ( - *models.UpdateEventsSubscResponse, string, int, *models.ProblemDetails, -) { pcfSelf := pcf_context.GetSelf() var appSession *pcf_context.AppSessionData - if val, ok := pcfSelf.AppSessionPool.Load(appSessID); ok { + if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) } if appSession == nil { problemDetail := util.GetProblemDetail("can't find app session", util.APPLICATION_SESSION_CONTEXT_NOT_FOUND) - return nil, "", int(problemDetail.Status), &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } smPolicy := appSession.SmPolicyData eventSubs := make(map[models.AfEvent]models.AfNotifMethod) @@ -1057,15 +983,61 @@ func UpdateEventsSubscContextProcedure(appSessID string, eventsSubscReqData mode } if created { locationHeader := fmt.Sprintf("%s/events-subscription", - util.GetResourceUri(models.ServiceName_NPCF_POLICYAUTHORIZATION, appSessID)) - logger.PolicyAuthLog.Tracef("App Session Id[%s] Create Subscription", appSessID) - return &resp, locationHeader, http.StatusCreated, nil + util.GetResourceUri(models.ServiceName_NPCF_POLICYAUTHORIZATION, appSessionId)) + logger.PolicyAuthLog.Tracef("App Session Id[%s] Create Subscription", appSessionId) + c.Header("Location", locationHeader) + c.JSON(http.StatusCreated, resp) } else if resp.EvsNotif != nil { - logger.PolicyAuthLog.Tracef("App Session Id[%s] Modify Subscription", appSessID) - return &resp, "", http.StatusOK, nil + logger.PolicyAuthLog.Tracef("App Session Id[%s] Modify Subscription", appSessionId) + c.JSON(http.StatusOK, resp) } else { - logger.PolicyAuthLog.Tracef("App Session Id[%s] Modify Subscription", appSessID) - return &resp, "", http.StatusNoContent, nil + logger.PolicyAuthLog.Tracef("App Session Id[%s] Modify Subscription", appSessionId) + c.JSON(http.StatusNoContent, nil) + } +} + +func SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, request models.EventsNotification) { + logger.PolicyAuthLog.Tracef("Send App Session Event Notification") + if appSession == nil { + logger.PolicyAuthLog.Warnln("Send App Session Event Notification Error[appSession is nil]") + return + } + uri := appSession.EventUri + + if uri != "" { + ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_POLICYAUTHORIZATION, models.NfType_PCF) + if err != nil { + return + } + + request.EvSubsUri = fmt.Sprintf("%s/events-subscription", + util.GetResourceUri(models.ServiceName_NPCF_POLICYAUTHORIZATION, appSession.AppSessionId)) + client := util.GetNpcfPolicyAuthorizationCallbackClient() + httpResponse, err := client.PolicyAuthorizationEventNotificationApi.PolicyAuthorizationEventNotification( + ctx, uri, request) + if err != nil { + if httpResponse != nil { + logger.PolicyAuthLog.Warnf("Send App Session Event Notification Error[%s]", httpResponse.Status) + } else { + logger.PolicyAuthLog.Warnf("Send App Session Event Notification Failed[%s]", err.Error()) + } + return + } else if httpResponse == nil { + logger.PolicyAuthLog.Warnln("Send App Session Event Notification Failed[HTTP Response is nil]") + return + } + defer func() { + if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { + logger.PolicyAuthLog.Errorf( + "PolicyAuthorizationEventNotification response body cannot close: %+v", + rspCloseErr) + } + }() + if httpResponse.StatusCode != http.StatusOK && httpResponse.StatusCode != http.StatusNoContent { + logger.PolicyAuthLog.Warnf("Send App Session Event Notification Failed") + } else { + logger.PolicyAuthLog.Tracef("Send App Session Event Notification Success") + } } } diff --git a/internal/sbi/processor/smpolicy.go b/internal/sbi/processor/smpolicy.go index 3c1a25f..9d234e1 100644 --- a/internal/sbi/processor/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/antihax/optional" + "github.com/gin-gonic/gin" "go.mongodb.org/mongo-driver/bson" "github.com/free5gc/openapi" @@ -16,7 +17,6 @@ import ( "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" "github.com/free5gc/util/flowdesc" - "github.com/free5gc/util/httpwrapper" "github.com/free5gc/util/mongoapi" ) @@ -27,51 +27,17 @@ const ( ) // SmPoliciesPost - -func (p *Processor) HandleCreateSmPolicyRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log +func (p *Processor) HandleCreateSmPolicyRequest( + c *gin.Context, + request models.SmPolicyContextData) { + logger.SmPolicyLog.Infof("Handle CreateSmPolicy") // step 2: retrieve request - requestDataType := request.Body.(models.SmPolicyContextData) + // requestDataType := request.Body.(models.SmPolicyContextData) // step 3: handle the message - header, response, problemDetails := p.createSMPolicyProcedure(requestDataType) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusCreated, header, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNotFound, nil, nil) - } -} - -func newQosDataWithQosFlowMap(qosFlow map[string]interface{}) *models.QosData { - qosData := &models.QosData{ - QosId: strconv.Itoa(int(qosFlow["qosRef"].(float64))), - Qnc: false, - Var5qi: int32(qosFlow["5qi"].(float64)), - } - if qosFlow["mbrUL"] != nil { - qosData.MaxbrUl = qosFlow["mbrUL"].(string) - } - if qosFlow["mbrDL"] != nil { - qosData.MaxbrDl = qosFlow["mbrDL"].(string) - } - if qosFlow["gbrUL"] != nil { - qosData.GbrUl = qosFlow["gbrUL"].(string) - } - if qosFlow["gbrDL"] != nil { - qosData.GbrDl = qosFlow["gbrDL"].(string) - } - - return qosData -} + // header, response, problemDetails := p.createSMPolicyProcedure(requestDataType) -func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) ( - header http.Header, response *models.SmPolicyDecision, problemDetails *models.ProblemDetails, -) { var err error queryStrength := 2 // 2: case-insensitive, 3: case-sensitive logger.SmPolicyLog.Tracef("Handle Create SM Policy Request") @@ -79,7 +45,8 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) if request.Supi == "" || request.SliceInfo == nil || len(request.SliceInfo.Sd) != 6 { problemDetail := util.GetProblemDetail("Errorneous/Missing Mandotory IE", util.ERROR_INITIAL_PARAMETERS) logger.SmPolicyLog.Warnln("Errorneous/Missing Mandotory IE", util.ERROR_INITIAL_PARAMETERS) - return nil, nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } pcfSelf := pcf_context.GetSelf() @@ -91,13 +58,15 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) if ue == nil { problemDetail := util.GetProblemDetail("Supi is not supported in PCF", util.USER_UNKNOWN) logger.SmPolicyLog.Warnf("Supi[%s] is not supported in PCF", request.Supi) - return nil, nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } udrUri := p.getUdrUri(ue) if udrUri == "" { problemDetail := util.GetProblemDetail("Can't find corresponding UDR with UE", util.USER_UNKNOWN) logger.SmPolicyLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) - return nil, nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } var smData models.SmPolicyData smPolicyID := fmt.Sprintf("%s-%d", ue.Supi, request.PduSessionId) @@ -112,14 +81,16 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) ctx, pd, err1 := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err1 != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } smData, response, err1 = client.DefaultApi.PolicyDataUesUeIdSmDataGet(ctx, ue.Supi, ¶m) if err1 != nil || response == nil || response.StatusCode != http.StatusOK { problemDetail := util.GetProblemDetail("Can't find UE SM Policy Data in UDR", util.USER_UNKNOWN) logger.SmPolicyLog.Warnf("Can't find UE[%s] SM Policy Data in UDR", ue.Supi) - return nil, nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } defer func() { if rspCloseErr := response.Body.Close(); rspCloseErr != nil { @@ -136,7 +107,8 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) problemDetail := util.GetProblemDetail("Can't find corresponding AM Policy", util.POLICY_CONTEXT_DENIED) logger.SmPolicyLog.Warnf("Can't find corresponding AM Policy") // message.SendHttpResponseMessage(httpChannel, nil, int(rsp.Status), rsp) - return nil, nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } // TODO: check service restrict if ue.Gpsi == "" { @@ -250,7 +222,8 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) if err1 != nil { logger.SmPolicyLog.Error("rating group allocate error") problemDetails := util.GetProblemDetail("rating group allocate error", util.ERROR_IDGENERATOR) - return nil, nil, &problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } chgData := &models.ChargingData{ ChgId: util.GetChgId(smPolicyData.ChargingIdGenerator), @@ -345,7 +318,8 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) if err1 != nil { logger.SmPolicyLog.Error("rating group allocate error") problemDetails := util.GetProblemDetail("rating group allocate error", util.ERROR_IDGENERATOR) - return nil, nil, &problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } chgData := &models.ChargingData{ ChgId: util.GetChgId(smPolicyData.ChargingIdGenerator), @@ -408,7 +382,8 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } udrClient := util.GetNudrClient(udrUri) @@ -469,7 +444,8 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) ctx, pd, err = pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NBSF_MANAGEMENT, models.NfType_BSF) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } _, resp, err = bsfClient.PCFBindingsCollectionApi.CreatePCFBinding(ctx, pcfBinding) @@ -486,46 +462,53 @@ func (p *Processor) createSMPolicyProcedure(request models.SmPolicyContextData) } } locationHeader := util.GetResourceUri(models.ServiceName_NPCF_SMPOLICYCONTROL, smPolicyID) - header = http.Header{ - "Location": {locationHeader}, - } + c.Header("Location", locationHeader) logger.SmPolicyLog.Tracef("SMPolicy PduSessionId[%d] Create", request.PduSessionId) - - return header, &decision, nil + c.JSON(http.StatusCreated, decision) } -// SmPoliciessmPolicyIDDeletePost - -func (p *Processor) HandleDeleteSmPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SmPolicyLog.Infof("Handle DeleteSmPolicyContext") +func newQosDataWithQosFlowMap(qosFlow map[string]interface{}) *models.QosData { + qosData := &models.QosData{ + QosId: strconv.Itoa(int(qosFlow["qosRef"].(float64))), + Qnc: false, + Var5qi: int32(qosFlow["5qi"].(float64)), + } + if qosFlow["mbrUL"] != nil { + qosData.MaxbrUl = qosFlow["mbrUL"].(string) + } + if qosFlow["mbrDL"] != nil { + qosData.MaxbrDl = qosFlow["mbrDL"].(string) + } + if qosFlow["gbrUL"] != nil { + qosData.GbrUl = qosFlow["gbrUL"].(string) + } + if qosFlow["gbrDL"] != nil { + qosData.GbrDl = qosFlow["gbrDL"].(string) + } - // step 2: retrieve request - smPolicyID := request.Params["smPolicyId"] + return qosData +} - // step 3: handle the message - problemDetails := p.deleteSmPolicyContextProcedure(smPolicyID) +// SmPoliciessmPolicyIDDeletePost - +func (p *Processor) HandleDeleteSmPolicyContextRequest( + c *gin.Context, + smPolicyId string) { - // step 4: process the return value from step 3 - if problemDetails != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} + logger.SmPolicyLog.Infof("Handle DeleteSmPolicyContext") -func (p *Processor) deleteSmPolicyContextProcedure(smPolicyID string) *models.ProblemDetails { + // handle the message logger.AmPolicyLog.Traceln("Handle SM Policy Delete") - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyID) - if ue == nil || ue.SmPolicyData[smPolicyID] == nil { + ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyId) + if ue == nil || ue.SmPolicyData[smPolicyId] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.SmPolicyLog.Warnf(problemDetail.Detail) - return &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } pcfSelf := pcf_context.GetSelf() - smPolicy := ue.SmPolicyData[smPolicyID] + smPolicy := ue.SmPolicyData[smPolicyId] problemDetail, err := p.consumer.RemoveInfluenceDataSubscription(ue, smPolicy.SubscriptionID) if problemDetail != nil { @@ -535,8 +518,8 @@ func (p *Processor) deleteSmPolicyContextProcedure(smPolicyID string) *models.Pr } // Unsubscrice UDR - delete(ue.SmPolicyData, smPolicyID) - logger.SmPolicyLog.Tracef("SMPolicy smPolicyID[%s] DELETE", smPolicyID) + delete(ue.SmPolicyData, smPolicyId) + logger.SmPolicyLog.Tracef("SMPolicy smPolicyID[%s] DELETE", smPolicyId) // Release related App Session terminationInfo := models.TerminationInfo{ @@ -547,11 +530,11 @@ func (p *Processor) deleteSmPolicyContextProcedure(smPolicyID string) *models.Pr appSession := val.(*pcf_context.AppSessionData) SendAppSessionTermination(appSession, terminationInfo) pcfSelf.AppSessionPool.Delete(appSessionID) - logger.SmPolicyLog.Tracef("SMPolicy[%s] DELETE Related AppSession[%s]", smPolicyID, appSessionID) + logger.SmPolicyLog.Tracef("SMPolicy[%s] DELETE Related AppSession[%s]", smPolicyId, appSessionID) } } - for _, ratingGroup := range ue.RatingGroupData[smPolicyID] { + for _, ratingGroup := range ue.RatingGroupData[smPolicyId] { pcfSelf.RatingGroupIdGenerator.FreeID(int64(ratingGroup)) filterCharging := bson.M{ @@ -562,92 +545,56 @@ func (p *Processor) deleteSmPolicyContextProcedure(smPolicyID string) *models.Pr logger.SmPolicyLog.Errorf("Fail to delete charging data, ratingGroup: %+v, err: %+v", ratingGroup, err) } } - delete(ue.RatingGroupData, smPolicyID) - return nil + delete(ue.RatingGroupData, smPolicyId) + c.JSON(http.StatusNoContent, nil) + } // SmPoliciessmPolicyIDGet - -func HandleGetSmPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SmPolicyLog.Infof("Handle GetSmPolicyContext") +func (p *Processor) HandleGetSmPolicyContextRequest( + c *gin.Context, + smPolicyId string) { - // step 2: retrieve request - smPolicyID := request.Params["smPolicyId"] - // step 3: handle the message - response, problemDetails := getSmPolicyContextProcedure(smPolicyID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) -} - -func getSmPolicyContextProcedure(smPolicyID string) ( - response *models.SmPolicyControl, problemDetails *models.ProblemDetails, -) { + logger.SmPolicyLog.Infof("Handle GetSmPolicyContext") + // handle the message logger.SmPolicyLog.Traceln("Handle GET SM Policy Request") - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyID) - if ue == nil || ue.SmPolicyData[smPolicyID] == nil { + ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyId) + if ue == nil || ue.SmPolicyData[smPolicyId] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.SmPolicyLog.Warnf(problemDetail.Detail) - return nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } - smPolicyData := ue.SmPolicyData[smPolicyID] - response = &models.SmPolicyControl{ + smPolicyData := ue.SmPolicyData[smPolicyId] + response := &models.SmPolicyControl{ Policy: smPolicyData.PolicyDecision, Context: smPolicyData.PolicyContext, } - logger.SmPolicyLog.Tracef("SMPolicy smPolicyID[%s] GET", smPolicyID) - return response, nil + logger.SmPolicyLog.Tracef("SMPolicy smPolicyID[%s] GET", smPolicyId) + c.JSON(http.StatusOK, response) } // SmPoliciessmPolicyIDUpdatePost - -func HandleUpdateSmPolicyContextRequest(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleUpdateSmPolicyContextRequest( + c *gin.Context, + smPolicyId string, + request models.SmPolicyUpdateContextData) { // step 1: log logger.SmPolicyLog.Infof("Handle UpdateSmPolicyContext") - // step 2: retrieve request - requestDataType := request.Body.(models.SmPolicyUpdateContextData) - smPolicyID := request.Params["smPolicyId"] + // // step 3: handle the message - // step 3: handle the message - response, problemDetails := updateSmPolicyContextProcedure(requestDataType, smPolicyID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) -} - -func updateSmPolicyContextProcedure(request models.SmPolicyUpdateContextData, smPolicyID string) ( - response *models.SmPolicyDecision, problemDetails *models.ProblemDetails, -) { logger.SmPolicyLog.Traceln("Handle updateSmPolicyContext") - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyID) - if ue == nil || ue.SmPolicyData[smPolicyID] == nil { + ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyId) + if ue == nil || ue.SmPolicyData[smPolicyId] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.SmPolicyLog.Warnf(problemDetail.Detail) - return nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } - smPolicy := ue.SmPolicyData[smPolicyID] + smPolicy := ue.SmPolicyData[smPolicyId] smPolicyDecision := smPolicy.PolicyDecision smPolicyContext := smPolicy.PolicyContext errCause := "" @@ -705,7 +652,8 @@ func updateSmPolicyContextProcedure(request models.SmPolicyUpdateContextData, sm if err != nil { problemDetail := util.GetProblemDetail(err.Error(), util.ERROR_TRAFFIC_MAPPING_INFO_REJECTED) logger.SmPolicyLog.Warnf(problemDetail.Detail) - return nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } if qosData.GbrDl != "" { logger.SmPolicyLog.Tracef("SM Policy Dnn[%s] Data Aggregate decrease %s and then DL GBR remain[%.2f Kbps]", @@ -753,7 +701,8 @@ func updateSmPolicyContextProcedure(request models.SmPolicyUpdateContextData, sm smPolicy.RemainGbrUL = origUl problemDetail := util.GetProblemDetail(err.Error(), util.ERROR_TRAFFIC_MAPPING_INFO_REJECTED) logger.SmPolicyLog.Warnf(problemDetail.Detail) - return nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } qosData.Var5qi = req.ReqQos.Var5qi qosData.GbrDl = gbrDl @@ -1002,11 +951,12 @@ func updateSmPolicyContextProcedure(request models.SmPolicyUpdateContextData, sm if errCause != "" { problemDetail := util.GetProblemDetail(errCause, util.ERROR_TRIGGER_EVENT) logger.SmPolicyLog.Warnf(errCause) - return nil, &problemDetail + c.JSON(int(problemDetail.Status), problemDetail) + return } - logger.SmPolicyLog.Tracef("SMPolicy smPolicyID[%s] Update", smPolicyID) + logger.SmPolicyLog.Tracef("SMPolicy smPolicyID[%s] Update", smPolicyId) // message.SendHttpResponseMessage(httpChannel, nil, http.StatusOK, *smPolicyDecision) - return smPolicyDecision, nil + c.JSON(http.StatusOK, smPolicyDecision) } func sendSmPolicyRelatedAppSessionNotification(smPolicy *pcf_context.UeSmPolicyData, From 64c29640665558a9f85e4bab48bd7b5e65e88649 Mon Sep 17 00:00:00 2001 From: chh Date: Thu, 16 May 2024 09:04:33 +0000 Subject: [PATCH 11/20] fix: fix linter error --- internal/sbi/api_ampolicy.go | 3 - internal/sbi/api_bdtpolicy.go | 1 - internal/sbi/api_policyauthorization.go | 1 - internal/sbi/consumer/amf_service.go | 2 - internal/sbi/consumer/consumer.go | 3 +- internal/sbi/consumer/nrf_service.go | 3 +- internal/sbi/consumer/udr_service.go | 4 +- internal/sbi/processor/ampolicy.go | 17 ++- internal/sbi/processor/bdtpolicy.go | 20 ++-- internal/sbi/processor/callback.go | 14 +-- internal/sbi/processor/oam.go | 4 +- internal/sbi/processor/policyauthorization.go | 25 +++-- internal/sbi/processor/smpolicy.go | 16 +-- internal/sbi/server.go | 100 ------------------ pkg/service/init.go | 9 +- 15 files changed, 58 insertions(+), 164 deletions(-) diff --git a/internal/sbi/api_ampolicy.go b/internal/sbi/api_ampolicy.go index dbdc2ee..70b581c 100644 --- a/internal/sbi/api_ampolicy.go +++ b/internal/sbi/api_ampolicy.go @@ -84,7 +84,6 @@ func (s *Server) HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { } s.Processor().HandleUpdatePostPoliciesPolAssoId(c, polAssoId, policyAssociationUpdateRequest) - } func (s *Server) HTTPPoliciesPost(c *gin.Context) { @@ -135,12 +134,10 @@ func (s *Server) HTTPPoliciesPost(c *gin.Context) { } s.Processor().HandlePostPolicies(c, polAssoId, policyAssociationRequest) - } func (s *Server) getAmPolicyRoutes() []Route { return []Route{ - { Method: http.MethodGet, Pattern: "/policies/:polAssoId", diff --git a/internal/sbi/api_bdtpolicy.go b/internal/sbi/api_bdtpolicy.go index b45a447..4eff462 100644 --- a/internal/sbi/api_bdtpolicy.go +++ b/internal/sbi/api_bdtpolicy.go @@ -74,7 +74,6 @@ func (s *Server) HTTPCreateBDTPolicy(c *gin.Context) { } s.Processor().HandleCreateBDTPolicyContextRequest(c, bdtReqData) - } func (s *Server) HTTPGetBDTPolicy(c *gin.Context) { diff --git a/internal/sbi/api_policyauthorization.go b/internal/sbi/api_policyauthorization.go index cbf6f36..4f2f6e9 100644 --- a/internal/sbi/api_policyauthorization.go +++ b/internal/sbi/api_policyauthorization.go @@ -101,7 +101,6 @@ func (s *Server) HTTPPostAppSessions(c *gin.Context) { // api_events_subscription // HTTPDeleteEventsSubsc - deletes the Events Subscription subresource func (s *Server) HTTPDeleteEventsSubsc(c *gin.Context) { - appSessionId := c.Params.ByName("appSessionId") if appSessionId == "" { problemDetails := &models.ProblemDetails{ diff --git a/internal/sbi/consumer/amf_service.go b/internal/sbi/consumer/amf_service.go index 0cc649e..7f27576 100644 --- a/internal/sbi/consumer/amf_service.go +++ b/internal/sbi/consumer/amf_service.go @@ -46,8 +46,6 @@ func (s *namfService) getNFCommunicationClient(uri string) *Namf_Communication.A func (s *namfService) AmfStatusChangeSubscribe(amfUri string, guamiList []models.Guami) ( problemDetails *models.ProblemDetails, err error, ) { - - logger.ConsumerLog.Debugf("PCF Subscribe to AMF status[%+v]", amfUri) pcfContext := s.consumer.pcf.Context() diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go index a52860a..b5843f1 100644 --- a/internal/sbi/consumer/consumer.go +++ b/internal/sbi/consumer/consumer.go @@ -7,9 +7,8 @@ import ( "github.com/free5gc/openapi/Nnrf_NFDiscovery" "github.com/free5gc/openapi/Nnrf_NFManagement" "github.com/free5gc/openapi/Nudr_DataRepository" - "github.com/free5gc/pcf/pkg/factory" - pcf_context "github.com/free5gc/pcf/internal/context" + "github.com/free5gc/pcf/pkg/factory" ) type pcf interface { diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 1083293..37f2a4a 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -72,8 +72,8 @@ func (s *nnrfService) getNFDiscClient(uri string) *Nnrf_NFDiscovery.APIClient { defer s.nfDiscMu.Unlock() s.nfDiscClients[uri] = client return client - } + func (s *nnrfService) SendSearchNFInstances( nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( *models.SearchResult, error, @@ -207,6 +207,7 @@ func (s *nnrfService) BuildNFInstance(context *pcf_context.PCFContext) (profile } return } + func (s *nnrfService) SendRegisterNFInstance(ctx context.Context) ( resouceNrfUri string, retrieveNfInstanceID string, err error, ) { diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go index f3509d0..b141cd4 100644 --- a/internal/sbi/consumer/udr_service.go +++ b/internal/sbi/consumer/udr_service.go @@ -6,8 +6,8 @@ import ( "sync" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" "github.com/free5gc/openapi/Nudr_DataRepository" + "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" @@ -55,7 +55,7 @@ func (s *nudrService) CreateInfluenceDataSubscription(ue *pcf_context.UeContext, if err != nil { return "", pd, err } - client := s.getDataSubscription(ue.UdrUri); + client := s.getDataSubscription(ue.UdrUri) trafficInfluSub := s.buildTrafficInfluSub(request) _, httpResp, localErr := client.InfluenceDataSubscriptionsCollectionApi. ApplicationDataInfluenceDataSubsToNotifyPost(ctx, trafficInfluSub) diff --git a/internal/sbi/processor/ampolicy.go b/internal/sbi/processor/ampolicy.go index 783a649..e9bf922 100644 --- a/internal/sbi/processor/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -17,8 +17,8 @@ import ( func (p *Processor) HandleDeletePoliciesPolAssoId( c *gin.Context, - polAssoId string) { - + polAssoId string, +) { logger.AmPolicyLog.Infof("Handle AM Policy Association Delete") ue := pcf_context.GetSelf().PCFUeFindByPolicyId(polAssoId) @@ -34,8 +34,8 @@ func (p *Processor) HandleDeletePoliciesPolAssoId( // PoliciesPolAssoIdGet - func (p *Processor) HandleGetPoliciesPolAssoId( c *gin.Context, - polAssoId string) { - + polAssoId string, +) { logger.AmPolicyLog.Infof("Handle AM Policy Association Get") // response, problemDetails := GetPoliciesPolAssoIdProcedure(polAssoId) @@ -70,8 +70,8 @@ func (p *Processor) HandleGetPoliciesPolAssoId( func (p *Processor) HandleUpdatePostPoliciesPolAssoId( c *gin.Context, polAssoId string, - policyAssociationUpdateRequest models.PolicyAssociationUpdateRequest) { - + policyAssociationUpdateRequest models.PolicyAssociationUpdateRequest, +) { logger.AmPolicyLog.Infof("Handle AM Policy Association Update") response, problemDetails := UpdatePostPoliciesPolAssoIdProcedure(polAssoId, policyAssociationUpdateRequest) @@ -167,7 +167,6 @@ func (p *Processor) HandlePostPolicies( polAssoId string, policyAssociationRequest models.PolicyAssociationRequest, ) { - logger.AmPolicyLog.Infof("Handle AM Policy Create Request") response, locationHeader, problemDetails := p.PostPoliciesProcedure(polAssoId, policyAssociationRequest) @@ -184,7 +183,6 @@ func (p *Processor) HandlePostPolicies( Cause: "UNSPECIFIED", } c.JSON(int(problemDetails.Status), problemDetails) - } func (p *Processor) PostPoliciesProcedure(polAssoId string, @@ -287,7 +285,8 @@ func (p *Processor) PostPoliciesProcedure(polAssoId string, if needSubscribe { logger.AmPolicyLog.Debugf("Subscribe AMF status change[GUAMI: %+v]", *policyAssociationRequest.Guami) - amfUri := p.consumer.SendNFInstancesAMF(pcfSelf.NrfUri, *policyAssociationRequest.Guami, models.ServiceName_NAMF_COMM) + amfUri := p.consumer.SendNFInstancesAMF(pcfSelf.NrfUri, + *policyAssociationRequest.Guami, models.ServiceName_NAMF_COMM) if amfUri != "" { problemDetails, err := p.consumer.AmfStatusChangeSubscribe(amfUri, []models.Guami{*policyAssociationRequest.Guami}) if err != nil { diff --git a/internal/sbi/processor/bdtpolicy.go b/internal/sbi/processor/bdtpolicy.go index 0066c31..02151ce 100644 --- a/internal/sbi/processor/bdtpolicy.go +++ b/internal/sbi/processor/bdtpolicy.go @@ -19,7 +19,8 @@ import ( func (p *Processor) HandleGetBDTPolicyContextRequest( c *gin.Context, - bdtPolicyID string) { + bdtPolicyID string, +) { // step 1: log logger.BdtPolicyLog.Infof("Handle GetBDTPolicyContext") @@ -43,7 +44,8 @@ func (p *Processor) HandleGetBDTPolicyContextRequest( func (p *Processor) HandleUpdateBDTPolicyContextProcedure( c *gin.Context, bdtPolicyID string, - bdtPolicyDataPatch models.BdtPolicyDataPatch) { + bdtPolicyDataPatch models.BdtPolicyDataPatch, +) { // step 1: log logger.BdtPolicyLog.Infof("Handle UpdateBDTPolicyContext") @@ -111,7 +113,8 @@ func (p *Processor) HandleUpdateBDTPolicyContextProcedure( // CreateBDTPolicy - Create a new Individual BDT policy func (p *Processor) HandleCreateBDTPolicyContextRequest( c *gin.Context, - requestMsg models.BdtReqData) { + requestMsg models.BdtReqData, +) { // step 1: log logger.BdtPolicyLog.Infof("Handle CreateBDTPolicyContext") @@ -235,15 +238,12 @@ func (p *Processor) HandleCreateBDTPolicyContextRequest( locationHeader := util.GetResourceUri(models.ServiceName_NPCF_BDTPOLICYCONTROL, bdtPolicyID) logger.BdtPolicyLog.Tracef("BDT Policy Id[%s] Create", bdtPolicyID) - if response != nil { - // status code is based on SPEC, and option headers - c.Header("Location", locationHeader) - c.JSON(http.StatusCreated, response) - } else if problemDetails != nil { + if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) - } else { - c.JSON(http.StatusNotFound, nil) + return } + c.Header("Location", locationHeader) + c.JSON(http.StatusCreated, response) } func (p *Processor) getDefaultUdrUri(context *pcf_context.PCFContext) string { diff --git a/internal/sbi/processor/callback.go b/internal/sbi/processor/callback.go index 9476d2c..f55da14 100644 --- a/internal/sbi/processor/callback.go +++ b/internal/sbi/processor/callback.go @@ -5,16 +5,18 @@ import ( "net/http" "strings" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" - "github.com/gin-gonic/gin" ) func (p *Processor) HandleAmfStatusChangeNotify( c *gin.Context, - amfStatusChangeNotification models.AmfStatusChangeNotification) { + amfStatusChangeNotification models.AmfStatusChangeNotification, +) { logger.CallbackLog.Warnf("[PCF] Handle Amf Status Change Notify is not implemented.") // TODO: handle AMF Status Change Notify @@ -26,8 +28,8 @@ func (p *Processor) HandleAmfStatusChangeNotify( func (p *Processor) HandlePolicyDataChangeNotify( c *gin.Context, supi string, - policyDataChangeNotification models.PolicyDataChangeNotification) { - + policyDataChangeNotification models.PolicyDataChangeNotification, +) { logger.CallbackLog.Warnf("[PCF] Handle Policy Data Change Notify is not implemented.") PolicyDataChangeNotifyProcedure(supi, policyDataChangeNotification) @@ -43,8 +45,8 @@ func (p *Processor) HandleInfluenceDataUpdateNotify( c *gin.Context, supi string, pduSessionId string, - trafficInfluDataNotif []models.TrafficInfluDataNotif) { - + trafficInfluDataNotif []models.TrafficInfluDataNotif, +) { logger.CallbackLog.Infof("[PCF] Handle Influence Data Update Notify") smPolicyID := fmt.Sprintf("%s-%s", supi, pduSessionId) diff --git a/internal/sbi/processor/oam.go b/internal/sbi/processor/oam.go index 702ad8a..442ac46 100644 --- a/internal/sbi/processor/oam.go +++ b/internal/sbi/processor/oam.go @@ -26,7 +26,8 @@ type UEAmPolicys []UEAmPolicy func (p *Processor) HandleOAMGetAmPolicyRequest( c *gin.Context, - supi string) { + supi string, +) { // step 1: log logger.OamLog.Infof("Handle OAMGetAmPolicy") @@ -63,5 +64,4 @@ func (p *Processor) HandleOAMGetAmPolicyRequest( c.JSON(int(problemDetails.Status), problemDetails) return } - } diff --git a/internal/sbi/processor/policyauthorization.go b/internal/sbi/processor/policyauthorization.go index 2559776..b2acd4b 100644 --- a/internal/sbi/processor/policyauthorization.go +++ b/internal/sbi/processor/policyauthorization.go @@ -130,7 +130,8 @@ func handleMediaSubComponent(smPolicy *pcf_context.UeSmPolicyData, medComp *mode // Support of content versioning (TODO) func (p *Processor) HandlePostAppSessionsContext( c *gin.Context, - appSessionContext models.AppSessionContext) { + appSessionContext models.AppSessionContext, +) { logger.PolicyAuthLog.Traceln("Handle Create AppSessions") response, locationHeader, problemDetails := p.postAppSessCtxProcedure(&appSessionContext) @@ -437,8 +438,8 @@ func (p *Processor) postAppSessCtxProcedure(appSessCtx *models.AppSessionContext func (p *Processor) HandleDeleteAppSessionContext( c *gin.Context, appSessionId string, - eventsSubscReqData *models.EventsSubscReqData) { - + eventsSubscReqData *models.EventsSubscReqData, +) { logger.PolicyAuthLog.Infof("Handle Del AppSessions, AppSessionId[%s]", appSessionId) pcfSelf := pcf_context.GetSelf() @@ -497,8 +498,8 @@ func (p *Processor) HandleDeleteAppSessionContext( // HandleGetAppSession - Reads an existing Individual Application Session Context func (p *Processor) HandleGetAppSessionContext( c *gin.Context, - appSessionId string) { - + appSessionId string, +) { logger.PolicyAuthLog.Infof("Handle Get AppSessions, AppSessionId[%s]", appSessionId) pcfSelf := pcf_context.GetSelf() @@ -514,15 +515,14 @@ func (p *Processor) HandleGetAppSessionContext( } logger.PolicyAuthLog.Tracef("App Session Id[%s] Get", appSessionId) c.JSON(http.StatusOK, appSession.AppSessionContext) - } // HandleModAppSession - Modifies an existing Individual Application Session Context func (p *Processor) HandleModAppSessionContext( c *gin.Context, appSessionId string, - appSessionContextUpdateData models.AppSessionContextUpdateData) { - + appSessionContextUpdateData models.AppSessionContextUpdateData, +) { // appSessID := request.Params["appSessionId"] // ascUpdateData := request.Body.(models.AppSessionContextUpdateData) logger.PolicyAuthLog.Infof("Handle Modify AppSessions, AppSessionId[%s]", appSessionId) @@ -808,7 +808,8 @@ func (p *Processor) HandleModAppSessionContext( // HandleDeleteEventsSubsc - deletes the Events Subscription subresource func (p *Processor) HandleDeleteEventsSubscContext( c *gin.Context, - appSessionId string) { + appSessionId string, +) { // appSessID := request.Params["appSessID"] logger.PolicyAuthLog.Tracef("Handle Del AppSessions Events Subsc, AppSessionId[%s]", appSessionId) @@ -852,14 +853,12 @@ func (p *Processor) HandleDeleteEventsSubscContext( func (p *Processor) HandleUpdateEventsSubscContext( c *gin.Context, appSessionId string, - eventsSubscReqData models.EventsSubscReqData) { - + eventsSubscReqData models.EventsSubscReqData, +) { // EventsSubscReqData := request.Body.(models.EventsSubscReqData) // appSessID := request.Params["appSessID"] logger.PolicyAuthLog.Tracef("Handle Put AppSessions Events Subsc, AppSessionId[%s]", appSessionId) - // response, locationHeader, status, problemDetails := UpdateEventsSubscContextProcedure(appSessionId, eventsSubscReqData) - pcfSelf := pcf_context.GetSelf() var appSession *pcf_context.AppSessionData diff --git a/internal/sbi/processor/smpolicy.go b/internal/sbi/processor/smpolicy.go index 9d234e1..9c7d0fe 100644 --- a/internal/sbi/processor/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -29,8 +29,8 @@ const ( // SmPoliciesPost - func (p *Processor) HandleCreateSmPolicyRequest( c *gin.Context, - request models.SmPolicyContextData) { - + request models.SmPolicyContextData, +) { logger.SmPolicyLog.Infof("Handle CreateSmPolicy") // step 2: retrieve request // requestDataType := request.Body.(models.SmPolicyContextData) @@ -492,8 +492,8 @@ func newQosDataWithQosFlowMap(qosFlow map[string]interface{}) *models.QosData { // SmPoliciessmPolicyIDDeletePost - func (p *Processor) HandleDeleteSmPolicyContextRequest( c *gin.Context, - smPolicyId string) { - + smPolicyId string, +) { logger.SmPolicyLog.Infof("Handle DeleteSmPolicyContext") // handle the message @@ -547,14 +547,13 @@ func (p *Processor) HandleDeleteSmPolicyContextRequest( } delete(ue.RatingGroupData, smPolicyId) c.JSON(http.StatusNoContent, nil) - } // SmPoliciessmPolicyIDGet - func (p *Processor) HandleGetSmPolicyContextRequest( c *gin.Context, - smPolicyId string) { - + smPolicyId string, +) { logger.SmPolicyLog.Infof("Handle GetSmPolicyContext") // handle the message logger.SmPolicyLog.Traceln("Handle GET SM Policy Request") @@ -579,7 +578,8 @@ func (p *Processor) HandleGetSmPolicyContextRequest( func (p *Processor) HandleUpdateSmPolicyContextRequest( c *gin.Context, smPolicyId string, - request models.SmPolicyUpdateContextData) { + request models.SmPolicyUpdateContextData, +) { // step 1: log logger.SmPolicyLog.Infof("Handle UpdateSmPolicyContext") diff --git a/internal/sbi/server.go b/internal/sbi/server.go index be5fc58..024d893 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -13,8 +13,6 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/free5gc/openapi" - // "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/sbi/consumer" @@ -64,7 +62,6 @@ type Server struct { httpServer *http.Server router *gin.Engine - processor *processor.Processor } func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { @@ -182,100 +179,3 @@ func (s *Server) startServer(wg *sync.WaitGroup) { } logger.SBILog.Warnf("SBI server (listen on %s) stopped", s.httpServer.Addr) } - -func checkContentTypeIsJSON(gc *gin.Context) (string, error) { - var err error - contentType := gc.GetHeader("Content-Type") - if openapi.KindOfMediaType(contentType) != openapi.MediaKindJSON { - err = fmt.Errorf("Wrong content type %q", contentType) - } - - if err != nil { - logger.SBILog.Error(err) - gc.JSON(http.StatusInternalServerError, - openapi.ProblemDetailsMalformedReqSyntax(err.Error())) - return "", err - } - - return contentType, nil -} - -func (s *Server) deserializeData(gc *gin.Context, data interface{}, contentType string) error { - reqBody, err := gc.GetRawData() - if err != nil { - logger.SBILog.Errorf("Get Request Body error: %v", err) - gc.JSON(http.StatusInternalServerError, - openapi.ProblemDetailsSystemFailure(err.Error())) - return err - } - - err = openapi.Deserialize(data, reqBody, contentType) - if err != nil { - logger.SBILog.Errorf("Deserialize Request Body error: %v", err) - gc.JSON(http.StatusBadRequest, - openapi.ProblemDetailsMalformedReqSyntax(err.Error())) - return err - } - - return nil -} - -func (s *Server) bindData(gc *gin.Context, data interface{}) error { - err := gc.Bind(data) - if err != nil { - logger.SBILog.Errorf("Bind Request Body error: %v", err) - gc.JSON(http.StatusBadRequest, - openapi.ProblemDetailsMalformedReqSyntax(err.Error())) - return err - } - - return nil -} - -func (s *Server) buildAndSendHttpResponse( - gc *gin.Context, - hdlRsp *processor.HandlerResponse, - multipart bool, -) { - if hdlRsp.Status == 0 { - // No Response to send - return - } - - rsp := httpwrapper.NewResponse(hdlRsp.Status, hdlRsp.Headers, hdlRsp.Body) - - buildHttpResponseHeader(gc, rsp) - - var rspBody []byte - var contentType string - var err error - if multipart { - rspBody, contentType, err = openapi.MultipartSerialize(rsp.Body) - } else { - // TODO: support other JSON content-type - rspBody, err = openapi.Serialize(rsp.Body, "application/json") - contentType = "application/json" - } - - if err != nil { - logger.SBILog.Errorln(err) - gc.JSON(http.StatusInternalServerError, openapi.ProblemDetailsSystemFailure(err.Error())) - } else { - gc.Data(rsp.Status, contentType, rspBody) - } -} - -func buildHttpResponseHeader(gc *gin.Context, rsp *httpwrapper.Response) { - for k, v := range rsp.Header { - // Concatenate all values of the Header with ',' - allValues := "" - for i, vv := range v { - if i == 0 { - allValues += vv - } else { - allValues += "," + vv - } - } - gc.Header(k, allValues) - } -} diff --git a/pkg/service/init.go b/pkg/service/init.go index 7c478df..05208e1 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -41,7 +41,7 @@ func NewApp( pcf.SetLogLevel(cfg.GetLogLevel()) pcf.SetReportCaller(cfg.GetLogReportCaller()) - //這段要嗎? + // 這段要嗎? // pcf.ctx, pcf.cancel = context.WithCancel(ctx) // err := pcf_context.InitPcfContext() // if err != nil { @@ -51,14 +51,14 @@ func NewApp( pcf_context.Init() pcf.pcfCtx = pcf_context.GetSelf() - //processor + // processor // p, err := processor.NewProcessor(pcf) // if err != nil { // return pcf, err // } // pcf.processor = p - //consumer + // consumer consumer, err := consumer.NewConsumer(pcf) if err != nil { return pcf, err @@ -134,8 +134,8 @@ func (a *PcfApp) Start(tlsKeyLogPath string) { if err := a.sbiServer.Run(context.Background(), &a.wg); err != nil { logger.InitLog.Fatalf("Run SBI server failed: %+v", err) } - } + func (a *PcfApp) listenShutdownEvent() { defer func() { if p := recover(); p != nil { @@ -152,6 +152,7 @@ func (a *PcfApp) listenShutdownEvent() { a.Terminate() } } + func (a *PcfApp) Terminate() { logger.InitLog.Infof("Terminating PCF...") // deregister with NRF From 0cee90c3c4c6ba2c450597af4bdfc0701731e53b Mon Sep 17 00:00:00 2001 From: chh Date: Wed, 29 May 2024 13:50:40 +0000 Subject: [PATCH 12/20] fix: new sbiServer bug --- cmd/main.go | 34 +++++++---------------- internal/context/context.go | 4 +-- internal/sbi/api_ampolicy.go | 5 ---- internal/sbi/server.go | 24 ++++++++++++++-- pkg/service/init.go | 53 ++++++++++++++++++++++-------------- 5 files changed, 66 insertions(+), 54 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 4702341..14e6c33 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -18,9 +18,7 @@ import ( "os/signal" "path/filepath" "runtime/debug" - "sync" "syscall" - "time" "github.com/urfave/cli" @@ -72,42 +70,30 @@ func action(cliCtx *cli.Context) error { ctx, cancel := context.WithCancel(context.Background()) sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) - wg := new(sync.WaitGroup) - wg.Add(1) - go func() { - defer wg.Done() - <-sigCh // Wait for interrupt signal to gracefully shutdown UPF - - logger.MainLog.Warnln("Terminating... (Wait 2s for other NFs to deregister)") - time.Sleep(2 * time.Second) // Waiting for other NFs to deregister - cancel() // Notify each goroutine and wait them stopped - if PCF != nil { - PCF.WaitRoutineStopped() - } - }() - defer func() { - select { - case sigCh <- nil: // Send signal in case of returning with error - default: - } - wg.Wait() - logger.MainLog.Infof("PCF Stopped...") + go func() { + <-sigCh // Wait for interrupt signal to gracefully shutdown UPF + cancel() // Notify each goroutine and wait them stopped }() cfg, err := factory.ReadConfig(cliCtx.String("config")) if err != nil { + sigCh <- nil return err } factory.PcfConfig = cfg pcf, err := service.NewApp(ctx, cfg, tlsKeyLogPath) if err != nil { + sigCh <- nil return err } PCF = pcf - - pcf.Start(tlsKeyLogPath) + if pcf == nil { + logger.MainLog.Infoln("pcf is nil") + } + pcf.Start() + PCF.WaitRoutineStopped() return nil } diff --git a/internal/context/context.go b/internal/context/context.go index 7fd925b..4d830b2 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -82,7 +82,7 @@ type NFContext interface { var _ NFContext = &PCFContext{} -func InitpcfContext(context *PCFContext) { +func InitPcfContext(context *PCFContext) { config := factory.PcfConfig logger.UtilLog.Infof("pcfconfig Info: Version[%s] Description[%s]", config.Info.Version, config.Info.Description) configuration := config.Configuration @@ -157,7 +157,7 @@ func Init() { pcfContext.PcfSuppFeats = make(map[models.ServiceName]openapi.SupportedFeature) pcfContext.BdtPolicyIDGenerator = idgenerator.NewGenerator(1, math.MaxInt64) pcfContext.RatingGroupIdGenerator = idgenerator.NewGenerator(1, math.MaxInt64) - InitpcfContext(&pcfContext) + InitPcfContext(&pcfContext) } // Create new PCF context diff --git a/internal/sbi/api_ampolicy.go b/internal/sbi/api_ampolicy.go index 70b581c..470f860 100644 --- a/internal/sbi/api_ampolicy.go +++ b/internal/sbi/api_ampolicy.go @@ -148,11 +148,6 @@ func (s *Server) getAmPolicyRoutes() []Route { Pattern: "/policies/:polAssoId", APIFunc: s.HTTPPoliciesPolAssoIdDelete, }, - { - Method: http.MethodGet, - Pattern: "/policies/:polAssoId", - APIFunc: s.HTTPPoliciesPolAssoIdGet, - }, { Method: http.MethodPost, Pattern: "/policies/:polAssoId/update", diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 024d893..fde5795 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -13,10 +13,13 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/free5gc/openapi/models" pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/sbi/consumer" "github.com/free5gc/pcf/internal/sbi/processor" + "github.com/free5gc/pcf/internal/util" + "github.com/free5gc/pcf/pkg/app" "github.com/free5gc/pcf/pkg/factory" "github.com/free5gc/util/httpwrapper" logger_util "github.com/free5gc/util/logger" @@ -50,9 +53,7 @@ func applyRoutes(group *gin.RouterGroup, routes []Route) { } type pcf interface { - Config() *factory.Config - Context() *pcf_context.PCFContext - CancelContext() context.Context + app.App Processor() *processor.Processor Consumer() *consumer.Consumer } @@ -76,10 +77,18 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { amPolicyRoutes := s.getAmPolicyRoutes() amPolicyGroup := s.router.Group(factory.PcfAMpolicyCtlResUriPrefix) + amRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_AM_POLICY_CONTROL) + amPolicyGroup.Use(func(c *gin.Context) { + amRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + }) applyRoutes(amPolicyGroup, amPolicyRoutes) bdtPolicyRoutes := s.getBdtPolicyRoutes() bdtPolicyGroup := s.router.Group(factory.PcfBdtPolicyCtlResUriPrefix) + bdtRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_BDTPOLICYCONTROL) + bdtPolicyGroup.Use(func(c *gin.Context) { + bdtRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + }) applyRoutes(bdtPolicyGroup, bdtPolicyRoutes) httpcallbackRoutes := s.getHttpCallBackRoutes() @@ -88,10 +97,18 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { oamRoutes := s.getOamRoutes() oamGroup := s.router.Group(factory.PcfOamResUriPrefix) + oamRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_OAM) + oamGroup.Use(func(c *gin.Context) { + oamRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + }) applyRoutes(oamGroup, oamRoutes) policyAuthorizationRoutes := s.getPolicyAuthorizationRoutes() policyAuthorizationGroup := s.router.Group(factory.PcfPolicyAuthResUriPrefix) + policyAuthorizationRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_POLICYAUTHORIZATION) + policyAuthorizationGroup.Use(func(c *gin.Context) { + policyAuthorizationRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + }) applyRoutes(policyAuthorizationGroup, policyAuthorizationRoutes) uePolicyRoutes := s.getUePolicyRoutes() @@ -126,6 +143,7 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { var err error _, s.Context().NfId, err = s.Consumer().SendRegisterNFInstance(context.Background()) + if err != nil { logger.InitLog.Errorf("CHF register to NRF Error[%s]", err.Error()) } diff --git a/pkg/service/init.go b/pkg/service/init.go index 05208e1..47ec3d0 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -13,17 +13,24 @@ import ( "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/sbi" "github.com/free5gc/pcf/internal/sbi/consumer" + "github.com/free5gc/pcf/internal/sbi/processor" + "github.com/free5gc/pcf/pkg/app" "github.com/free5gc/pcf/pkg/factory" ) +var PCF *PcfApp + +var _ app.App = &PcfApp{} + type PcfApp struct { + app.App cfg *factory.Config pcfCtx *pcf_context.PCFContext ctx context.Context cancel context.CancelFunc - consumer *consumer.Consumer - // processor *processor.Processor + consumer *consumer.Consumer + processor *processor.Processor sbiServer *sbi.Server wg sync.WaitGroup } @@ -41,29 +48,29 @@ func NewApp( pcf.SetLogLevel(cfg.GetLogLevel()) pcf.SetReportCaller(cfg.GetLogReportCaller()) - // 這段要嗎? - // pcf.ctx, pcf.cancel = context.WithCancel(ctx) - // err := pcf_context.InitPcfContext() - // if err != nil { - // logger.InitLog.Errorln(err) - // return pcf, err - // } + pcf.ctx, pcf.cancel = context.WithCancel(ctx) pcf_context.Init() pcf.pcfCtx = pcf_context.GetSelf() - // processor - // p, err := processor.NewProcessor(pcf) - // if err != nil { - // return pcf, err - // } - // pcf.processor = p - // consumer consumer, err := consumer.NewConsumer(pcf) if err != nil { return pcf, err } pcf.consumer = consumer + + // processor + p, err := processor.NewProcessor(pcf, consumer) + if err != nil { + return pcf, err + } + pcf.processor = p + + if pcf.sbiServer, err = sbi.NewServer(pcf, tlsKeyLogPath); err != nil { + return nil, err + } + PCF = pcf + return pcf, nil } @@ -83,6 +90,10 @@ func (a *PcfApp) Consumer() *consumer.Consumer { return a.consumer } +func (a *PcfApp) Processor() *processor.Processor { + return a.processor +} + func (a *PcfApp) SetLogEnable(enable bool) { logger.MainLog.Infof("Log enable is set to [%v]", enable) if enable && logger.Log.Out == os.Stderr { @@ -125,11 +136,9 @@ func (a *PcfApp) SetReportCaller(reportCaller bool) { logger.Log.SetReportCaller(reportCaller) } -func (a *PcfApp) Start(tlsKeyLogPath string) { +func (a *PcfApp) Start() { logger.InitLog.Infoln("Server started") - a.wg.Add(1) - go a.listenShutdownEvent() if err := a.sbiServer.Run(context.Background(), &a.wg); err != nil { logger.InitLog.Fatalf("Run SBI server failed: %+v", err) @@ -146,15 +155,19 @@ func (a *PcfApp) listenShutdownEvent() { }() <-a.ctx.Done() + a.Terminate() +} +func (a *PcfApp) CallServerStop() { if a.sbiServer != nil { a.sbiServer.Stop(context.Background()) - a.Terminate() } } func (a *PcfApp) Terminate() { logger.InitLog.Infof("Terminating PCF...") + a.cancel() + a.CallServerStop() // deregister with NRF problemDetails, err := a.consumer.SendDeregisterNFInstance() if problemDetails != nil { From c4ec427f97f42e872c44e1574c5737482917ff76 Mon Sep 17 00:00:00 2001 From: chh Date: Mon, 3 Jun 2024 06:28:22 +0000 Subject: [PATCH 13/20] fix: fix polAssoId for ampolicy --- internal/sbi/api_ampolicy.go | 18 ++++-------------- internal/sbi/server.go | 4 ++-- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/internal/sbi/api_ampolicy.go b/internal/sbi/api_ampolicy.go index 470f860..692cd07 100644 --- a/internal/sbi/api_ampolicy.go +++ b/internal/sbi/api_ampolicy.go @@ -12,7 +12,7 @@ import ( ) func (s *Server) HTTPPoliciesPolAssoIdDelete(c *gin.Context) { - polAssoId := c.Param("polAssoId") + polAssoId, _ := c.Params.Get("polAssoId") if polAssoId == "" { problemDetails := &models.ProblemDetails{ @@ -28,7 +28,7 @@ func (s *Server) HTTPPoliciesPolAssoIdDelete(c *gin.Context) { // HTTPPoliciesPolAssoIdGet - func (s *Server) HTTPPoliciesPolAssoIdGet(c *gin.Context) { - polAssoId := c.Param("polAssoId") + polAssoId, _ := c.Params.Get("polAssoId") if polAssoId == "" { problemDetails := &models.ProblemDetails{ @@ -72,7 +72,7 @@ func (s *Server) HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { return } - polAssoId := c.Param("polAssoId") + polAssoId, _ := c.Params.Get("polAssoId") if polAssoId == "" { problemDetails := &models.ProblemDetails{ @@ -88,7 +88,6 @@ func (s *Server) HTTPPoliciesPolAssoIdUpdatePost(c *gin.Context) { func (s *Server) HTTPPoliciesPost(c *gin.Context) { var policyAssociationRequest models.PolicyAssociationRequest - requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -122,16 +121,7 @@ func (s *Server) HTTPPoliciesPost(c *gin.Context) { return } - polAssoId := c.Param("polAssoId") - - if polAssoId == "" { - problemDetails := &models.ProblemDetails{ - Title: util.ERROR_INITIAL_PARAMETERS, - Status: http.StatusBadRequest, - } - c.JSON(http.StatusBadRequest, problemDetails) - return - } + polAssoId, _ := c.Params.Get("polAssoId") s.Processor().HandlePostPolicies(c, polAssoId, policyAssociationRequest) } diff --git a/internal/sbi/server.go b/internal/sbi/server.go index fde5795..0240a80 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -105,7 +105,8 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { policyAuthorizationRoutes := s.getPolicyAuthorizationRoutes() policyAuthorizationGroup := s.router.Group(factory.PcfPolicyAuthResUriPrefix) - policyAuthorizationRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_POLICYAUTHORIZATION) + policyAuthorizationRouterAuthorizationCheck := util. + NewRouterAuthorizationCheck(models.ServiceName_NPCF_POLICYAUTHORIZATION) policyAuthorizationGroup.Use(func(c *gin.Context) { policyAuthorizationRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) }) @@ -143,7 +144,6 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { var err error _, s.Context().NfId, err = s.Consumer().SendRegisterNFInstance(context.Background()) - if err != nil { logger.InitLog.Errorf("CHF register to NRF Error[%s]", err.Error()) } From 55d26fef745ad37a38d02f133b08d6d0a703be55 Mon Sep 17 00:00:00 2001 From: chh Date: Mon, 10 Jun 2024 15:06:07 +0000 Subject: [PATCH 14/20] style: clean code --- .gitignore | 1 - cmd/main.go | 2 +- internal/sbi/api_httpcallback.go | 17 ++++++++++++++++ internal/sbi/api_oam.go | 30 ++++++++++++++++++++++++++++ internal/sbi/api_smpolicy.go | 8 ++++++++ internal/sbi/api_uepolicy.go | 4 ++++ internal/sbi/consumer/nrf_service.go | 20 +++---------------- internal/sbi/processor/bdtpolicy.go | 1 - internal/sbi/server.go | 21 ++----------------- pkg/service/init.go | 2 +- 10 files changed, 66 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index b457816..c294e4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -/bin/ # Swap files *.swp diff --git a/cmd/main.go b/cmd/main.go index 14e6c33..6fd6c10 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -93,7 +93,7 @@ func action(cliCtx *cli.Context) error { logger.MainLog.Infoln("pcf is nil") } pcf.Start() - PCF.WaitRoutineStopped() + pcf.WaitRoutineStopped() return nil } diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index f1ddb79..20bc5f5 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -8,6 +8,7 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/pcf/internal/logger" + "github.com/free5gc/pcf/internal/util" ) func (s *Server) getHttpCallBackRoutes() []Route { @@ -95,6 +96,14 @@ func (s *Server) HTTPUdrPolicyDataChangeNotify(c *gin.Context) { } supi := c.Params.ByName("supi") + if supi == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, + } + c.JSON(http.StatusBadRequest, problemDetails) + return + } s.Processor().HandlePolicyDataChangeNotify(c, supi, policyDataChangeNotification) } @@ -130,5 +139,13 @@ func (s *Server) HTTPUdrInfluenceDataUpdateNotify(c *gin.Context) { supi := c.Params.ByName("supi") pduSessionId := c.Params.ByName("pduSessionId") + if supi == "" || pduSessionId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, + } + c.JSON(http.StatusBadRequest, problemDetails) + return + } s.Processor().HandleInfluenceDataUpdateNotify(c, supi, pduSessionId, trafficInfluDataNotif) } diff --git a/internal/sbi/api_oam.go b/internal/sbi/api_oam.go index 177be54..d6e4199 100644 --- a/internal/sbi/api_oam.go +++ b/internal/sbi/api_oam.go @@ -3,10 +3,32 @@ package sbi import ( "net/http" + "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/pcf/internal/util" +) + +const ( + CorsConfigMaxAge = 86400 ) func (s *Server) setCorsHeader(c *gin.Context) { + // TODO: 1. turn these values into configurable variables + // TODO: 2. use the official cors middleware + s.router.Use(cors.New(cors.Config{ + AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, + AllowHeaders: []string{ + "Origin", "Content-Length", "Content-Type", "User-Agent", + "Referrer", "Host", "Token", "X-Requested-With", + }, + ExposeHeaders: []string{"Content-Length"}, + AllowCredentials: true, + AllowAllOrigins: true, + MaxAge: CorsConfigMaxAge, + })) + c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set( @@ -19,6 +41,14 @@ func (s *Server) HTTPOAMGetAmPolicy(c *gin.Context) { s.setCorsHeader(c) supi := c.Params.ByName("supi") + if supi == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, + } + c.JSON(http.StatusBadRequest, problemDetails) + return + } s.Processor().HandleOAMGetAmPolicyRequest(c, supi) } diff --git a/internal/sbi/api_smpolicy.go b/internal/sbi/api_smpolicy.go index 0ac65b6..9e770fd 100644 --- a/internal/sbi/api_smpolicy.go +++ b/internal/sbi/api_smpolicy.go @@ -138,5 +138,13 @@ func (s *Server) HTTPSmPoliciesSmPolicyIdUpdatePost(c *gin.Context) { } smPolicyId := c.Params.ByName("smPolicyId") + if smPolicyId == "" { + problemDetails := &models.ProblemDetails{ + Title: util.ERROR_INITIAL_PARAMETERS, + Status: http.StatusBadRequest, + } + c.JSON(http.StatusBadRequest, problemDetails) + return + } s.Processor().HandleUpdateSmPolicyContextRequest(c, smPolicyId, smPolicyUpdateContextData) } diff --git a/internal/sbi/api_uepolicy.go b/internal/sbi/api_uepolicy.go index 52cfab4..9eb778d 100644 --- a/internal/sbi/api_uepolicy.go +++ b/internal/sbi/api_uepolicy.go @@ -42,16 +42,20 @@ func (s *Server) getUePolicyRoutes() []Route { // PoliciesPolAssoIdDelete - func (s *Server) PoliciesPolAssoIdDelete(c *gin.Context) { + c.JSON(http.StatusNotImplemented, nil) } // PoliciesPolAssoIdGet - func (s *Server) PoliciesPolAssoIdGet(c *gin.Context) { + c.JSON(http.StatusNotImplemented, nil) } // PoliciesPolAssoIdUpdatePost - func (s *Server) PoliciesPolAssoIdUpdatePost(c *gin.Context) { + c.JSON(http.StatusNotImplemented, nil) } // PoliciesPost - func (s *Server) PoliciesPost(c *gin.Context) { + c.JSON(http.StatusNotImplemented, nil) } diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 37f2a4a..17cbc13 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -90,11 +90,13 @@ func (s *nnrfService) SendSearchNFInstances( if err != nil { logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err) } + defer func() { if resCloseErr := res.Body.Close(); resCloseErr != nil { logger.ConsumerLog.Errorf("NFInstancesStoreApi response body cannot close: %+v", resCloseErr) } }() + if res != nil && res.StatusCode == http.StatusTemporaryRedirect { return nil, fmt.Errorf("Temporary Redirect For Non NRF Consumer") } @@ -108,14 +110,6 @@ func (s *nnrfService) SendNFInstancesUDR(nrfUri, id string) string { localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ // DataSet: optional.NewInterface(models.DataSetId_SUBSCRIPTION), } - // switch types { - // case NFDiscoveryToUDRParamSupi: - // localVarOptionals.Supi = optional.NewString(id) - // case NFDiscoveryToUDRParamExtGroupId: - // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) - // case NFDiscoveryToUDRParamGpsi: - // localVarOptionals.Gpsi = optional.NewString(id) - // } result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) if err != nil { @@ -156,14 +150,6 @@ func (s *nnrfService) SendNFInstancesAMF(nrfUri string, guami models.Guami, serv localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ Guami: optional.NewInterface(util.MarshToJsonString(guami)), } - // switch types { - // case NFDiscoveryToUDRParamSupi: - // localVarOptionals.Supi = optional.NewString(id) - // case NFDiscoveryToUDRParamExtGroupId: - // localVarOptionals.ExternalGroupIdentity = optional.NewString(id) - // case NFDiscoveryToUDRParamGpsi: - // localVarOptionals.Gpsi = optional.NewString(id) - // } result, err := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, localVarOptionals) if err != nil { @@ -226,7 +212,7 @@ func (s *nnrfService) SendRegisterNFInstance(ctx context.Context) ( for { nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), pcfContext.NfId, nfProfile) if err != nil || res == nil { - logger.ConsumerLog.Errorf("CHF register to NRF Error[%v]", err) + logger.ConsumerLog.Errorf("PCF register to NRF Error[%v]", err) time.Sleep(2 * time.Second) continue } diff --git a/internal/sbi/processor/bdtpolicy.go b/internal/sbi/processor/bdtpolicy.go index 02151ce..05de96d 100644 --- a/internal/sbi/processor/bdtpolicy.go +++ b/internal/sbi/processor/bdtpolicy.go @@ -121,7 +121,6 @@ func (p *Processor) HandleCreateBDTPolicyContextRequest( var problemDetails *models.ProblemDetails // step 2: retrieve request and check mandatory contents - // requestMsg := request.Body.(models.BdtReqData) if requestMsg.AspId == "" || requestMsg.DesTimeInt == nil || requestMsg.NumOfUes == 0 || requestMsg.VolPerUe == nil { logger.BdtPolicyLog.Errorf("Required BdtReqData not found: AspId[%+v], DesTimeInt[%+v], NumOfUes[%+v], VolPerUe[%+v]", requestMsg.AspId, requestMsg.DesTimeInt, requestMsg.NumOfUes, requestMsg.VolPerUe) diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 0240a80..93e7abb 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -9,7 +9,6 @@ import ( "sync" "time" - "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" @@ -25,10 +24,6 @@ import ( logger_util "github.com/free5gc/util/logger" ) -const ( - CorsConfigMaxAge = 86400 -) - type Route struct { Method string Pattern string @@ -116,18 +111,6 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { uePolicyGroup := s.router.Group(factory.PcfUePolicyCtlResUriPrefix) applyRoutes(uePolicyGroup, uePolicyRoutes) - s.router.Use(cors.New(cors.Config{ - AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, - AllowHeaders: []string{ - "Origin", "Content-Length", "Content-Type", "User-Agent", - "Referrer", "Host", "Token", "X-Requested-With", - }, - ExposeHeaders: []string{"Content-Length"}, - AllowCredentials: true, - AllowAllOrigins: true, - MaxAge: CorsConfigMaxAge, - })) - cfg := s.Config() bindAddr := cfg.GetSbiBindingAddr() logger.SBILog.Infof("Binding addr: [%s]", bindAddr) @@ -145,7 +128,7 @@ func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { var err error _, s.Context().NfId, err = s.Consumer().SendRegisterNFInstance(context.Background()) if err != nil { - logger.InitLog.Errorf("CHF register to NRF Error[%s]", err.Error()) + logger.InitLog.Errorf("PCF register to NRF Error[%s]", err.Error()) } wg.Add(1) @@ -154,7 +137,7 @@ func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { return nil } -func (s *Server) Stop(traceCtx context.Context) { +func (s *Server) Shutdown(traceCtx context.Context) { const defaultShutdownTimeout time.Duration = 2 * time.Second if s.httpServer != nil { diff --git a/pkg/service/init.go b/pkg/service/init.go index 47ec3d0..abba858 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -160,7 +160,7 @@ func (a *PcfApp) listenShutdownEvent() { func (a *PcfApp) CallServerStop() { if a.sbiServer != nil { - a.sbiServer.Stop(context.Background()) + a.sbiServer.Shutdown(context.Background()) } } From 2dc47215826f812d4674898a9d6bf38c738d6173 Mon Sep 17 00:00:00 2001 From: chh Date: Fri, 21 Jun 2024 13:58:12 +0000 Subject: [PATCH 15/20] fix: add terminate --- cmd/main.go | 1 - internal/sbi/consumer/nrf_service.go | 2 +- internal/sbi/server.go | 3 ++- pkg/service/init.go | 13 ++++++------- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 6fd6c10..86bdc4a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -93,7 +93,6 @@ func action(cliCtx *cli.Context) error { logger.MainLog.Infoln("pcf is nil") } pcf.Start() - pcf.WaitRoutineStopped() return nil } diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 17cbc13..d786dee 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -210,7 +210,7 @@ func (s *nnrfService) SendRegisterNFInstance(ctx context.Context) ( var nf models.NfProfile var res *http.Response for { - nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), pcfContext.NfId, nfProfile) + nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, pcfContext.NfId, nfProfile) if err != nil || res == nil { logger.ConsumerLog.Errorf("PCF register to NRF Error[%v]", err) time.Sleep(2 * time.Second) diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 93e7abb..babdb99 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -155,6 +155,7 @@ func (s *Server) startServer(wg *sync.WaitGroup) { if p := recover(); p != nil { // Print stack for panic to log. Fatalf() will let program exit. logger.SBILog.Fatalf("panic: %v\n%s", p, string(debug.Stack())) + s.Terminate() } wg.Done() @@ -178,5 +179,5 @@ func (s *Server) startServer(wg *sync.WaitGroup) { if err != nil && err != http.ErrServerClosed { logger.SBILog.Errorf("SBI server error: %v", err) } - logger.SBILog.Warnf("SBI server (listen on %s) stopped", s.httpServer.Addr) + logger.SBILog.Infof("SBI server (listen on %s) stopped", s.httpServer.Addr) } diff --git a/pkg/service/init.go b/pkg/service/init.go index abba858..9fb85c2 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -143,6 +143,7 @@ func (a *PcfApp) Start() { if err := a.sbiServer.Run(context.Background(), &a.wg); err != nil { logger.InitLog.Fatalf("Run SBI server failed: %+v", err) } + a.WaitRoutineStopped() } func (a *PcfApp) listenShutdownEvent() { @@ -155,7 +156,7 @@ func (a *PcfApp) listenShutdownEvent() { }() <-a.ctx.Done() - a.Terminate() + a.terminateProcedure() } func (a *PcfApp) CallServerStop() { @@ -165,8 +166,11 @@ func (a *PcfApp) CallServerStop() { } func (a *PcfApp) Terminate() { - logger.InitLog.Infof("Terminating PCF...") a.cancel() +} + +func (a *PcfApp) terminateProcedure() { + logger.MainLog.Infof("Terminating PCF...") a.CallServerStop() // deregister with NRF problemDetails, err := a.consumer.SendDeregisterNFInstance() @@ -184,8 +188,3 @@ func (a *PcfApp) WaitRoutineStopped() { a.wg.Wait() logger.MainLog.Infof("PCF App is terminated") } - -func (a *PcfApp) Stop() { - a.cancel() - a.WaitRoutineStopped() -} From 6a4eded09546b32579f57f2b6d863a41a5265404 Mon Sep 17 00:00:00 2001 From: chh Date: Tue, 25 Jun 2024 11:34:10 +0000 Subject: [PATCH 16/20] style: get Context from p instead of pcf_context.GetSelf() --- internal/sbi/processor/ampolicy.go | 24 +++++------ internal/sbi/processor/bdtpolicy.go | 12 +++--- internal/sbi/processor/callback.go | 5 +-- internal/sbi/processor/policyauthorization.go | 32 +++++++------- internal/sbi/processor/smpolicy.go | 42 +++++++++---------- 5 files changed, 57 insertions(+), 58 deletions(-) diff --git a/internal/sbi/processor/ampolicy.go b/internal/sbi/processor/ampolicy.go index e9bf922..37277ae 100644 --- a/internal/sbi/processor/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -21,7 +21,7 @@ func (p *Processor) HandleDeletePoliciesPolAssoId( ) { logger.AmPolicyLog.Infof("Handle AM Policy Association Delete") - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(polAssoId) + ue := p.Context().PCFUeFindByPolicyId(polAssoId) if ue == nil || ue.AMPolicyData[polAssoId] == nil { problemDetails := util.GetProblemDetail("polAssoId not found in PCF", util.CONTEXT_NOT_FOUND) c.JSON(int(problemDetails.Status), problemDetails) @@ -39,7 +39,7 @@ func (p *Processor) HandleGetPoliciesPolAssoId( logger.AmPolicyLog.Infof("Handle AM Policy Association Get") // response, problemDetails := GetPoliciesPolAssoIdProcedure(polAssoId) - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(polAssoId) + ue := p.Context().PCFUeFindByPolicyId(polAssoId) if ue == nil || ue.AMPolicyData[polAssoId] == nil { problemDetails := util.GetProblemDetail("polAssoId not found in PCF", util.CONTEXT_NOT_FOUND) c.JSON(int(problemDetails.Status), problemDetails) @@ -74,7 +74,7 @@ func (p *Processor) HandleUpdatePostPoliciesPolAssoId( ) { logger.AmPolicyLog.Infof("Handle AM Policy Association Update") - response, problemDetails := UpdatePostPoliciesPolAssoIdProcedure(polAssoId, policyAssociationUpdateRequest) + response, problemDetails := p.UpdatePostPoliciesPolAssoIdProcedure(polAssoId, policyAssociationUpdateRequest) if response != nil { c.JSON(http.StatusOK, response) } else if problemDetails != nil { @@ -88,10 +88,10 @@ func (p *Processor) HandleUpdatePostPoliciesPolAssoId( c.JSON(int(problemDetails.Status), problemDetails) } -func UpdatePostPoliciesPolAssoIdProcedure(polAssoId string, +func (p *Processor) UpdatePostPoliciesPolAssoIdProcedure(polAssoId string, policyAssociationUpdateRequest models.PolicyAssociationUpdateRequest, ) (*models.PolicyUpdate, *models.ProblemDetails) { - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(polAssoId) + ue := p.Context().PCFUeFindByPolicyId(polAssoId) if ue == nil || ue.AMPolicyData[polAssoId] == nil { problemDetails := util.GetProblemDetail("polAssoId not found in PCF", util.CONTEXT_NOT_FOUND) return nil, &problemDetails @@ -189,7 +189,7 @@ func (p *Processor) PostPoliciesProcedure(polAssoId string, policyAssociationRequest models.PolicyAssociationRequest, ) (*models.PolicyAssociation, string, *models.ProblemDetails) { var response models.PolicyAssociation - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var ue *pcf_context.UeContext if val, ok := pcfSelf.UePool.Load(policyAssociationRequest.Supi); ok { ue = val.(*pcf_context.UeContext) @@ -218,7 +218,7 @@ func (p *Processor) PostPoliciesProcedure(polAssoId string, assolId := fmt.Sprintf("%s-%d", ue.Supi, ue.PolAssociationIDGenerator) amPolicy := ue.AMPolicyData[assolId] - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return nil, "", pd } @@ -305,7 +305,7 @@ func (p *Processor) PostPoliciesProcedure(polAssoId string, } // Send AM Policy Update to AMF if policy has changed -func SendAMPolicyUpdateNotification(ue *pcf_context.UeContext, PolId string, request models.PolicyUpdate) { +func (p *Processor) SendAMPolicyUpdateNotification(ue *pcf_context.UeContext, PolId string, request models.PolicyUpdate) { if ue == nil { logger.AmPolicyLog.Warnln("Policy Update Notification Error[Ue is nil]") return @@ -316,7 +316,7 @@ func SendAMPolicyUpdateNotification(ue *pcf_context.UeContext, PolId string, req return } - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfType_PCF) + ctx, _, err := p.Context().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfType_PCF) if err != nil { return } @@ -358,7 +358,7 @@ func SendAMPolicyUpdateNotification(ue *pcf_context.UeContext, PolId string, req } // Send AM Policy Update to AMF if policy has been terminated -func SendAMPolicyTerminationRequestNotification(ue *pcf_context.UeContext, +func (p *Processor) SendAMPolicyTerminationRequestNotification(ue *pcf_context.UeContext, PolId string, request models.TerminationNotification, ) { if ue == nil { @@ -374,7 +374,7 @@ func SendAMPolicyTerminationRequestNotification(ue *pcf_context.UeContext, client := util.GetNpcfAMPolicyCallbackClient() uri := amPolicyData.NotificationUri - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfType_PCF) + ctx, _, err := p.Context().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfType_PCF) if err != nil { return } @@ -419,5 +419,5 @@ func (p *Processor) getUdrUri(ue *pcf_context.UeContext) string { if ue.UdrUri != "" { return ue.UdrUri } - return p.consumer.SendNFInstancesUDR(pcf_context.GetSelf().NrfUri, ue.Supi) + return p.consumer.SendNFInstancesUDR(p.Context().NrfUri, ue.Supi) } diff --git a/internal/sbi/processor/bdtpolicy.go b/internal/sbi/processor/bdtpolicy.go index 05de96d..da7ebd3 100644 --- a/internal/sbi/processor/bdtpolicy.go +++ b/internal/sbi/processor/bdtpolicy.go @@ -27,7 +27,7 @@ func (p *Processor) HandleGetBDTPolicyContextRequest( // step 2: handle the message logger.BdtPolicyLog.Traceln("Handle BDT Policy GET") // check bdtPolicyID from pcfUeContext - if value, ok := pcf_context.GetSelf().BdtPolicyPool.Load(bdtPolicyID); ok { + if value, ok := p.Context().BdtPolicyPool.Load(bdtPolicyID); ok { bdtPolicy := value.(*models.BdtPolicy) c.JSON(http.StatusOK, bdtPolicy) return @@ -52,10 +52,10 @@ func (p *Processor) HandleUpdateBDTPolicyContextProcedure( // step 2: handle the message logger.BdtPolicyLog.Infoln("Handle BDTPolicyUpdate") // check bdtPolicyID from pcfUeContext - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var bdtPolicy *models.BdtPolicy - if value, ok := pcf_context.GetSelf().BdtPolicyPool.Load(bdtPolicyID); ok { + if value, ok := p.Context().BdtPolicyPool.Load(bdtPolicyID); ok { bdtPolicy = value.(*models.BdtPolicy) } else { // not found @@ -82,7 +82,7 @@ func (p *Processor) HandleUpdateBDTPolicyContextProcedure( BdtData: optional.NewInterface(bdtData), } client := util.GetNudrClient(p.getDefaultUdrUri(pcfSelf)) - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { c.JSON(int(pd.Status), pd) return @@ -133,7 +133,7 @@ func (p *Processor) HandleCreateBDTPolicyContextRequest( response := &models.BdtPolicy{} logger.BdtPolicyLog.Traceln("Handle BDT Policy Create") - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() udrUri := p.getDefaultUdrUri(pcfSelf) if udrUri == "" { // Can't find any UDR support this Ue @@ -149,7 +149,7 @@ func (p *Processor) HandleCreateBDTPolicyContextRequest( pcfSelf.SetDefaultUdrURI(udrUri) // Query BDT DATA array from UDR - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { c.JSON(int(pd.Status), pd) return diff --git a/internal/sbi/processor/callback.go b/internal/sbi/processor/callback.go index f55da14..eb3b7ec 100644 --- a/internal/sbi/processor/callback.go +++ b/internal/sbi/processor/callback.go @@ -8,7 +8,6 @@ import ( "github.com/gin-gonic/gin" "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/util" ) @@ -50,7 +49,7 @@ func (p *Processor) HandleInfluenceDataUpdateNotify( logger.CallbackLog.Infof("[PCF] Handle Influence Data Update Notify") smPolicyID := fmt.Sprintf("%s-%s", supi, pduSessionId) - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyID) + ue := p.Context().PCFUeFindByPolicyId(smPolicyID) if ue == nil || ue.SmPolicyData[smPolicyID] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.CallbackLog.Errorf(problemDetail.Detail) @@ -97,7 +96,7 @@ func (p *Processor) HandleInfluenceDataUpdateNotify( ResourceUri: util.GetResourceUri(models.ServiceName_NPCF_SMPOLICYCONTROL, smPolicyID), SmPolicyDecision: decision, } - go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, &smPolicyNotification) + go p.SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, &smPolicyNotification) c.JSON(http.StatusNoContent, nil) } diff --git a/internal/sbi/processor/policyauthorization.go b/internal/sbi/processor/policyauthorization.go index b2acd4b..10a1b90 100644 --- a/internal/sbi/processor/policyauthorization.go +++ b/internal/sbi/processor/policyauthorization.go @@ -155,7 +155,7 @@ func (p *Processor) postAppSessCtxProcedure(appSessCtx *models.AppSessionContext string, *models.ProblemDetails, ) { ascReqData := appSessCtx.AscReqData - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() // Initial BDT policy indication(the only one which is not related to session) if ascReqData.BdtRefId != "" { @@ -429,7 +429,7 @@ func (p *Processor) postAppSessCtxProcedure(appSessCtx *models.AppSessionContext ResourceUri: util.GetResourceUri(models.ServiceName_NPCF_SMPOLICYCONTROL, smPolicyID), SmPolicyDecision: smPolicy.PolicyDecision, } - go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) + go p.SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) } return appSessCtx, locationHeader, nil } @@ -442,7 +442,7 @@ func (p *Processor) HandleDeleteAppSessionContext( ) { logger.PolicyAuthLog.Infof("Handle Del AppSessions, AppSessionId[%s]", appSessionId) - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var appSession *pcf_context.AppSessionData if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) @@ -490,7 +490,7 @@ func (p *Processor) HandleDeleteAppSessionContext( ResourceUri: util.GetResourceUri(models.ServiceName_NPCF_SMPOLICYCONTROL, smPolicyID), SmPolicyDecision: &deletedSmPolicyDec, } - go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) + go p.SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) logger.PolicyAuthLog.Tracef("Send SM Policy[%s] Update Notification", smPolicyID) c.JSON(http.StatusNoContent, nil) } @@ -502,7 +502,7 @@ func (p *Processor) HandleGetAppSessionContext( ) { logger.PolicyAuthLog.Infof("Handle Get AppSessions, AppSessionId[%s]", appSessionId) - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var appSession *pcf_context.AppSessionData if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { @@ -527,7 +527,7 @@ func (p *Processor) HandleModAppSessionContext( // ascUpdateData := request.Body.(models.AppSessionContextUpdateData) logger.PolicyAuthLog.Infof("Handle Modify AppSessions, AppSessionId[%s]", appSessionId) - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var appSession *pcf_context.AppSessionData if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) @@ -799,7 +799,7 @@ func (p *Processor) HandleModAppSessionContext( ResourceUri: util.GetResourceUri(models.ServiceName_NPCF_SMPOLICYCONTROL, smPolicyID), SmPolicyDecision: smPolicy.PolicyDecision, } - go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) + go p.SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) logger.PolicyAuthLog.Tracef("Send SM Policy[%s] Update Notification", smPolicyID) } c.JSON(http.StatusOK, appSessCtx) @@ -815,7 +815,7 @@ func (p *Processor) HandleDeleteEventsSubscContext( // problemDetails := DeleteEventsSubscContextProcedure(appSessionId) - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var appSession *pcf_context.AppSessionData if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { appSession = val.(*pcf_context.AppSessionData) @@ -843,7 +843,7 @@ func (p *Processor) HandleDeleteEventsSubscContext( ResourceUri: util.GetResourceUri(models.ServiceName_NPCF_SMPOLICYCONTROL, smPolicyID), SmPolicyDecision: smPolicy.PolicyDecision, } - go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) + go p.SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) logger.PolicyAuthLog.Tracef("Send SM Policy[%s] Update Notification", smPolicyID) } c.JSON(http.StatusNoContent, nil) @@ -859,7 +859,7 @@ func (p *Processor) HandleUpdateEventsSubscContext( // appSessID := request.Params["appSessID"] logger.PolicyAuthLog.Tracef("Handle Put AppSessions Events Subsc, AppSessionId[%s]", appSessionId) - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var appSession *pcf_context.AppSessionData if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { @@ -977,7 +977,7 @@ func (p *Processor) HandleUpdateEventsSubscContext( ResourceUri: util.GetResourceUri(models.ServiceName_NPCF_SMPOLICYCONTROL, smPolicyID), SmPolicyDecision: smPolicy.PolicyDecision, } - go SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) + go p.SendSMPolicyUpdateNotification(smPolicy.PolicyContext.NotificationUri, ¬ification) logger.PolicyAuthLog.Tracef("Send SM Policy[%s] Update Notification", smPolicyID) } if created { @@ -995,7 +995,7 @@ func (p *Processor) HandleUpdateEventsSubscContext( } } -func SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, request models.EventsNotification) { +func (p *Processor) SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, request models.EventsNotification) { logger.PolicyAuthLog.Tracef("Send App Session Event Notification") if appSession == nil { logger.PolicyAuthLog.Warnln("Send App Session Event Notification Error[appSession is nil]") @@ -1004,7 +1004,7 @@ func SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, req uri := appSession.EventUri if uri != "" { - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_POLICYAUTHORIZATION, models.NfType_PCF) + ctx, _, err := p.Context().GetTokenCtx(models.ServiceName_NPCF_POLICYAUTHORIZATION, models.NfType_PCF) if err != nil { return } @@ -1040,7 +1040,7 @@ func SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, req } } -func SendAppSessionTermination(appSession *pcf_context.AppSessionData, request models.TerminationInfo) { +func (p *Processor) SendAppSessionTermination(appSession *pcf_context.AppSessionData, request models.TerminationInfo) { logger.PolicyAuthLog.Tracef("Send App Session Termination") if appSession == nil { logger.PolicyAuthLog.Warnln("Send App Session Termination Error[appSession is nil]") @@ -1049,7 +1049,7 @@ func SendAppSessionTermination(appSession *pcf_context.AppSessionData, request m uri := appSession.AppSessionContext.AscReqData.NotifUri if uri != "" { - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_POLICYAUTHORIZATION, models.NfType_PCF) + ctx, _, err := p.Context().GetTokenCtx(models.ServiceName_NPCF_POLICYAUTHORIZATION, models.NfType_PCF) if err != nil { return } @@ -1101,7 +1101,7 @@ func (p *Processor) handleBDTPolicyInd(pcfSelf *pcf_context.PCFContext, requestSuppFeat).String(), } - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, _, err := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return err } diff --git a/internal/sbi/processor/smpolicy.go b/internal/sbi/processor/smpolicy.go index 9c7d0fe..483ab21 100644 --- a/internal/sbi/processor/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -49,7 +49,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( return } - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() var ue *pcf_context.UeContext if val, exist := pcfSelf.UePool.Load(request.Supi); exist { ue = val.(*pcf_context.UeContext) @@ -79,7 +79,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( } var response *http.Response - ctx, pd, err1 := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, pd, err1 := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err1 != nil { c.JSON(int(pd.Status), pd) return @@ -218,7 +218,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( logger.SmPolicyLog.Errorf("chargingInterface %+v", chargingInterface) util.SetPccRuleRelatedData(&decision, pcc, nil, nil, nil, nil) } else if chargingInterface != nil { - rg, err1 := pcf_context.GetSelf().RatingGroupIdGenerator.Allocate() + rg, err1 := p.Context().RatingGroupIdGenerator.Allocate() if err1 != nil { logger.SmPolicyLog.Error("rating group allocate error") problemDetails := util.GetProblemDetail("rating group allocate error", util.ERROR_IDGENERATOR) @@ -314,7 +314,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( if err != nil { logger.SmPolicyLog.Errorf("Fail to get charging data to mongoDB err: %+v", err) } else { - rg, err1 := pcf_context.GetSelf().RatingGroupIdGenerator.Allocate() + rg, err1 := p.Context().RatingGroupIdGenerator.Allocate() if err1 != nil { logger.SmPolicyLog.Error("rating group allocate error") problemDetails := util.GetProblemDetail("rating group allocate error", util.ERROR_IDGENERATOR) @@ -380,7 +380,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( Supis: optional.NewInterface([]string{request.Supi}), } - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { c.JSON(int(pd.Status), pd) return @@ -424,7 +424,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( smPolicyData.SubscriptionID = subscriptionID // Create PCF binding data to BSF - policyAuthorizationService := pcf_context.GetSelf().NfService[models.ServiceName_NPCF_POLICYAUTHORIZATION] + policyAuthorizationService := p.Context().NfService[models.ServiceName_NPCF_POLICYAUTHORIZATION] pcfBinding := models.PcfBinding{ Supi: request.Supi, Gpsi: request.Gpsi, @@ -438,11 +438,11 @@ func (p *Processor) HandleCreateSmPolicyRequest( } // TODO: Record BSF URI instead of discovering from NRF every time - bsfUri := p.consumer.SendNFInstancesBSF(pcf_context.GetSelf().NrfUri) + bsfUri := p.consumer.SendNFInstancesBSF(p.Context().NrfUri) if bsfUri != "" { bsfClient := util.GetNbsfClient(bsfUri) - ctx, pd, err = pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NBSF_MANAGEMENT, models.NfType_BSF) + ctx, pd, err = p.Context().GetTokenCtx(models.ServiceName_NBSF_MANAGEMENT, models.NfType_BSF) if err != nil { c.JSON(int(pd.Status), pd) return @@ -499,7 +499,7 @@ func (p *Processor) HandleDeleteSmPolicyContextRequest( // handle the message logger.AmPolicyLog.Traceln("Handle SM Policy Delete") - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyId) + ue := p.Context().PCFUeFindByPolicyId(smPolicyId) if ue == nil || ue.SmPolicyData[smPolicyId] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.SmPolicyLog.Warnf(problemDetail.Detail) @@ -507,7 +507,7 @@ func (p *Processor) HandleDeleteSmPolicyContextRequest( return } - pcfSelf := pcf_context.GetSelf() + pcfSelf := p.Context() smPolicy := ue.SmPolicyData[smPolicyId] problemDetail, err := p.consumer.RemoveInfluenceDataSubscription(ue, smPolicy.SubscriptionID) @@ -528,7 +528,7 @@ func (p *Processor) HandleDeleteSmPolicyContextRequest( for appSessionID := range smPolicy.AppSessions { if val, exist := pcfSelf.AppSessionPool.Load(appSessionID); exist { appSession := val.(*pcf_context.AppSessionData) - SendAppSessionTermination(appSession, terminationInfo) + p.SendAppSessionTermination(appSession, terminationInfo) pcfSelf.AppSessionPool.Delete(appSessionID) logger.SmPolicyLog.Tracef("SMPolicy[%s] DELETE Related AppSession[%s]", smPolicyId, appSessionID) } @@ -558,7 +558,7 @@ func (p *Processor) HandleGetSmPolicyContextRequest( // handle the message logger.SmPolicyLog.Traceln("Handle GET SM Policy Request") - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyId) + ue := p.Context().PCFUeFindByPolicyId(smPolicyId) if ue == nil || ue.SmPolicyData[smPolicyId] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.SmPolicyLog.Warnf(problemDetail.Detail) @@ -587,7 +587,7 @@ func (p *Processor) HandleUpdateSmPolicyContextRequest( logger.SmPolicyLog.Traceln("Handle updateSmPolicyContext") - ue := pcf_context.GetSelf().PCFUeFindByPolicyId(smPolicyId) + ue := p.Context().PCFUeFindByPolicyId(smPolicyId) if ue == nil || ue.SmPolicyData[smPolicyId] == nil { problemDetail := util.GetProblemDetail("smPolicyID not found in PCF", util.CONTEXT_NOT_FOUND) logger.SmPolicyLog.Warnf(problemDetail.Detail) @@ -944,7 +944,7 @@ func (p *Processor) HandleUpdateSmPolicyContextRequest( afEventsNotification.EvNotifs = append(afEventsNotification.EvNotifs, afNotif) } if afEventsNotification.EvNotifs != nil { - sendSmPolicyRelatedAppSessionNotification( + p.sendSmPolicyRelatedAppSessionNotification( smPolicy, afEventsNotification, request.AccuUsageReports, successRules, failRules) } @@ -959,12 +959,12 @@ func (p *Processor) HandleUpdateSmPolicyContextRequest( c.JSON(http.StatusOK, smPolicyDecision) } -func sendSmPolicyRelatedAppSessionNotification(smPolicy *pcf_context.UeSmPolicyData, +func (p *Processor) sendSmPolicyRelatedAppSessionNotification(smPolicy *pcf_context.UeSmPolicyData, notification models.EventsNotification, usageReports []models.AccuUsageReport, successRules, failRules []models.RuleReport, ) { for appSessionId := range smPolicy.AppSessions { - if val, exist := pcf_context.GetSelf().AppSessionPool.Load(appSessionId); exist { + if val, exist := p.Context().AppSessionPool.Load(appSessionId); exist { appSession := val.(*pcf_context.AppSessionData) if len(appSession.Events) == 0 { continue @@ -1123,13 +1123,13 @@ func sendSmPolicyRelatedAppSessionNotification(smPolicy *pcf_context.UeSmPolicyD } } if sessionNotif.EvNotifs != nil { - SendAppSessionEventNotification(appSession, sessionNotif) + p.SendAppSessionEventNotification(appSession, sessionNotif) } } } } -func SendSMPolicyUpdateNotification( +func (p *Processor) SendSMPolicyUpdateNotification( uri string, request *models.SmPolicyNotification, ) { if uri == "" { @@ -1137,7 +1137,7 @@ func SendSMPolicyUpdateNotification( return } - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_SMPOLICYCONTROL, models.NfType_PCF) + ctx, _, err := p.Context().GetTokenCtx(models.ServiceName_NPCF_SMPOLICYCONTROL, models.NfType_PCF) if err != nil { return } @@ -1171,7 +1171,7 @@ func SendSMPolicyUpdateNotification( } } -func SendSMPolicyTerminationRequestNotification( +func (p *Processor) SendSMPolicyTerminationRequestNotification( uri string, request *models.TerminationNotification, ) { if uri == "" { @@ -1179,7 +1179,7 @@ func SendSMPolicyTerminationRequestNotification( return } - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_SMPOLICYCONTROL, models.NfType_PCF) + ctx, _, err := p.Context().GetTokenCtx(models.ServiceName_NPCF_SMPOLICYCONTROL, models.NfType_PCF) if err != nil { return } From 7c87e7cb2f57a97fc6723cb436265bae8c07e2cb Mon Sep 17 00:00:00 2001 From: chh Date: Tue, 25 Jun 2024 12:20:10 +0000 Subject: [PATCH 17/20] style: delete unuse code --- internal/sbi/processor/{callback.go => notifier.go} | 0 internal/sbi/processor/smpolicy.go | 5 ----- 2 files changed, 5 deletions(-) rename internal/sbi/processor/{callback.go => notifier.go} (100%) diff --git a/internal/sbi/processor/callback.go b/internal/sbi/processor/notifier.go similarity index 100% rename from internal/sbi/processor/callback.go rename to internal/sbi/processor/notifier.go diff --git a/internal/sbi/processor/smpolicy.go b/internal/sbi/processor/smpolicy.go index 483ab21..4fc8c31 100644 --- a/internal/sbi/processor/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -32,11 +32,6 @@ func (p *Processor) HandleCreateSmPolicyRequest( request models.SmPolicyContextData, ) { logger.SmPolicyLog.Infof("Handle CreateSmPolicy") - // step 2: retrieve request - // requestDataType := request.Body.(models.SmPolicyContextData) - - // step 3: handle the message - // header, response, problemDetails := p.createSMPolicyProcedure(requestDataType) var err error queryStrength := 2 // 2: case-insensitive, 3: case-sensitive From 5e3906e5219b6790f667433d9141c98c36a4f7c8 Mon Sep 17 00:00:00 2001 From: chh Date: Tue, 25 Jun 2024 12:32:54 +0000 Subject: [PATCH 18/20] fix: linter --- internal/sbi/processor/ampolicy.go | 4 +++- internal/sbi/processor/policyauthorization.go | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/sbi/processor/ampolicy.go b/internal/sbi/processor/ampolicy.go index 37277ae..96bf89c 100644 --- a/internal/sbi/processor/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -305,7 +305,9 @@ func (p *Processor) PostPoliciesProcedure(polAssoId string, } // Send AM Policy Update to AMF if policy has changed -func (p *Processor) SendAMPolicyUpdateNotification(ue *pcf_context.UeContext, PolId string, request models.PolicyUpdate) { +func (p *Processor) SendAMPolicyUpdateNotification(ue *pcf_context.UeContext, + PolId string, request models.PolicyUpdate, +) { if ue == nil { logger.AmPolicyLog.Warnln("Policy Update Notification Error[Ue is nil]") return diff --git a/internal/sbi/processor/policyauthorization.go b/internal/sbi/processor/policyauthorization.go index 10a1b90..d7a9cf7 100644 --- a/internal/sbi/processor/policyauthorization.go +++ b/internal/sbi/processor/policyauthorization.go @@ -995,7 +995,9 @@ func (p *Processor) HandleUpdateEventsSubscContext( } } -func (p *Processor) SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, request models.EventsNotification) { +func (p *Processor) SendAppSessionEventNotification(appSession *pcf_context.AppSessionData, + request models.EventsNotification, +) { logger.PolicyAuthLog.Tracef("Send App Session Event Notification") if appSession == nil { logger.PolicyAuthLog.Warnln("Send App Session Event Notification Error[appSession is nil]") From 2aac88ba058bf50bf4b7b600e890e14c85a8363b Mon Sep 17 00:00:00 2001 From: chh Date: Wed, 26 Jun 2024 12:34:34 +0000 Subject: [PATCH 19/20] style: delete unuse code and get context by function --- internal/context/context.go | 5 ----- internal/sbi/consumer/amf_service.go | 2 +- internal/sbi/consumer/nrf_service.go | 10 +++++----- internal/sbi/consumer/udr_service.go | 6 +++--- internal/sbi/processor/policyauthorization.go | 9 --------- internal/sbi/processor/processor.go | 6 ------ internal/sbi/processor/smpolicy.go | 8 -------- internal/sbi/server.go | 9 ++++----- pkg/service/init.go | 2 +- 9 files changed, 14 insertions(+), 43 deletions(-) diff --git a/internal/context/context.go b/internal/context/context.go index 4d830b2..6c8380d 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -458,11 +458,6 @@ func (c *PCFContext) AuthorizationCheck(token string, serviceName models.Service logger.UtilLog.Debugf("PCFContext::AuthorizationCheck: OAuth2 not required\n") return nil } - // TODO: free5gc webconsole uses npcf-oam but it can't get token since it's not an NF. - if serviceName == models.ServiceName_NPCF_OAM { - logger.UtilLog.Warnf("OAuth2 is enable but namf-oam didn't check token now.") - return nil - } logger.UtilLog.Debugf("PCFContext::AuthorizationCheck: token[%s] serviceName[%s]\n", token, serviceName) return oauth.VerifyOAuth(token, string(serviceName), c.NrfCertPem) diff --git a/internal/sbi/consumer/amf_service.go b/internal/sbi/consumer/amf_service.go index 7f27576..daea3d1 100644 --- a/internal/sbi/consumer/amf_service.go +++ b/internal/sbi/consumer/amf_service.go @@ -56,7 +56,7 @@ func (s *namfService) AmfStatusChangeSubscribe(amfUri string, guamiList []models AmfStatusUri: fmt.Sprintf("%s"+factory.PcfCallbackResUriPrefix+"/amfstatus", pcfContext.GetIPv4Uri()), GuamiList: guamiList, } - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) + ctx, pd, err := pcfContext.GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) if err != nil { return pd, err } diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index d786dee..ed6072f 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -81,7 +81,7 @@ func (s *nnrfService) SendSearchNFInstances( // Set client and set url client := s.getNFDiscClient(nrfUri) - ctx, _, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) + ctx, _, err := s.consumer.Context().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) if err != nil { return nil, err } @@ -239,8 +239,8 @@ func (s *nnrfService) SendRegisterNFInstance(ctx context.Context) ( logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2) } } - pcf_context.GetSelf().OAuth2Required = oauth2 - if oauth2 && pcf_context.GetSelf().NrfCertPem == "" { + pcfContext.OAuth2Required = oauth2 + if oauth2 && pcfContext.NrfCertPem == "" { logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") } @@ -255,13 +255,13 @@ func (s *nnrfService) SendRegisterNFInstance(ctx context.Context) ( func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) { logger.ConsumerLog.Infof("Send Deregister NFInstance") + pcfContext := s.consumer.pcf.Context() - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + ctx, pd, err := pcfContext.GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) if err != nil { return pd, err } - pcfContext := s.consumer.pcf.Context() // Set client and set url client := s.getNFManagementClient(pcfContext.NrfUri) diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go index b141cd4..e9643bb 100644 --- a/internal/sbi/consumer/udr_service.go +++ b/internal/sbi/consumer/udr_service.go @@ -51,7 +51,7 @@ func (s *nudrService) CreateInfluenceDataSubscription(ue *pcf_context.UeContext, logger.ConsumerLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) return "", &problemDetail, nil } - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, pd, err := s.consumer.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return "", pd, err } @@ -89,7 +89,7 @@ func (s *nudrService) buildTrafficInfluSub(request models.SmPolicyContextData) m Snssais: []models.Snssai{*request.SliceInfo}, InternalGroupIds: request.InterGrpIds, Supis: []string{request.Supi}, - NotificationUri: pcf_context.GetSelf().GetIPv4Uri() + + NotificationUri: s.consumer.Context().GetIPv4Uri() + pcf_context.InfluenceDataUpdateNotifyUri + "/" + request.Supi + "/" + strconv.Itoa(int(request.PduSessionId)), // TODO: support expiry time and resend subscription when expired @@ -105,7 +105,7 @@ func (s *nudrService) RemoveInfluenceDataSubscription(ue *pcf_context.UeContext, logger.ConsumerLog.Warnf("Can't find corresponding UDR with UE[%s]", ue.Supi) return &problemDetail, nil } - ctx, pd, err := pcf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + ctx, pd, err := s.consumer.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return pd, err } diff --git a/internal/sbi/processor/policyauthorization.go b/internal/sbi/processor/policyauthorization.go index d7a9cf7..ddcce10 100644 --- a/internal/sbi/processor/policyauthorization.go +++ b/internal/sbi/processor/policyauthorization.go @@ -523,8 +523,6 @@ func (p *Processor) HandleModAppSessionContext( appSessionId string, appSessionContextUpdateData models.AppSessionContextUpdateData, ) { - // appSessID := request.Params["appSessionId"] - // ascUpdateData := request.Body.(models.AppSessionContextUpdateData) logger.PolicyAuthLog.Infof("Handle Modify AppSessions, AppSessionId[%s]", appSessionId) pcfSelf := p.Context() @@ -810,11 +808,8 @@ func (p *Processor) HandleDeleteEventsSubscContext( c *gin.Context, appSessionId string, ) { - // appSessID := request.Params["appSessID"] logger.PolicyAuthLog.Tracef("Handle Del AppSessions Events Subsc, AppSessionId[%s]", appSessionId) - // problemDetails := DeleteEventsSubscContextProcedure(appSessionId) - pcfSelf := p.Context() var appSession *pcf_context.AppSessionData if val, ok := pcfSelf.AppSessionPool.Load(appSessionId); ok { @@ -831,8 +826,6 @@ func (p *Processor) HandleDeleteEventsSubscContext( appSession.AppSessionContext.EvsNotif = nil appSession.AppSessionContext.AscReqData.EvSubsc = nil - // changed := appSession.SmPolicyData.ArrangeExistEventSubscription() - logger.PolicyAuthLog.Tracef("App Session Id[%s] Del Events Subsc success", appSessionId) smPolicy := appSession.SmPolicyData @@ -855,8 +848,6 @@ func (p *Processor) HandleUpdateEventsSubscContext( appSessionId string, eventsSubscReqData models.EventsSubscReqData, ) { - // EventsSubscReqData := request.Body.(models.EventsSubscReqData) - // appSessID := request.Params["appSessID"] logger.PolicyAuthLog.Tracef("Handle Put AppSessions Events Subsc, AppSessionId[%s]", appSessionId) pcfSelf := p.Context() diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go index 358a88d..4b68bbf 100644 --- a/internal/sbi/processor/processor.go +++ b/internal/sbi/processor/processor.go @@ -11,12 +11,6 @@ type Processor struct { consumer *consumer.Consumer } -type HandlerResponse struct { - Status int - Headers map[string][]string - Body interface{} -} - func NewProcessor(pcf app.App, consumer *consumer.Consumer) (*Processor, error) { p := &Processor{ App: pcf, diff --git a/internal/sbi/processor/smpolicy.go b/internal/sbi/processor/smpolicy.go index 4fc8c31..9c93e95 100644 --- a/internal/sbi/processor/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -26,7 +26,6 @@ const ( chargingDataColl = "policyData.ues.chargingData" ) -// SmPoliciesPost - func (p *Processor) HandleCreateSmPolicyRequest( c *gin.Context, request models.SmPolicyContextData, @@ -101,7 +100,6 @@ func (p *Processor) HandleCreateSmPolicyRequest( if amPolicy == nil { problemDetail := util.GetProblemDetail("Can't find corresponding AM Policy", util.POLICY_CONTEXT_DENIED) logger.SmPolicyLog.Warnf("Can't find corresponding AM Policy") - // message.SendHttpResponseMessage(httpChannel, nil, int(rsp.Status), rsp) c.JSON(int(problemDetail.Status), problemDetail) return } @@ -544,7 +542,6 @@ func (p *Processor) HandleDeleteSmPolicyContextRequest( c.JSON(http.StatusNoContent, nil) } -// SmPoliciessmPolicyIDGet - func (p *Processor) HandleGetSmPolicyContextRequest( c *gin.Context, smPolicyId string, @@ -569,17 +566,13 @@ func (p *Processor) HandleGetSmPolicyContextRequest( c.JSON(http.StatusOK, response) } -// SmPoliciessmPolicyIDUpdatePost - func (p *Processor) HandleUpdateSmPolicyContextRequest( c *gin.Context, smPolicyId string, request models.SmPolicyUpdateContextData, ) { - // step 1: log logger.SmPolicyLog.Infof("Handle UpdateSmPolicyContext") - // // step 3: handle the message - logger.SmPolicyLog.Traceln("Handle updateSmPolicyContext") ue := p.Context().PCFUeFindByPolicyId(smPolicyId) @@ -950,7 +943,6 @@ func (p *Processor) HandleUpdateSmPolicyContextRequest( return } logger.SmPolicyLog.Tracef("SMPolicy smPolicyID[%s] Update", smPolicyId) - // message.SendHttpResponseMessage(httpChannel, nil, http.StatusOK, *smPolicyDecision) c.JSON(http.StatusOK, smPolicyDecision) } diff --git a/internal/sbi/server.go b/internal/sbi/server.go index babdb99..997d810 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -13,7 +13,6 @@ import ( "github.com/sirupsen/logrus" "github.com/free5gc/openapi/models" - pcf_context "github.com/free5gc/pcf/internal/context" "github.com/free5gc/pcf/internal/logger" "github.com/free5gc/pcf/internal/sbi/consumer" "github.com/free5gc/pcf/internal/sbi/processor" @@ -74,7 +73,7 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { amPolicyGroup := s.router.Group(factory.PcfAMpolicyCtlResUriPrefix) amRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_AM_POLICY_CONTROL) amPolicyGroup.Use(func(c *gin.Context) { - amRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + amRouterAuthorizationCheck.Check(c, s.Context()) }) applyRoutes(amPolicyGroup, amPolicyRoutes) @@ -82,7 +81,7 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { bdtPolicyGroup := s.router.Group(factory.PcfBdtPolicyCtlResUriPrefix) bdtRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_BDTPOLICYCONTROL) bdtPolicyGroup.Use(func(c *gin.Context) { - bdtRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + bdtRouterAuthorizationCheck.Check(c, s.Context()) }) applyRoutes(bdtPolicyGroup, bdtPolicyRoutes) @@ -94,7 +93,7 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { oamGroup := s.router.Group(factory.PcfOamResUriPrefix) oamRouterAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NPCF_OAM) oamGroup.Use(func(c *gin.Context) { - oamRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + oamRouterAuthorizationCheck.Check(c, s.Context()) }) applyRoutes(oamGroup, oamRoutes) @@ -103,7 +102,7 @@ func NewServer(pcf pcf, tlsKeyLogPath string) (*Server, error) { policyAuthorizationRouterAuthorizationCheck := util. NewRouterAuthorizationCheck(models.ServiceName_NPCF_POLICYAUTHORIZATION) policyAuthorizationGroup.Use(func(c *gin.Context) { - policyAuthorizationRouterAuthorizationCheck.Check(c, pcf_context.GetSelf()) + policyAuthorizationRouterAuthorizationCheck.Check(c, s.Context()) }) applyRoutes(policyAuthorizationGroup, policyAuthorizationRoutes) diff --git a/pkg/service/init.go b/pkg/service/init.go index 9fb85c2..fefcb25 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -173,7 +173,7 @@ func (a *PcfApp) terminateProcedure() { logger.MainLog.Infof("Terminating PCF...") a.CallServerStop() // deregister with NRF - problemDetails, err := a.consumer.SendDeregisterNFInstance() + problemDetails, err := a.Consumer().SendDeregisterNFInstance() if problemDetails != nil { logger.InitLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails) } else if err != nil { From 2a008f6fdcb5dac4c4fdbf7f949157de2c3ae665 Mon Sep 17 00:00:00 2001 From: chh Date: Thu, 27 Jun 2024 06:50:27 +0000 Subject: [PATCH 20/20] style: use Consumer() in processor --- internal/sbi/processor/ampolicy.go | 7 ++++--- internal/sbi/processor/bdtpolicy.go | 2 +- internal/sbi/processor/processor.go | 16 +++++++--------- internal/sbi/processor/smpolicy.go | 6 +++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/internal/sbi/processor/ampolicy.go b/internal/sbi/processor/ampolicy.go index 96bf89c..f162a77 100644 --- a/internal/sbi/processor/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -285,10 +285,11 @@ func (p *Processor) PostPoliciesProcedure(polAssoId string, if needSubscribe { logger.AmPolicyLog.Debugf("Subscribe AMF status change[GUAMI: %+v]", *policyAssociationRequest.Guami) - amfUri := p.consumer.SendNFInstancesAMF(pcfSelf.NrfUri, + amfUri := p.Consumer().SendNFInstancesAMF(pcfSelf.NrfUri, *policyAssociationRequest.Guami, models.ServiceName_NAMF_COMM) if amfUri != "" { - problemDetails, err := p.consumer.AmfStatusChangeSubscribe(amfUri, []models.Guami{*policyAssociationRequest.Guami}) + problemDetails, err := p.Consumer().AmfStatusChangeSubscribe(amfUri, + []models.Guami{*policyAssociationRequest.Guami}) if err != nil { logger.AmPolicyLog.Errorf("Subscribe AMF status change error[%+v]", err) } else if problemDetails != nil { @@ -421,5 +422,5 @@ func (p *Processor) getUdrUri(ue *pcf_context.UeContext) string { if ue.UdrUri != "" { return ue.UdrUri } - return p.consumer.SendNFInstancesUDR(p.Context().NrfUri, ue.Supi) + return p.Consumer().SendNFInstancesUDR(p.Context().NrfUri, ue.Supi) } diff --git a/internal/sbi/processor/bdtpolicy.go b/internal/sbi/processor/bdtpolicy.go index da7ebd3..b762c20 100644 --- a/internal/sbi/processor/bdtpolicy.go +++ b/internal/sbi/processor/bdtpolicy.go @@ -254,7 +254,7 @@ func (p *Processor) getDefaultUdrUri(context *pcf_context.PCFContext) string { param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NUDR_DR}), } - resp, err := p.consumer.SendSearchNFInstances(context.NrfUri, models.NfType_UDR, models.NfType_PCF, param) + resp, err := p.Consumer().SendSearchNFInstances(context.NrfUri, models.NfType_UDR, models.NfType_PCF, param) if err != nil { return "" } diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go index 4b68bbf..59b64f8 100644 --- a/internal/sbi/processor/processor.go +++ b/internal/sbi/processor/processor.go @@ -5,21 +5,19 @@ import ( "github.com/free5gc/pcf/pkg/app" ) -type Processor struct { +type PCF interface { app.App + Consumer() *consumer.Consumer +} - consumer *consumer.Consumer +type Processor struct { + PCF } -func NewProcessor(pcf app.App, consumer *consumer.Consumer) (*Processor, error) { +func NewProcessor(pcf PCF, consumer *consumer.Consumer) (*Processor, error) { p := &Processor{ - App: pcf, - consumer: consumer, + PCF: pcf, } return p, nil } - -func (p *Processor) Consumer() *consumer.Consumer { - return p.consumer -} diff --git a/internal/sbi/processor/smpolicy.go b/internal/sbi/processor/smpolicy.go index 9c93e95..f30cfca 100644 --- a/internal/sbi/processor/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -408,7 +408,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( } // Subscribe to Traffic Influence Data in UDR - subscriptionID, problemDetail, err := p.consumer.CreateInfluenceDataSubscription(ue, request) + subscriptionID, problemDetail, err := p.Consumer().CreateInfluenceDataSubscription(ue, request) if problemDetail != nil { logger.SmPolicyLog.Errorf("Subscribe UDR Influence Data Failed Problem[%+v]", problemDetail) } else if err != nil { @@ -431,7 +431,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( } // TODO: Record BSF URI instead of discovering from NRF every time - bsfUri := p.consumer.SendNFInstancesBSF(p.Context().NrfUri) + bsfUri := p.Consumer().SendNFInstancesBSF(p.Context().NrfUri) if bsfUri != "" { bsfClient := util.GetNbsfClient(bsfUri) @@ -503,7 +503,7 @@ func (p *Processor) HandleDeleteSmPolicyContextRequest( pcfSelf := p.Context() smPolicy := ue.SmPolicyData[smPolicyId] - problemDetail, err := p.consumer.RemoveInfluenceDataSubscription(ue, smPolicy.SubscriptionID) + problemDetail, err := p.Consumer().RemoveInfluenceDataSubscription(ue, smPolicy.SubscriptionID) if problemDetail != nil { logger.SmPolicyLog.Errorf("Remove UDR Influence Data Subscription Failed Problem[%+v]", problemDetail) } else if err != nil {