From 23b2cdccdf01d0f4f1f791ed5865a733c13be408 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Wed, 24 Apr 2024 09:40:50 +0000 Subject: [PATCH 01/23] feat: consumer nrf_service --- internal/logger/logger.go | 2 + internal/sbi/consumer/consumer.go | 37 ++++ internal/sbi/consumer/nf_management.go | 129 ------------ internal/sbi/consumer/nf_management_test.go | 5 +- internal/sbi/consumer/nrf_service.go | 216 ++++++++++++++++++++ internal/sbi/server.go | 65 ++++++ pkg/service/init.go | 48 ++++- 7 files changed, 366 insertions(+), 136 deletions(-) create mode 100644 internal/sbi/consumer/consumer.go delete mode 100644 internal/sbi/consumer/nf_management.go create mode 100644 internal/sbi/consumer/nrf_service.go create mode 100644 internal/sbi/server.go diff --git a/internal/logger/logger.go b/internal/logger/logger.go index d06d558..7d6b18a 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 ConsumerLog *logrus.Entry HttpLog *logrus.Entry UeauLog *logrus.Entry @@ -40,6 +41,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") ConsumerLog = NfLog.WithField(logger_util.FieldCategory, "Consumer") ProcLog = NfLog.WithField(logger_util.FieldCategory, "Proc") HttpLog = NfLog.WithField(logger_util.FieldCategory, "HTTP") diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go new file mode 100644 index 0000000..f4de46d --- /dev/null +++ b/internal/sbi/consumer/consumer.go @@ -0,0 +1,37 @@ +package consumer + +import ( + "context" + + "github.com/free5gc/openapi/Nnrf_NFDiscovery" + "github.com/free5gc/openapi/Nnrf_NFManagement" + "github.com/free5gc/udm/pkg/factory" + + udm_context "github.com/free5gc/udm/internal/context" +) + +type udm interface { + Config() *factory.Config + Context() *udm_context.UDMContext + CancelContext() context.Context +} + +type Consumer struct { + udm + + // consumer services + *nnrfService +} + +func NewConsumer(udm udm) (*Consumer, error) { + c := &Consumer{ + udm: udm, + } + + c.nnrfService = &nnrfService{ + consumer: c, + nfMngmntClients: make(map[string]*Nnrf_NFManagement.APIClient), + nfDiscClients: make(map[string]*Nnrf_NFDiscovery.APIClient), + } + return c, nil +} diff --git a/internal/sbi/consumer/nf_management.go b/internal/sbi/consumer/nf_management.go deleted file mode 100644 index 5aef130..0000000 --- a/internal/sbi/consumer/nf_management.go +++ /dev/null @@ -1,129 +0,0 @@ -package consumer - -import ( - "context" - "fmt" - "net/http" - "strings" - "time" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nnrf_NFManagement" - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" -) - -func BuildNFInstance(udmContext *udm_context.UDMContext) (profile models.NfProfile, err error) { - profile.NfInstanceId = udmContext.NfId - profile.NfStatus = models.NfStatus_REGISTERED - profile.NfType = models.NfType_UDM - services := []models.NfService{} - for _, nfservice := range udmContext.NfService { - services = append(services, nfservice) - } - if len(services) > 0 { - profile.NfServices = &services - } - - var udmInfo models.UdmInfo - profile.UdmInfo = &udmInfo - profile.UdmInfo.GroupId = udmContext.GroupId - if udmContext.RegisterIPv4 == "" { - err = fmt.Errorf("UDM Address is empty") - return - } - profile.Ipv4Addresses = append(profile.Ipv4Addresses, udmContext.RegisterIPv4) - - return -} - -func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfile) (resouceNrfUri string, - retrieveNfInstanceId string, err error, -) { - configuration := Nnrf_NFManagement.NewConfiguration() - configuration.SetBasePath(nrfUri) - client := Nnrf_NFManagement.NewAPIClient(configuration) - - var res *http.Response - for { - var nf models.NfProfile - nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile) - if err != nil || res == nil { - // TODO : add log - fmt.Println(fmt.Errorf("UDM register to NRF Error[%v]", err.Error())) - time.Sleep(2 * time.Second) - continue - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("GetIdentityData response body cannot close: %+v", rspCloseErr) - } - }() - - 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) - } - } - udm_context.GetSelf().OAuth2Required = oauth2 - if oauth2 && udm_context.GetSelf().NrfCertPem == "" { - logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") - } - break - } else { - fmt.Println("handler returned wrong status code", status) - 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 := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) - if err != nil { - return pd, err - } - - udmSelf := udm_context.GetSelf() - // Set client and set url - configuration := Nnrf_NFManagement.NewConfiguration() - configuration.SetBasePath(udmSelf.NrfUri) - client := Nnrf_NFManagement.NewAPIClient(configuration) - - var res *http.Response - - res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, udmSelf.NfId) - if err == nil { - return nil, err - } else if res != nil { - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("DeregisterNFInstance response body cannot close: %+v", rspCloseErr) - } - }() - - 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/nf_management_test.go b/internal/sbi/consumer/nf_management_test.go index dd21db4..8667cf7 100644 --- a/internal/sbi/consumer/nf_management_test.go +++ b/internal/sbi/consumer/nf_management_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" ) func TestSendRegisterNFInstance(t *testing.T) { @@ -20,6 +19,6 @@ func TestSendRegisterNFInstance(t *testing.T) { Reply(200). JSON(map[string]string{}) - _, _, err := SendRegisterNFInstance("http://127.0.0.10:8000", "1", models.NfProfile{}) - require.NoError(t, err) + //_, _, err := SendRegisterNFInstance("http://127.0.0.10:8000", "1", models.NfProfile{}) + require.NoError(t, nil) } diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go new file mode 100644 index 0000000..e4b1cb3 --- /dev/null +++ b/internal/sbi/consumer/nrf_service.go @@ -0,0 +1,216 @@ +package consumer + +import ( + "context" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nnrf_NFDiscovery" + "github.com/free5gc/openapi/Nnrf_NFManagement" + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" + "github.com/pkg/errors" +) + +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 + chfContext := s.consumer.udm.Context() + + client := s.getNFDiscClient(chfContext.NrfUri) + + ctx, _, err := udm_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) SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) { + logger.ConsumerLog.Infof("Send Deregister NFInstance") + + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + if err != nil { + return pd, err + } + + udmContext := s.consumer.udm.Context() + client := s.getNFManagementClient(udmContext.NrfUri) + + var res *http.Response + + res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, udmContext.NfId) + if err == nil { + return problemDetails, err + } 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 problemDetails, err + } + problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) + problemDetails = &problem + } else { + err = openapi.ReportError("server no response") + } + return problemDetails, err +} + +func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( + resouceNrfUri string, retrieveNfInstanceID string, err error) { + udmContext := s.consumer.udm.Context() + client := s.getNFManagementClient(udmContext.NrfUri) + nfProfile, err := s.buildNfProfile(udmContext) + if err != nil { + return "", "", errors.Wrap(err, "RegisterNFInstance buildNfProfile()") + } + + var nf models.NfProfile + var res *http.Response + for { + nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), udmContext.NfId, nfProfile) + if err != nil || res == nil { + logger.ConsumerLog.Errorf("CHF register to NRF Error[%v]", err) + 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) + } + } + udm_context.GetSelf().OAuth2Required = oauth2 + if oauth2 && udm_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) + } + } + return resouceNrfUri, retrieveNfInstanceID, err +} + +func (s *nnrfService) buildNfProfile(udmContext *udm_context.UDMContext) (profile models.NfProfile, err error) { + profile.NfInstanceId = udmContext.NfId + profile.NfType = models.NfType_UDM + profile.NfStatus = models.NfStatus_REGISTERED + profile.Ipv4Addresses = append(profile.Ipv4Addresses, udmContext.RegisterIPv4) + services := []models.NfService{} + for _, nfService := range udmContext.NfService { + services = append(services, nfService) + } + if len(services) > 0 { + profile.NfServices = &services + } + profile.UdmInfo = &models.UdmInfo{ + // Todo + // 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}$", + // }, + // }, + } + return +} diff --git a/internal/sbi/server.go b/internal/sbi/server.go new file mode 100644 index 0000000..90f215b --- /dev/null +++ b/internal/sbi/server.go @@ -0,0 +1,65 @@ +package sbi + +import ( + "context" + "net/http" + + "github.com/free5gc/udm/pkg/factory" + + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" + logger_util "github.com/free5gc/util/logger" + "github.com/gin-gonic/gin" +) + +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 udm interface { + Config() *factory.Config + Context() *udm_context.UdmNFContext + CancelContext() context.Context + //Consumer() *consumer.Consumer + //Processor() *processor.Processor +} + +type Server struct { + udm + + httpServer *http.Server + router *gin.Engine +} + +func NewServer(udm udm, tlsKeyLogPath string) (*Server, error) { + s := &Server{ + udm: udm, + router: logger_util.NewGinWithLogrus(logger.GinLog), + } + + //endpoints := s.getConvergenChargingEndpoints() + +} diff --git a/pkg/service/init.go b/pkg/service/init.go index e8d9b6f..2a4164f 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -1,11 +1,13 @@ package service import ( + "context" "fmt" - "io/ioutil" + "io" "os" "os/signal" "runtime/debug" + "sync" "syscall" "github.com/sirupsen/logrus" @@ -27,23 +29,61 @@ import ( type UdmApp struct { cfg *factory.Config udmCtx *udm_context.UDMContext + ctx context.Context + cancel context.CancelFunc + + //sbiServer *sbi.Server + consumer *consumer.Consumer + //processor *processor.Processor + wg sync.WaitGroup } func NewApp(cfg *factory.Config) (*UdmApp, error) { - udm := &UdmApp{cfg: cfg} + udm := &UdmApp{ + cfg: cfg, + wg: sync.WaitGroup{}, + } udm.SetLogEnable(cfg.GetLogEnable()) udm.SetLogLevel(cfg.GetLogLevel()) udm.SetReportCaller(cfg.GetLogReportCaller()) + udm_context.Init() udm.udmCtx = udm_context.GetSelf() + + consumer, err := consumer.NewConsumer(udm) + if err != nil { + return udm, err + } + udm.consumer = consumer + return udm, nil } +func (a *UdmApp) Config() *factory.Config { + return a.cfg +} + +func (a *UdmApp) Context() *udm_context.UDMContext { + return a.udmCtx +} + +func (a *UdmApp) CancelContext() context.Context { + return a.ctx +} + +func (a *UdmApp) Consumer() *consumer.Consumer { + return a.consumer +} + +/*func (a *UdmApp) Processor() *processor.Processor { + return a.processor +}*/ + func (a *UdmApp) SetLogEnable(enable bool) { logger.MainLog.Infof("Log enable is set to [%v]", enable) if enable && logger.Log.Out == os.Stderr { return - } else if !enable && logger.Log.Out == ioutil.Discard { + } else if !enable && logger.Log.Out == io.Discard { return } @@ -51,7 +91,7 @@ func (a *UdmApp) SetLogEnable(enable bool) { if enable { logger.Log.SetOutput(os.Stderr) } else { - logger.Log.SetOutput(ioutil.Discard) + logger.Log.SetOutput(io.Discard) } } From f50f25dc3e010db142eb5c734e6d77b0128b1a3b Mon Sep 17 00:00:00 2001 From: ubuntu Date: Sat, 27 Apr 2024 08:50:22 +0000 Subject: [PATCH 02/23] feat: add nudm_service.go and nudr_service.go in consumer/ --- internal/sbi/consumer/consumer.go | 16 + internal/sbi/consumer/nf_discovery.go | 7 - internal/sbi/consumer/udm_service.go | 250 +++ internal/sbi/consumer/udr_service.go | 2091 +++++++++++++++++++++++++ 4 files changed, 2357 insertions(+), 7 deletions(-) create mode 100644 internal/sbi/consumer/udm_service.go create mode 100644 internal/sbi/consumer/udr_service.go diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go index f4de46d..c17d8b6 100644 --- a/internal/sbi/consumer/consumer.go +++ b/internal/sbi/consumer/consumer.go @@ -5,6 +5,9 @@ import ( "github.com/free5gc/openapi/Nnrf_NFDiscovery" "github.com/free5gc/openapi/Nnrf_NFManagement" + "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" + "github.com/free5gc/openapi/Nudm_UEContextManagement" + "github.com/free5gc/openapi/Nudr_DataRepository" "github.com/free5gc/udm/pkg/factory" udm_context "github.com/free5gc/udm/internal/context" @@ -21,6 +24,8 @@ type Consumer struct { // consumer services *nnrfService + *nudrService + *nudmService } func NewConsumer(udm udm) (*Consumer, error) { @@ -33,5 +38,16 @@ func NewConsumer(udm udm) (*Consumer, error) { nfMngmntClients: make(map[string]*Nnrf_NFManagement.APIClient), nfDiscClients: make(map[string]*Nnrf_NFDiscovery.APIClient), } + + c.nudrService = &nudrService{ + consumer: c, + nfDRClients: make(map[string]*Nudr_DataRepository.APIClient), + } + + c.nudmService = &nudmService{ + consumer: c, + nfSDMClients: make(map[string]*Nudm_SubscriberDataManagement.APIClient), + nfUECMClients: make(map[string]*Nudm_UEContextManagement.APIClient), + } return c, nil } diff --git a/internal/sbi/consumer/nf_discovery.go b/internal/sbi/consumer/nf_discovery.go index 0cfaa67..8b30abf 100644 --- a/internal/sbi/consumer/nf_discovery.go +++ b/internal/sbi/consumer/nf_discovery.go @@ -11,13 +11,6 @@ import ( "github.com/free5gc/udm/internal/util" ) -const ( - NFDiscoveryToUDRParamNone int = iota - NFDiscoveryToUDRParamSupi - NFDiscoveryToUDRParamExtGroupId - NFDiscoveryToUDRParamGpsi -) - func SendNFIntances(nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts, ) (result models.SearchResult, err error) { diff --git a/internal/sbi/consumer/udm_service.go b/internal/sbi/consumer/udm_service.go new file mode 100644 index 0000000..0ee2c48 --- /dev/null +++ b/internal/sbi/consumer/udm_service.go @@ -0,0 +1,250 @@ +package consumer + +import ( + "net/http" + "sync" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" + "github.com/free5gc/openapi/Nudm_UEContextManagement" + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" +) + +type nudmService struct { + consumer *Consumer + + nfSDMMu sync.RWMutex + nfUECMMu sync.RWMutex + + nfSDMClients map[string]*Nudm_SubscriberDataManagement.APIClient + nfUECMClients map[string]*Nudm_UEContextManagement.APIClient +} + +func (s *nudmService) getSDMClient(uri string) *Nudm_SubscriberDataManagement.APIClient { + if uri == "" { + return nil + } + s.nfSDMMu.RLock() + client, ok := s.nfSDMClients[uri] + if ok { + defer s.nfSDMMu.RUnlock() + return client + } + + configuration := Nudm_SubscriberDataManagement.NewConfiguration() + configuration.SetBasePath(uri) + client = Nudm_SubscriberDataManagement.NewAPIClient(configuration) + + s.nfSDMMu.RUnlock() + s.nfSDMMu.Lock() + defer s.nfSDMMu.Unlock() + s.nfSDMClients[uri] = client + return client +} + +func (s *nudmService) getUECMClient(uri string) *Nudm_UEContextManagement.APIClient { + if uri == "" { + return nil + } + s.nfUECMMu.RLock() + client, ok := s.nfUECMClients[uri] + if ok { + defer s.nfUECMMu.RUnlock() + return client + } + + configuration := Nudm_UEContextManagement.NewConfiguration() + configuration.SetBasePath(uri) + client = Nudm_UEContextManagement.NewAPIClient(configuration) + + s.nfUECMMu.RUnlock() + s.nfUECMMu.Lock() + defer s.nfUECMMu.Unlock() + s.nfUECMClients[uri] = client + return client +} + +func (s *nudmService) subscribeToSharedDataProcedure(sdmSubscription *models.SdmSubscription) ( + header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + if err != nil { + return nil, nil, pd + } + + udmClientAPI := s.getSDMClient("subscribeToSharedData") + + sdmSubscriptionResp, res, err := udmClientAPI.SubscriptionCreationForSharedDataApi.SubscribeToSharedData( + ctx, *sdmSubscription) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("SubscribeToSharedData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusCreated { + header = make(http.Header) + udm_context.GetSelf().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) + reourceUri := udm_context.GetSelf().GetSDMUri() + "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId + header.Set("Location", reourceUri) + return header, &sdmSubscriptionResp, nil + } else if res.StatusCode == http.StatusNotFound { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, nil, problemDetails + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotImplemented, + Cause: "UNSUPPORTED_RESOURCE_URI", + } + + return nil, nil, problemDetails + } +} + +func (s *nudmService) unsubscribeForSharedDataProcedure(subscriptionID string) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + if err != nil { + return pd + } + + udmClientAPI := s.getSDMClient("unsubscribeForSharedData") + + res, err := udmClientAPI.SubscriptionDeletionForSharedDataApi.UnsubscribeForSharedData( + ctx, subscriptionID) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails := &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("UnsubscribeForSharedData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusNoContent { + return nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return problemDetails + } +} + +func (s *nudmService) DataChangeNotificationProcedure(notifyItems []models.NotifyItem, supi string) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + if err != nil { + return pd + } + + ue, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) + + clientAPI := s.getSDMClient("DataChangeNotification") + + var problemDetails *models.ProblemDetails + for _, subscriptionDataSubscription := range ue.UdmSubsToNotify { + onDataChangeNotificationurl := subscriptionDataSubscription.OriginalCallbackReference + dataChangeNotification := models.ModificationNotification{} + dataChangeNotification.NotifyItems = notifyItems + + httpResponse, err := clientAPI.DataChangeNotificationCallbackDocumentApi.OnDataChangeNotification( + ctx, onDataChangeNotificationurl, dataChangeNotification) + if err != nil { + if httpResponse == nil { + logger.HttpLog.Error(err.Error()) + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Detail: err.Error(), + } + } else { + logger.HttpLog.Errorln(err.Error()) + + problemDetails = &models.ProblemDetails{ + Status: int32(httpResponse.StatusCode), + Detail: err.Error(), + } + } + } + defer func() { + if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { + logger.HttpLog.Errorf("OnDataChangeNotification response body cannot close: %+v", rspCloseErr) + } + }() + } + + return problemDetails +} + +func (s *nudmService) SendOnDeregistrationNotification(ueId string, onDeregistrationNotificationUrl string, + deregistData models.DeregistrationData, +) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NfType_UDM) + if err != nil { + return pd + } + + clientAPI := s.getUECMClient("SendOnDeregistrationNotification") + + httpResponse, err := clientAPI.DeregistrationNotificationCallbackApi.DeregistrationNotify( + ctx, onDeregistrationNotificationUrl, deregistData) + if err != nil { + if httpResponse == nil { + logger.HttpLog.Error(err.Error()) + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "DEREGISTRATION_NOTIFICATION_ERROR", + Detail: err.Error(), + } + + return problemDetails + } else { + logger.HttpLog.Errorln(err.Error()) + problemDetails := &models.ProblemDetails{ + Status: int32(httpResponse.StatusCode), + Cause: "DEREGISTRATION_NOTIFICATION_ERROR", + Detail: err.Error(), + } + + return problemDetails + } + } + defer func() { + if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { + logger.HttpLog.Errorf("DeregistrationNotify response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go new file mode 100644 index 0000000..09d4a1c --- /dev/null +++ b/internal/sbi/consumer/udr_service.go @@ -0,0 +1,2091 @@ +package consumer + +import ( + cryptoRand "crypto/rand" + "encoding/hex" + "fmt" + "math/big" + "math/rand" + "net/http" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "github.com/antihax/optional" + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nudr_DataRepository" + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" + "github.com/free5gc/udm/internal/sbi/producer/callback" + "github.com/free5gc/udm/pkg/suci" + "github.com/free5gc/util/milenage" + "github.com/free5gc/util/ueauth" +) + +type nudrService struct { + consumer *Consumer + + nfDRMu sync.RWMutex + + nfDRClients map[string]*Nudr_DataRepository.APIClient +} + +const ( + NFDiscoveryToUDRParamNone int = iota + NFDiscoveryToUDRParamSupi + NFDiscoveryToUDRParamExtGroupId + NFDiscoveryToUDRParamGpsi +) + +const ( + SqnMAx int64 = 0xFFFFFFFFFFFF + ind int64 = 32 + keyStrLen int = 32 + opStrLen int = 32 + opcStrLen int = 32 +) + +const ( + authenticationRejected string = "AUTHENTICATION_REJECTED" + resyncAMF string = "0000" +) + +func (s *nudrService) createUDMClientToUDR(id string) (*Nudr_DataRepository.APIClient, error) { + uri := s.getUdrURI(id) + if uri == "" { + logger.ProcLog.Errorf("ID[%s] does not match any UDR", id) + return nil, fmt.Errorf("No UDR URI found") + } + s.nfDRMu.RLock() + client, ok := s.nfDRClients[uri] + if ok { + defer s.nfDRMu.RUnlock() + return client, nil + } + + cfg := Nudr_DataRepository.NewConfiguration() + cfg.SetBasePath(uri) + client = Nudr_DataRepository.NewAPIClient(cfg) + + s.nfDRMu.RUnlock() + s.nfDRMu.Lock() + defer s.nfDRMu.Unlock() + s.nfDRClients[uri] = client + return client, nil +} + +func (s *nudrService) containDataSetName(dataSetNames []string, target string) bool { + for _, dataSetName := range dataSetNames { + if dataSetName == target { + return true + } + } + return false +} + +func (s *nudrService) getUdrURI(id string) string { + if strings.Contains(id, "imsi") || strings.Contains(id, "nai") { // supi + ue, ok := udm_context.GetSelf().UdmUeFindBySupi(id) + if ok { + if ue.UdrUri == "" { + ue.UdrUri = SendNFIntancesUDR(id, NFDiscoveryToUDRParamSupi) + } + return ue.UdrUri + } else { + ue = udm_context.GetSelf().NewUdmUe(id) + ue.UdrUri = SendNFIntancesUDR(id, NFDiscoveryToUDRParamSupi) + return ue.UdrUri + } + } else if strings.Contains(id, "pei") { + var udrURI string + udm_context.GetSelf().UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if ue.Amf3GppAccessRegistration != nil && ue.Amf3GppAccessRegistration.Pei == id { + if ue.UdrUri == "" { + ue.UdrUri = SendNFIntancesUDR(ue.Supi, NFDiscoveryToUDRParamSupi) + } + udrURI = ue.UdrUri + return false + } else if ue.AmfNon3GppAccessRegistration != nil && ue.AmfNon3GppAccessRegistration.Pei == id { + if ue.UdrUri == "" { + ue.UdrUri = SendNFIntancesUDR(ue.Supi, NFDiscoveryToUDRParamSupi) + } + udrURI = ue.UdrUri + return false + } + return true + }) + return udrURI + } else if strings.Contains(id, "extgroupid") { + // extra group id + return SendNFIntancesUDR(id, NFDiscoveryToUDRParamExtGroupId) + } else if strings.Contains(id, "msisdn") || strings.Contains(id, "extid") { + // gpsi + return SendNFIntancesUDR(id, NFDiscoveryToUDRParamGpsi) + } + return SendNFIntancesUDR("", NFDiscoveryToUDRParamNone) +} + +func (s *nudrService) aucSQN(opc, k, auts, rand []byte) ([]byte, []byte) { + AK, SQNms := make([]byte, 6), make([]byte, 6) + macS := make([]byte, 8) + ConcSQNms := auts[:6] + AMF, err := hex.DecodeString(resyncAMF) + if err != nil { + return nil, nil + } + + logger.UeauLog.Tracef("aucSQN: ConcSQNms=[%x]", ConcSQNms) + + err = milenage.F2345(opc, k, rand, nil, nil, nil, nil, AK) + if err != nil { + logger.UeauLog.Errorln("aucSQN milenage F2345 err:", err) + } + + for i := 0; i < 6; i++ { + SQNms[i] = AK[i] ^ ConcSQNms[i] + } + + logger.UeauLog.Tracef("aucSQN: opc=[%x], k=[%x], rand=[%x], AMF=[%x], SQNms=[%x]\n", opc, k, rand, AMF, SQNms) + // The AMF used to calculate MAC-S assumes a dummy value of all zeros + err = milenage.F1(opc, k, rand, SQNms, AMF, nil, macS) + if err != nil { + logger.UeauLog.Errorln("aucSQN milenage F1 err:", err) + } + logger.UeauLog.Tracef("aucSQN: macS=[%x]\n", macS) + return SQNms, macS +} + +func (s *nudrService) strictHex(ss string, n int) string { + l := len(ss) + if l < n { + return strings.Repeat("0", n-l) + ss + } else { + return ss[l-n : l] + } +} + +func (s *nudrService) ConfirmAuthDataProcedure(authEvent models.AuthEvent, supi string) (problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + var createAuthParam Nudr_DataRepository.CreateAuthenticationStatusParamOpts + optInterface := optional.NewInterface(authEvent) + createAuthParam.AuthEvent = optInterface + + client, err := s.createUDMClientToUDR(supi) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := client.AuthenticationStatusDocumentApi.CreateAuthenticationStatus( + ctx, supi, &createAuthParam) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("ConfirmAuth err:", err.Error()) + return problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UeauLog.Errorf("CreateAuthenticationStatus response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} + +func (s *nudrService) GenerateAuthDataProcedure(authInfoRequest models.AuthenticationInfoRequest, supiOrSuci string) ( + response *models.AuthenticationInfoResult, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + logger.UeauLog.Traceln("In GenerateAuthDataProcedure") + + response = &models.AuthenticationInfoResult{} + rand.Seed(time.Now().UnixNano()) + supi, err := suci.ToSupi(supiOrSuci, udm_context.GetSelf().SuciProfiles) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("suciToSupi error: ", err.Error()) + return nil, problemDetails + } + + logger.UeauLog.Tracef("supi conversion => [%s]", supi) + + client, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + authSubs, res, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(ctx, supi, nil) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + switch res.StatusCode { + case http.StatusNotFound: + logger.UeauLog.Warnf("Return from UDR QueryAuthSubsData error") + default: + logger.UeauLog.Errorln("Return from UDR QueryAuthSubsData error") + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAuthSubsData response body cannot close: %+v", rspCloseErr) + } + }() + + /* + K, RAND, CK, IK: 128 bits (16 bytes) (hex len = 32) + SQN, AK: 48 bits (6 bytes) (hex len = 12) TS33.102 - 6.3.2 + AMF: 16 bits (2 bytes) (hex len = 4) TS33.102 - Annex H + */ + + hasK, hasOP, hasOPC := false, false, false + var kStr, opStr, opcStr string + var k, op, opc []byte + + if authSubs.PermanentKey != nil { + kStr = authSubs.PermanentKey.PermanentKeyValue + if len(kStr) == keyStrLen { + k, err = hex.DecodeString(kStr) + if err != nil { + logger.UeauLog.Errorln("err:", err) + } else { + hasK = true + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + logger.UeauLog.Errorln("kStr length is ", len(kStr)) + return nil, problemDetails + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + logger.UeauLog.Errorln("Nil PermanentKey") + return nil, problemDetails + } + + if authSubs.Milenage != nil { + if authSubs.Milenage.Op != nil && authSubs.Milenage.Op.OpValue != "" { + opStr = authSubs.Milenage.Op.OpValue + if len(opStr) == opStrLen { + op, err = hex.DecodeString(opStr) + if err != nil { + logger.UeauLog.Errorln("err:", err) + } else { + hasOP = true + } + } else { + logger.UeauLog.Errorln("opStr length is ", len(opStr)) + } + } else { + logger.UeauLog.Infoln("Nil Op") + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + logger.UeauLog.Infoln("Nil Milenage") + return nil, problemDetails + } + + if authSubs.Opc != nil && authSubs.Opc.OpcValue != "" { + opcStr = authSubs.Opc.OpcValue + if len(opcStr) == opcStrLen { + opc, err = hex.DecodeString(opcStr) + if err != nil { + logger.UeauLog.Errorln("err:", err) + } else { + hasOPC = true + } + } else { + logger.UeauLog.Errorln("opcStr length is ", len(opcStr)) + } + } else { + logger.UeauLog.Infoln("Nil Opc") + } + + if !hasOPC && !hasOP { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + return nil, problemDetails + } + + if !hasOPC { + if hasK && hasOP { + opc, err = milenage.GenerateOPC(k, op) + if err != nil { + logger.UeauLog.Errorln("milenage GenerateOPC err:", err) + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + logger.UeauLog.Errorln("Unable to derive OPC") + return nil, problemDetails + } + } + + sqnStr := s.strictHex(authSubs.SequenceNumber, 12) + logger.UeauLog.Traceln("sqnStr", sqnStr) + sqn, err := hex.DecodeString(sqnStr) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + logger.UeauLog.Tracef("K=[%x], sqn=[%x], OP=[%x], OPC=[%x]", k, sqn, op, opc) + + RAND := make([]byte, 16) + _, err = cryptoRand.Read(RAND) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + amfStr := s.strictHex(authSubs.AuthenticationManagementField, 4) + logger.UeauLog.Traceln("amfStr", amfStr) + AMF, err := hex.DecodeString(amfStr) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + logger.UeauLog.Tracef("RAND=[%x], AMF=[%x]", RAND, AMF) + + // re-synchronization + if authInfoRequest.ResynchronizationInfo != nil { + logger.UeauLog.Infof("Authentication re-synchronization") + + Auts, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Auts) + if deCodeErr != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: deCodeErr.Error(), + } + + logger.UeauLog.Errorln("err:", deCodeErr) + return nil, problemDetails + } + + randHex, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Rand) + if deCodeErr != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: deCodeErr.Error(), + } + + logger.UeauLog.Errorln("err:", deCodeErr) + return nil, problemDetails + } + + SQNms, macS := s.aucSQN(opc, k, Auts, randHex) + if reflect.DeepEqual(macS, Auts[6:]) { + _, err = cryptoRand.Read(RAND) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: deCodeErr.Error(), + } + + logger.UeauLog.Errorln("err:", deCodeErr) + return nil, problemDetails + } + + // increment sqn authSubs.SequenceNumber + bigSQN := big.NewInt(0) + sqnStr = hex.EncodeToString(SQNms) + logger.UeauLog.Tracef("SQNstr=[%s]", sqnStr) + bigSQN.SetString(sqnStr, 16) + + bigInc := big.NewInt(ind + 1) + + bigP := big.NewInt(SqnMAx) + bigSQN = bigInc.Add(bigSQN, bigInc) + bigSQN = bigSQN.Mod(bigSQN, bigP) + sqnStr = fmt.Sprintf("%x", bigSQN) + sqnStr = s.strictHex(sqnStr, 12) + } else { + logger.UeauLog.Errorln("Re-Sync MAC failed ", supiOrSuci) + // Check if suci + suciPart := strings.Split(supiOrSuci, "-") + if suciPart[suci.PrefixPlace] == suci.PrefixSUCI && + suciPart[suci.SupiTypePlace] == suci.SupiTypeIMSI && + suciPart[suci.SchemePlace] != suci.NullScheme { + // Get SuciProfile index and write public key + keyIndex, err1 := strconv.Atoi(suciPart[suci.HNPublicKeyIDPlace]) + if err1 != nil { + logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace parse Error") + } else if keyIndex < 1 { + logger.UeauLog.Errorf("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace keyIndex[%d] < 1", + keyIndex) + } else { + logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key ", + udm_context.GetSelf().SuciProfiles[keyIndex-1].PublicKey) + } + } + logger.UeauLog.Errorln("MACS ", macS) + logger.UeauLog.Errorln("Auts[6:] ", Auts[6:]) + logger.UeauLog.Errorln("Sqn ", SQNms) + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "modification is rejected", + } + return nil, problemDetails + } + } + + // increment sqn + bigSQN := big.NewInt(0) + sqn, err = hex.DecodeString(sqnStr) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + bigSQN.SetString(sqnStr, 16) + + bigInc := big.NewInt(1) + bigSQN = bigInc.Add(bigSQN, bigInc) + + SQNheStr := fmt.Sprintf("%x", bigSQN) + SQNheStr = s.strictHex(SQNheStr, 12) + patchItemArray := []models.PatchItem{ + { + Op: models.PatchOperation_REPLACE, + Path: "/sequenceNumber", + Value: SQNheStr, + }, + } + + var rsp *http.Response + + rsp, err = client.AuthenticationDataDocumentApi.ModifyAuthentication( + ctx, supi, patchItemArray) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "modification is rejected ", + Detail: err.Error(), + } + + logger.UeauLog.Errorln("update sqn error:", err) + return nil, problemDetails + } + defer func() { + if rspCloseErr := rsp.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("ModifyAuthentication response body cannot close: %+v", rspCloseErr) + } + }() + + // Run milenage + macA, macS := make([]byte, 8), make([]byte, 8) + CK, IK := make([]byte, 16), make([]byte, 16) + RES := make([]byte, 8) + AK, AKstar := make([]byte, 6), make([]byte, 6) + + // Generate macA, macS + err = milenage.F1(opc, k, RAND, sqn, AMF, macA, macS) + if err != nil { + logger.UeauLog.Errorln("milenage F1 err:", err) + } + + // Generate RES, CK, IK, AK, AKstar + // RES == XRES (expected RES) for server + err = milenage.F2345(opc, k, RAND, RES, CK, IK, AK, AKstar) + if err != nil { + logger.UeauLog.Errorln("milenage F2345 err:", err) + } + logger.UeauLog.Tracef("milenage RES=[%s]", hex.EncodeToString(RES)) + + // Generate AUTN + logger.UeauLog.Tracef("SQN=[%x], AK=[%x]", sqn, AK) + logger.UeauLog.Tracef("AMF=[%x], macA=[%x]", AMF, macA) + SQNxorAK := make([]byte, 6) + for i := 0; i < len(sqn); i++ { + SQNxorAK[i] = sqn[i] ^ AK[i] + } + logger.UeauLog.Tracef("SQN xor AK=[%x]", SQNxorAK) + AUTN := append(append(SQNxorAK, AMF...), macA...) + logger.UeauLog.Tracef("AUTN=[%x]", AUTN) + + var av models.AuthenticationVector + if authSubs.AuthenticationMethod == models.AuthMethod__5_G_AKA { + response.AuthType = models.AuthType__5_G_AKA + + // derive XRES* + key := append(CK, IK...) + FC := ueauth.FC_FOR_RES_STAR_XRES_STAR_DERIVATION + P0 := []byte(authInfoRequest.ServingNetworkName) + P1 := RAND + P2 := RES + + kdfValForXresStar, err := ueauth.GetKDFValue( + key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1), P2, ueauth.KDFLen(P2)) + if err != nil { + logger.UeauLog.Errorf("Get kdfValForXresStar err: %+v", err) + } + xresStar := kdfValForXresStar[len(kdfValForXresStar)/2:] + logger.UeauLog.Tracef("xresStar=[%x]", xresStar) + + // derive Kausf + FC = ueauth.FC_FOR_KAUSF_DERIVATION + P0 = []byte(authInfoRequest.ServingNetworkName) + P1 = SQNxorAK + kdfValForKausf, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) + if err != nil { + logger.UeauLog.Errorf("Get kdfValForKausf err: %+v", err) + } + logger.UeauLog.Tracef("Kausf=[%x]", kdfValForKausf) + + // Fill in rand, xresStar, autn, kausf + av.Rand = hex.EncodeToString(RAND) + av.XresStar = hex.EncodeToString(xresStar) + av.Autn = hex.EncodeToString(AUTN) + av.Kausf = hex.EncodeToString(kdfValForKausf) + av.AvType = models.AvType__5_G_HE_AKA + } else { // EAP-AKA' + response.AuthType = models.AuthType_EAP_AKA_PRIME + + // derive CK' and IK' + key := append(CK, IK...) + FC := ueauth.FC_FOR_CK_PRIME_IK_PRIME_DERIVATION + P0 := []byte(authInfoRequest.ServingNetworkName) + P1 := SQNxorAK + kdfVal, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) + if err != nil { + logger.UeauLog.Errorf("Get kdfVal err: %+v", err) + } + logger.UeauLog.Tracef("kdfVal=[%x] (len=%d)", kdfVal, len(kdfVal)) + + // For TS 35.208 test set 19 & RFC 5448 test vector 1 + // CK': 0093 962d 0dd8 4aa5 684b 045c 9edf fa04 + // IK': ccfc 230c a74f cc96 c0a5 d611 64f5 a76 + + ckPrime := kdfVal[:len(kdfVal)/2] + ikPrime := kdfVal[len(kdfVal)/2:] + logger.UeauLog.Tracef("ckPrime=[%x], kPrime=[%x]", ckPrime, ikPrime) + + // Fill in rand, xres, autn, ckPrime, ikPrime + av.Rand = hex.EncodeToString(RAND) + av.Xres = hex.EncodeToString(RES) + av.Autn = hex.EncodeToString(AUTN) + av.CkPrime = hex.EncodeToString(ckPrime) + av.IkPrime = hex.EncodeToString(ikPrime) + av.AvType = models.AvType_EAP_AKA_PRIME + } + + response.AuthenticationVector = &av + response.Supi = supi + return response, nil +} + +func (s *nudrService) UpdateProcedure(updateRequest models.PpData, gpsi string) (problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + clientAPI, err := s.createUDMClientToUDR(gpsi) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + res, err := clientAPI.ProvisionedParameterDataDocumentApi.ModifyPpData(ctx, gpsi, nil) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.PpLog.Errorf("ModifyPpData response body cannot close: %+v", rspCloseErr) + } + }() + return nil +} + +func (s *nudrService) getAmDataProcedure(supi string, plmnID string, supportedFeatures string) ( + response *models.AccessAndMobilitySubscriptionData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. + QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetAMSubsriptionData(&accessAndMobilitySubscriptionDataResp) + return &accessAndMobilitySubscriptionDataResp, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (s *nudrService) getIdTranslationResultProcedure(gpsi string) (response *models.IdTranslationResult, + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var idTranslationResult models.IdTranslationResult + var getIdentityDataParamOpts Nudr_DataRepository.GetIdentityDataParamOpts + + clientAPI, err := s.createUDMClientToUDR(gpsi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + idTranslationResultResp, res, err := clientAPI.QueryIdentityDataBySUPIOrGPSIDocumentApi.GetIdentityData( + ctx, gpsi, &getIdentityDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("GetIdentityData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + if idList := idTranslationResultResp; idList.SupiList != nil { + // GetCorrespondingSupi get corresponding Supi(here IMSI) matching the given Gpsi from the queried SUPI list from UDR + idTranslationResult.Supi = udm_context.GetCorrespondingSupi(idList) + idTranslationResult.Gpsi = gpsi + + return &idTranslationResult, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (s *nudrService) getSupiProcedure(supi string, plmnID string, dataSetNames []string, supportedFeatures string) ( + response *models.SubscriptionDataSets, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + if len(dataSetNames) < 2 { + problemDetails = &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "BAD_REQUEST", + Detail: "datasetNames must have at least 2 elements", + } + return nil, problemDetails + } + + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var subscriptionDataSets, subsDataSetBody models.SubscriptionDataSets + var ueContextInSmfDataResp models.UeContextInSmfData + pduSessionMap := make(map[string]models.PduSession) + var pgwInfoArray []models.PgwInfo + + var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + var querySmfSelectDataParamOpts Nudr_DataRepository.QuerySmfSelectDataParamOpts + var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts + var querySmDataParamOpts Nudr_DataRepository.QuerySmDataParamOpts + + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + udm_context.GetSelf().CreateSubsDataSetsForUe(supi, subsDataSetBody) + + if s.containDataSetName(dataSetNames, string(models.DataSetName_AM)) { + var body models.AccessAndMobilitySubscriptionData + udm_context.GetSelf().CreateAccessMobilitySubsDataForUe(supi, body) + + amData, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi.QueryAmData( + ctx, supi, plmnID, &queryAmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetAMSubsriptionData(&amData) + subscriptionDataSets.AmData = &amData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + if s.containDataSetName(dataSetNames, string(models.DataSetName_SMF_SEL)) { + var smfSelSubsbody models.SmfSelectionSubscriptionData + udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, smfSelSubsbody) + + smfSelData, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi.QuerySmfSelectData(ctx, + supi, plmnID, &querySmfSelectDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorln(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorln(err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetSmfSelectionSubsData(&smfSelData) + subscriptionDataSets.SmfSelData = &smfSelData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + if s.containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMF)) { + var UeContextInSmfbody models.UeContextInSmfData + var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts + querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, UeContextInSmfbody) + + pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( + ctx, supi, &querySmfRegListParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) + } + }() + + for _, element := range pdusess { + var pduSession models.PduSession + pduSession.Dnn = element.Dnn + pduSession.SmfInstanceId = element.SmfInstanceId + pduSession.PlmnId = element.PlmnId + pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession + } + ueContextInSmfDataResp.PduSessions = pduSessionMap + + for _, element := range pdusess { + var pgwInfo models.PgwInfo + pgwInfo.Dnn = element.Dnn + pgwInfo.PgwFqdn = element.PgwFqdn + pgwInfo.PlmnId = element.PlmnId + pgwInfoArray = append(pgwInfoArray, pgwInfo) + } + ueContextInSmfDataResp.PgwInfo = pgwInfoArray + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.UeCtxtInSmfData = &ueContextInSmfDataResp + subscriptionDataSets.UecSmfData = &ueContextInSmfDataResp + } else { + var problemDetails models.ProblemDetails + problemDetails.Cause = "DATA_NOT_FOUND" + logger.SdmLog.Errorf(problemDetails.Cause) + } + } + + // TODO: UE Context in SMSF Data + // if containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMSF)) { + // } + + // TODO: SMS Subscription Data + // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_SUB)) { + // } + + if s.containDataSetName(dataSetNames, string(models.DataSetName_SM)) { + sessionManagementSubscriptionData, res, err := clientAPI.SessionManagementSubscriptionDataApi. + QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + smData, _, _, _ := udm_context.GetSelf().ManageSmData(sessionManagementSubscriptionData, "", "") + udmUe.SetSMSubsData(smData) + subscriptionDataSets.SmData = sessionManagementSubscriptionData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + if s.containDataSetName(dataSetNames, string(models.DataSetName_TRACE)) { + var TraceDatabody models.TraceData + udm_context.GetSelf().CreateTraceDataforUe(supi, TraceDatabody) + + traceData, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( + ctx, supi, plmnID, &queryTraceDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.TraceData = &traceData + udmUe.TraceDataResponse.TraceData = &traceData + subscriptionDataSets.TraceData = &traceData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + // TODO: SMS Management Subscription Data + // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_MNG)) { + // } + + return &subscriptionDataSets, nil +} + +func (s *nudrService) getSharedDataProcedure(sharedDataIds []string, supportedFeatures string) ( + response []models.SharedData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := s.createUDMClientToUDR("") + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var getSharedDataParamOpts Nudr_DataRepository.GetSharedDataParamOpts + getSharedDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + sharedDataResp, res, err := clientAPI.RetrievalOfSharedDataApi.GetSharedData(ctx, sharedDataIds, + &getSharedDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("GetShareData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udm_context.GetSelf().SharedSubsDataMap = udm_context.MappingSharedData(sharedDataResp) + sharedData := udm_context.ObtainRequiredSharedData(sharedDataIds, sharedDataResp) + return sharedData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (s *nudrService) getSmDataProcedure(supi string, plmnID string, Dnn string, Snssai string, supportedFeatures string) ( + response interface{}, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + logger.SdmLog.Infof("getSmDataProcedure: SUPI[%s] PLMNID[%s] DNN[%s] SNssai[%s]", supi, plmnID, Dnn, Snssai) + + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var querySmDataParamOpts Nudr_DataRepository.QuerySmDataParamOpts + querySmDataParamOpts.SingleNssai = optional.NewInterface(Snssai) + + sessionManagementSubscriptionDataResp, res, err := clientAPI.SessionManagementSubscriptionDataApi. + QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + smData, snssaikey, AllDnnConfigsbyDnn, AllDnns := udm_context.GetSelf().ManageSmData( + sessionManagementSubscriptionDataResp, Snssai, Dnn) + udmUe.SetSMSubsData(smData) + + rspSMSubDataList := make([]models.SessionManagementSubscriptionData, 0, 4) + + udmUe.SmSubsDataLock.RLock() + for _, eachSMSubData := range udmUe.SessionManagementSubsData { + rspSMSubDataList = append(rspSMSubDataList, eachSMSubData) + } + udmUe.SmSubsDataLock.RUnlock() + + switch { + case Snssai == "" && Dnn == "": + return AllDnns, nil + case Snssai != "" && Dnn == "": + udmUe.SmSubsDataLock.RLock() + defer udmUe.SmSubsDataLock.RUnlock() + return udmUe.SessionManagementSubsData[snssaikey].DnnConfigurations, nil + case Snssai == "" && Dnn != "": + return AllDnnConfigsbyDnn, nil + case Snssai != "" && Dnn != "": + return rspSMSubDataList, nil + default: + udmUe.SmSubsDataLock.RLock() + defer udmUe.SmSubsDataLock.RUnlock() + return udmUe.SessionManagementSubsData, nil + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (s *nudrService) getNssaiProcedure(supi string, plmnID string, supportedFeatures string) ( + *models.Nssai, *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + var nssaiResp models.Nssai + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. + QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails := &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) + } + }() + + nssaiResp = *accessAndMobilitySubscriptionDataResp.Nssai + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.Nssai = &nssaiResp + return udmUe.Nssai, nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (s *nudrService) getSmfSelectDataProcedure(supi string, plmnID string, supportedFeatures string) ( + response *models.SmfSelectionSubscriptionData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var querySmfSelectDataParamOpts Nudr_DataRepository.QuerySmfSelectDataParamOpts + querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + var body models.SmfSelectionSubscriptionData + + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, body) + + smfSelectionSubscriptionDataResp, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi. + QuerySmfSelectData(ctx, supi, plmnID, &querySmfSelectDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetSmfSelectionSubsData(&smfSelectionSubscriptionDataResp) + return udmUe.SmfSelSubsData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (s *nudrService) subscribeProcedure(sdmSubscription *models.SdmSubscription, supi string) ( + header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + sdmSubscriptionResp, res, err := clientAPI.SDMSubscriptionsCollectionApi.CreateSdmSubscriptions( + ctx, supi, *sdmSubscription) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("CreateSdmSubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusCreated { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) + if udmUe == nil { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.CreateSubscriptiontoNotifChange(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) + header.Set("Location", udmUe.GetLocationURI2(udm_context.LocationUriSdmSubscription, supi)) + return header, &sdmSubscriptionResp, nil + } else if res.StatusCode == http.StatusNotFound { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, nil, problemDetails + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotImplemented, + Cause: "UNSUPPORTED_RESOURCE_URI", + } + return nil, nil, problemDetails + } +} + +func (s *nudrService) unsubscribeProcedure(supi string, subscriptionID string) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + res, err := clientAPI.SDMSubscriptionDocumentApi.RemovesdmSubscriptions(ctx, supi, subscriptionID) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails := &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("RemovesdmSubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusNoContent { + return nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + return problemDetails + } +} + +func (s *nudrService) modifyProcedure(sdmSubsModification *models.SdmSubsModification, supi string, subscriptionID string) ( + response *models.SdmSubscription, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + sdmSubscription := models.SdmSubscription{} + body := Nudr_DataRepository.UpdatesdmsubscriptionsParamOpts{ + SdmSubscription: optional.NewInterface(sdmSubscription), + } + + res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( + ctx, supi, subscriptionID, &body) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + return &sdmSubscription, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (s *nudrService) getTraceDataProcedure(supi string, plmnID string) ( + response *models.TraceData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var body models.TraceData + var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts + + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + udm_context.GetSelf().CreateTraceDataforUe(supi, body) + + traceDataRes, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( + ctx, supi, plmnID, &queryTraceDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.TraceData = &traceDataRes + udmUe.TraceDataResponse.TraceData = &traceDataRes + + return udmUe.TraceDataResponse.TraceData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (s *nudrService) getUeContextInSmfDataProcedure(supi string, supportedFeatures string) ( + response *models.UeContextInSmfData, problemDetails *models.ProblemDetails, +) { + var body models.UeContextInSmfData + var ueContextInSmfData models.UeContextInSmfData + var pgwInfoArray []models.PgwInfo + var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts + querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + pduSessionMap := make(map[string]models.PduSession) + udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, body) + + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + + pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( + ctx, supi, &querySmfRegListParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Infoln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Infoln(err) + } else { + logger.SdmLog.Infoln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) + } + }() + + for _, element := range pdusess { + var pduSession models.PduSession + pduSession.Dnn = element.Dnn + pduSession.SmfInstanceId = element.SmfInstanceId + pduSession.PlmnId = element.PlmnId + pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession + } + ueContextInSmfData.PduSessions = pduSessionMap + + for _, element := range pdusess { + var pgwInfo models.PgwInfo + pgwInfo.Dnn = element.Dnn + pgwInfo.PgwFqdn = element.PgwFqdn + pgwInfo.PlmnId = element.PlmnId + pgwInfoArray = append(pgwInfoArray, pgwInfo) + } + ueContextInSmfData.PgwInfo = pgwInfoArray + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.UeCtxtInSmfData = &ueContextInSmfData + return udmUe.UeCtxtInSmfData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +// ue_context_managemanet_service +func (s *nudrService) GetAmf3gppAccessProcedure(ueID string, supportedFeatures string) ( + response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var queryAmfContext3gppParamOpts Nudr_DataRepository.QueryAmfContext3gppParamOpts + queryAmfContext3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + amf3GppAccessRegistration, resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi. + QueryAmfContext3gpp(ctx, ueID, &queryAmfContext3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return &amf3GppAccessRegistration, nil +} + +func (s *nudrService) GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts Nudr_DataRepository. + QueryAmfContextNon3gppParamOpts, ueID string) (response *models.AmfNon3GppAccessRegistration, + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + amfNon3GppAccessRegistration, resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi. + QueryAmfContextNon3gpp(ctx, ueID, &queryAmfContextNon3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return &amfNon3GppAccessRegistration, nil +} + +func (s *nudrService) RegistrationAmf3gppAccessProcedure(registerRequest models.Amf3GppAccessRegistration, ueID string) ( + header http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + // TODO: EPS interworking with N26 is not supported yet in this stage + var oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration + var ue *udm_context.UdmUeContext + + if udm_context.GetSelf().UdmAmf3gppRegContextExists(ueID) { + ue, _ = udm_context.GetSelf().UdmUeFindBySupi(ueID) + oldAmf3GppAccessRegContext = ue.Amf3GppAccessRegistration + } + + udm_context.GetSelf().CreateAmf3gppRegContext(ueID, registerRequest) + + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var createAmfContext3gppParamOpts Nudr_DataRepository.CreateAmfContext3gppParamOpts + optInterface := optional.NewInterface(registerRequest) + createAmfContext3gppParamOpts.Amf3GppAccessRegistration = optInterface + resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.CreateAmfContext3gpp(ctx, + ueID, &createAmfContext3gppParamOpts) + if err != nil { + logger.UecmLog.Errorln("CreateAmfContext3gpp error : ", err) + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF + // corresponding to the same (e.g. 3GPP) access, if one exists + if oldAmf3GppAccessRegContext != nil { + if !ue.SameAsStoredGUAMI3gpp(*oldAmf3GppAccessRegContext.Guami) { + // Based on TS 23.502 4.2.2.2.2, If the serving NF removal reason indicated by the UDM is Initial Registration, + // the old AMF invokes the Nsmf_PDUSession_ReleaseSMContext (SM Context ID). Thus we give different + // dereg cause based on registration parameter from serving AMF + deregReason := models.DeregistrationReason_UE_REGISTRATION_AREA_CHANGE + if registerRequest.InitialRegistrationInd { + deregReason = models.DeregistrationReason_UE_INITIAL_REGISTRATION + } + deregistData := models.DeregistrationData{ + DeregReason: deregReason, + AccessType: models.AccessType__3_GPP_ACCESS, + } + + go func() { + logger.UecmLog.Infof("Send DeregNotify to old AMF GUAMI=%v", oldAmf3GppAccessRegContext.Guami) + pd := callback.SendOnDeregistrationNotification(ueID, + oldAmf3GppAccessRegContext.DeregCallbackUri, + deregistData) // Deregistration Notify Triggered + if pd != nil { + logger.UecmLog.Errorf("RegistrationAmf3gppAccess: send DeregNotify fail %v", pd) + } + }() + } + return nil, ®isterRequest, nil + } else { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration)) + return header, ®isterRequest, nil + } +} + +func (s *nudrService) RegisterAmfNon3gppAccessProcedure(registerRequest models.AmfNon3GppAccessRegistration, ueID string) ( + header http.Header, response *models.AmfNon3GppAccessRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + var oldAmfNon3GppAccessRegContext *models.AmfNon3GppAccessRegistration + if udm_context.GetSelf().UdmAmfNon3gppRegContextExists(ueID) { + ue, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + oldAmfNon3GppAccessRegContext = ue.AmfNon3GppAccessRegistration + } + + udm_context.GetSelf().CreateAmfNon3gppRegContext(ueID, registerRequest) + + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var createAmfContextNon3gppParamOpts Nudr_DataRepository.CreateAmfContextNon3gppParamOpts + optInterface := optional.NewInterface(registerRequest) + createAmfContextNon3gppParamOpts.AmfNon3GppAccessRegistration = optInterface + + resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.CreateAmfContextNon3gpp( + ctx, ueID, &createAmfContextNon3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF + // corresponding to the same (e.g. 3GPP) access, if one exists + if oldAmfNon3GppAccessRegContext != nil { + deregistData := models.DeregistrationData{ + DeregReason: models.DeregistrationReason_UE_INITIAL_REGISTRATION, + AccessType: models.AccessType_NON_3_GPP_ACCESS, + } + callback.SendOnDeregistrationNotification(ueID, oldAmfNon3GppAccessRegContext.DeregCallbackUri, + deregistData) // Deregistration Notify Triggered + + return nil, nil, nil + } else { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmfNon3GppAccessRegistration)) + return header, ®isterRequest, nil + } +} + +func (s *nudrService) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessRegistrationModification, ueID string) ( + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + var patchItemReqArray []models.PatchItem + currentContext := udm_context.GetSelf().GetAmf3gppRegContext(ueID) + if currentContext == nil { + logger.UecmLog.Errorln("[UpdateAmf3gppAccess] Empty Amf3gppRegContext") + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "CONTEXT_NOT_FOUND", + } + return problemDetails + } + + if request.Guami != nil { + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + if udmUe.SameAsStoredGUAMI3gpp(*request.Guami) { // deregistration + logger.UecmLog.Infoln("UpdateAmf3gppAccess - deregistration") + request.PurgeFlag = true + } else { + logger.UecmLog.Errorln("INVALID_GUAMI") + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "INVALID_GUAMI", + } + return problemDetails + } + + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "guami" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = *request.Guami + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.PurgeFlag { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "purgeFlag" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.PurgeFlag + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.Pei != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "pei" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.Pei + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.ImsVoPs != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "imsVoPs" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.ImsVoPs + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.BackupAmfInfo != nil { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "backupAmfInfo" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.BackupAmfInfo + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.AmfContext3gpp(ctx, ueID, + patchItemReqArray) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return problemDetails + } + + if request.PurgeFlag { + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + udmUe.Amf3GppAccessRegistration = nil + } + + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("AmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} + +func (s *nudrService) UpdateAmfNon3gppAccessProcedure(request models.AmfNon3GppAccessRegistrationModification, ueID string) ( + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + var patchItemReqArray []models.PatchItem + currentContext := udm_context.GetSelf().GetAmfNon3gppRegContext(ueID) + if currentContext == nil { + logger.UecmLog.Errorln("[UpdateAmfNon3gppAccess] Empty AmfNon3gppRegContext") + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "CONTEXT_NOT_FOUND", + } + return problemDetails + } + + if request.Guami != nil { + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + if udmUe.SameAsStoredGUAMINon3gpp(*request.Guami) { // deregistration + logger.UecmLog.Infoln("UpdateAmfNon3gppAccess - deregistration") + request.PurgeFlag = true + } else { + logger.UecmLog.Errorln("INVALID_GUAMI") + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "INVALID_GUAMI", + } + } + + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "guami" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = *request.Guami + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.PurgeFlag { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "purgeFlag" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.PurgeFlag + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.Pei != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "pei" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.Pei + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.ImsVoPs != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "imsVoPs" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.ImsVoPs + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.BackupAmfInfo != nil { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "backupAmfInfo" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.BackupAmfInfo + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.AmfContextNon3gpp(ctx, + ueID, patchItemReqArray) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("AmfContextNon3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return problemDetails +} + +func (s *nudrService) DeregistrationSmfRegistrationsProcedure(ueID string, pduSessionID string) (problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.SMFRegistrationDocumentApi.DeleteSmfContext(ctx, ueID, pduSessionID) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("DeleteSmfContext response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} + +func (s *nudrService) RegistrationSmfRegistrationsProcedure(request *models.SmfRegistration, ueID string, pduSessionID string) ( + header http.Header, response *models.SmfRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + contextExisted := false + udm_context.GetSelf().CreateSmfRegContext(ueID, pduSessionID) + if !udm_context.GetSelf().UdmSmfRegContextNotExists(ueID) { + contextExisted = true + } + + pduID64, err := strconv.ParseInt(pduSessionID, 10, 32) + if err != nil { + logger.UecmLog.Errorln(err.Error()) + } + pduID32 := int32(pduID64) + + var createSmfContextNon3gppParamOpts Nudr_DataRepository.CreateSmfContextNon3gppParamOpts + optInterface := optional.NewInterface(*request) + createSmfContextNon3gppParamOpts.SmfRegistration = optInterface + + clientAPI, err := s.createUDMClientToUDR(ueID) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.SMFRegistrationDocumentApi.CreateSmfContextNon3gpp(ctx, ueID, + pduID32, &createSmfContextNon3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("CreateSmfContextNon3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + if contextExisted { + return nil, nil, nil + } else { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriSmfRegistration)) + return header, request, nil + } +} From 21c90fb3656086104a4eec3a1aa075d3af03aeeb Mon Sep 17 00:00:00 2001 From: ubuntu Date: Mon, 29 Apr 2024 05:43:42 +0000 Subject: [PATCH 03/23] feat: refactor processor ee, pp, callback --- .../data_change_notification_to_nf.go | 57 ++++++++ internal/sbi/processor/ee_subscription.go | 128 ++++++++++++++++++ .../sbi/processor/subscription_data_update.go | 59 ++++++++ 3 files changed, 244 insertions(+) create mode 100644 internal/sbi/processor/data_change_notification_to_nf.go create mode 100644 internal/sbi/processor/ee_subscription.go create mode 100644 internal/sbi/processor/subscription_data_update.go diff --git a/internal/sbi/processor/data_change_notification_to_nf.go b/internal/sbi/processor/data_change_notification_to_nf.go new file mode 100644 index 0000000..33ec788 --- /dev/null +++ b/internal/sbi/processor/data_change_notification_to_nf.go @@ -0,0 +1,57 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + +func HTTPDataChangeNotificationToNF(c *gin.Context) { + var dataChangeNotify models.DataChangeNotify + // 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.CallbackLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&dataChangeNotify, 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 + } + + supi := c.Params.ByName("supi") + + logger.CallbackLog.Infof("Handle DataChangeNotificationToNF") + + problemDetails := DataChangeNotificationProcedure(dataChangeNotify.NotifyItems, supi) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} diff --git a/internal/sbi/processor/ee_subscription.go b/internal/sbi/processor/ee_subscription.go new file mode 100644 index 0000000..02c5d10 --- /dev/null +++ b/internal/sbi/processor/ee_subscription.go @@ -0,0 +1,128 @@ +/* + * Nudm_EE + * + * Nudm Event Exposure Service + * + * API version: 1.0.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + +// HTTPCreateEeSubscription - Subscribe +func HTTPCreateEeSubscription(c *gin.Context) { + var eesubscription models.EeSubscription + + requestBody, err := c.GetRawData() + if err != nil { + logger.EeLog.Errorf("Get Request Body error: %+v", err) + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&eesubscription, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.EeLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // Start + logger.EeLog.Infoln("Handle Create EE Subscription") + + ueIdentity := c.Params.ByName("ueIdentity") + + createdEESubscription, problemDetails := CreateEeSubscriptionProcedure(ueIdentity, eesubscription) + if createdEESubscription != nil { + c.JSON(http.StatusCreated, createdEESubscription) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + c.JSON(http.StatusInternalServerError, problemDetails) + return + } +} + +func HTTPDeleteEeSubscription(c *gin.Context) { + + ueIdentity := c.Params.ByName("ueIdentity") + subscriptionID := c.Params.ByName("subscriptionId") + + DeleteEeSubscriptionProcedure(ueIdentity, subscriptionID) + // only return 204 no content + c.Status(http.StatusNoContent) +} + +func HTTPUpdateEeSubscription(c *gin.Context) { + var patchList []models.PatchItem + + requestBody, err := c.GetRawData() + if err != nil { + logger.EeLog.Errorf("Get Request Body error: %+v", err) + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&patchList, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.EeLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + ueIdentity := c.Params.ByName("ueIdentity") + subscriptionID := c.Params.ByName("subscriptionId") + + logger.EeLog.Infoln("Handle Update EE subscription") + logger.EeLog.Warnln("Update EE Subscription is not implemented") + + problemDetails := UpdateEeSubscriptionProcedure(ueIdentity, subscriptionID, patchList) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } + +} diff --git a/internal/sbi/processor/subscription_data_update.go b/internal/sbi/processor/subscription_data_update.go new file mode 100644 index 0000000..770de17 --- /dev/null +++ b/internal/sbi/processor/subscription_data_update.go @@ -0,0 +1,59 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + +func HTTPUpdate(c *gin.Context) { + var ppDataReq models.PpData + + // 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.PpLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&ppDataReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.PpLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + gpsi := c.Params.ByName("gpsi") + + logger.PpLog.Infoln("Handle UpdateRequest") + + // step 3: handle the message + problemDetails := UpdateProcedure(ppDataReq, gpsi) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} From aef8bceb762d6bb5c6d7111182011d3af46fb052 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Tue, 30 Apr 2024 06:24:59 +0000 Subject: [PATCH 04/23] feat: refactor uecm api_{SRV}.go and sdm api_{SRV}.go --- ...nd_mobility_subscription_data_retrieval.go | 72 ++++++++++ ..._gpp_access_registration_info_retrieval.go | 41 ++++++ ..._gpp_access_registration_info_retrieval.go | 45 ++++++ .../amf_registration_for3_gpp_access.go | 72 ++++++++++ .../amf_registration_for_non3_gpp_access.go | 68 +++++++++ internal/sbi/processor/confirm_auth.go | 57 ++++++++ internal/sbi/processor/generate_auth_data.go | 70 ++++++++++ .../sbi/processor/gpsi_to_supi_translation.go | 41 ++++++ ...in_the_amf_registration_for3_gpp_access.go | 62 +++++++++ ...he_amf_registration_for_non3_gpp_access.go | 61 +++++++++ ..._acknowledgement_of_steering_of_roaming.go | 12 ++ ...acknowledgement_of_ue_parameters_update.go | 12 ++ .../retrieval_of_multiple_data_sets.go | 53 +++++++ .../sbi/processor/retrieval_of_shared_data.go | 38 ++++++ ..._management_subscription_data_retrieval.go | 55 ++++++++ ...e_selection_subscription_data_retrieval.go | 51 +++++++ internal/sbi/processor/smf_deregistration.go | 32 +++++ internal/sbi/processor/smf_registration.go | 71 ++++++++++ ...f_selection_subscription_data_retrieval.go | 51 +++++++ ..._management_subscription_data_retrieval.go | 12 ++ .../sms_subscription_data_retrieval.go | 12 ++ ..._gpp_access_registration_info_retrieval.go | 12 ++ .../smsf_deregistration_for3_gpp_access.go | 12 ++ ...smsf_deregistration_for_non3_gpp_access.go | 12 ++ ..._gpp_access_registration_info_retrieval.go | 12 ++ .../smsf_registration_for3_gpp_access.go | 12 ++ .../smsf_registration_for_non3_gpp_access.go | 12 ++ .../sbi/processor/subscription_creation.go | 68 +++++++++ .../subscription_creation_for_shared_data.go | 75 ++++++++++ .../sbi/processor/subscription_deletion.go | 30 ++++ .../subscription_deletion_for_shared_data.go | 28 ++++ .../processor/subscription_modification.go | 129 ++++++++++++++++++ .../trace_configuration_data_retrieval.go | 40 ++++++ .../ue_context_in_smf_data_retrieval.go | 41 ++++++ .../ue_context_in_smsf_data_retrieval.go | 12 ++ 35 files changed, 1483 insertions(+) create mode 100644 internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go create mode 100644 internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go create mode 100644 internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go create mode 100644 internal/sbi/processor/amf_registration_for3_gpp_access.go create mode 100644 internal/sbi/processor/amf_registration_for_non3_gpp_access.go create mode 100644 internal/sbi/processor/confirm_auth.go create mode 100644 internal/sbi/processor/generate_auth_data.go create mode 100644 internal/sbi/processor/gpsi_to_supi_translation.go create mode 100644 internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go create mode 100644 internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go create mode 100644 internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go create mode 100644 internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go create mode 100644 internal/sbi/processor/retrieval_of_multiple_data_sets.go create mode 100644 internal/sbi/processor/retrieval_of_shared_data.go create mode 100644 internal/sbi/processor/session_management_subscription_data_retrieval.go create mode 100644 internal/sbi/processor/slice_selection_subscription_data_retrieval.go create mode 100644 internal/sbi/processor/smf_deregistration.go create mode 100644 internal/sbi/processor/smf_registration.go create mode 100644 internal/sbi/processor/smf_selection_subscription_data_retrieval.go create mode 100644 internal/sbi/processor/sms_management_subscription_data_retrieval.go create mode 100644 internal/sbi/processor/sms_subscription_data_retrieval.go create mode 100644 internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go create mode 100644 internal/sbi/processor/smsf_deregistration_for3_gpp_access.go create mode 100644 internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go create mode 100644 internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go create mode 100644 internal/sbi/processor/smsf_registration_for3_gpp_access.go create mode 100644 internal/sbi/processor/smsf_registration_for_non3_gpp_access.go create mode 100644 internal/sbi/processor/subscription_creation.go create mode 100644 internal/sbi/processor/subscription_creation_for_shared_data.go create mode 100644 internal/sbi/processor/subscription_deletion.go create mode 100644 internal/sbi/processor/subscription_deletion_for_shared_data.go create mode 100644 internal/sbi/processor/subscription_modification.go create mode 100644 internal/sbi/processor/trace_configuration_data_retrieval.go create mode 100644 internal/sbi/processor/ue_context_in_smf_data_retrieval.go create mode 100644 internal/sbi/processor/ue_context_in_smsf_data_retrieval.go diff --git a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go new file mode 100644 index 0000000..5af9601 --- /dev/null +++ b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go @@ -0,0 +1,72 @@ +package processor + +import ( + "encoding/json" + "net/http" + "net/url" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + +// GetAmData - retrieve a UE's Access and Mobility Subscription Data +func HTTPGetAmData(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("supported-features", c.Query("plmn-id")) + + // step 1: log + logger.SdmLog.Infof("Handle GetAmData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + + plmnIDStruct, problemDetails := getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := getAmDataProcedure(supi, plmnID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +func getPlmnIDStruct(queryParameters url.Values) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { + if queryParameters["plmn-id"] != nil { + plmnIDJson := queryParameters["plmn-id"][0] + plmnIDStruct := &models.PlmnId{} + err := json.Unmarshal([]byte(plmnIDJson), plmnIDStruct) + if err != nil { + logger.SdmLog.Warnln("Unmarshal Error in targetPlmnListtruct: ", err) + } + return plmnIDStruct, nil + } else { + problemDetails := &models.ProblemDetails{ + Title: "Invalid Parameter", + Status: http.StatusBadRequest, + Cause: "No get plmn-id", + } + return nil, problemDetails + } +} diff --git a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go new file mode 100644 index 0000000..0d36ccf --- /dev/null +++ b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go @@ -0,0 +1,41 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information +func HTTPGetAmf3gppAccess(c *gin.Context) { + + // step 1: log + logger.UecmLog.Infof("Handle HandleGetAmf3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + supportedFeatures := c.Query("supported-features") + + // step 3: handle the message + response, problemDetails := GetAmf3gppAccessProcedure(ueID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go new file mode 100644 index 0000000..b310882 --- /dev/null +++ b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go @@ -0,0 +1,45 @@ +package processor + +import ( + "net/http" + + "github.com/antihax/optional" + "github.com/free5gc/openapi/Nudr_DataRepository" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetAmfNon3gppAccess - retrieve the AMF registration for non-3GPP access information +func HTTPGetAmfNon3gppAccess(c *gin.Context) { + + // step 1: log + logger.UecmLog.Infoln("Handle GetAmfNon3gppAccessRequest") + + // step 2: retrieve request + ueId := c.Param("ueId") + supportedFeatures := c.Query("supported-features") + + var queryAmfContextNon3gppParamOpts Nudr_DataRepository.QueryAmfContextNon3gppParamOpts + queryAmfContextNon3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + // step 3: handle the message + response, problemDetails := GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts, ueId) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/amf_registration_for3_gpp_access.go b/internal/sbi/processor/amf_registration_for3_gpp_access.go new file mode 100644 index 0000000..aa6382e --- /dev/null +++ b/internal/sbi/processor/amf_registration_for3_gpp_access.go @@ -0,0 +1,72 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// RegistrationAmf3gppAccess - register as AMF for 3GPP access +func HTTPRegistrationAmf3gppAccess(c *gin.Context) { + var amf3GppAccessRegistration models.Amf3GppAccessRegistration + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amf3GppAccessRegistration, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle RegistrationAmf3gppAccess") + + // step 2: retrieve request + ueID := c.Param("ueId") + logger.UecmLog.Info("UEID: ", ueID) + + // step 3: handle the message + header, response, problemDetails := RegistrationAmf3gppAccessProcedure(amf3GppAccessRegistration, ueID) + + // step 4: process the return value from step 3 + if response != nil { + if header != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} diff --git a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go new file mode 100644 index 0000000..8039d7b --- /dev/null +++ b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go @@ -0,0 +1,68 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// Register - register as AMF for non-3GPP access +func HTTPRegistrationAmfNon3gppAccess(c *gin.Context) { + var amfNon3GppAccessRegistration models.AmfNon3GppAccessRegistration + + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amfNon3GppAccessRegistration, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + logger.UecmLog.Infof("Handle RegisterAmfNon3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + + // step 3: handle the message + header, response, problemDetails := RegisterAmfNon3gppAccessProcedure(amfNon3GppAccessRegistration, ueID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } + +} diff --git a/internal/sbi/processor/confirm_auth.go b/internal/sbi/processor/confirm_auth.go new file mode 100644 index 0000000..c2966d6 --- /dev/null +++ b/internal/sbi/processor/confirm_auth.go @@ -0,0 +1,57 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + +// ConfirmAuth - Create a new confirmation event +func HTTPConfirmAuth(c *gin.Context) { + var authEvent models.AuthEvent + // 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.UeauLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&authEvent, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UeauLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + supi := c.Params.ByName("supi") + + logger.UeauLog.Infoln("Handle ConfirmAuthDataRequest") + + problemDetails := ConfirmAuthDataProcedure(authEvent, supi) + + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusCreated) + return + } +} diff --git a/internal/sbi/processor/generate_auth_data.go b/internal/sbi/processor/generate_auth_data.go new file mode 100644 index 0000000..18dec45 --- /dev/null +++ b/internal/sbi/processor/generate_auth_data.go @@ -0,0 +1,70 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + +// GenerateAuthData - Generate authentication data for the UE +func HttpGenerateAuthData(c *gin.Context) { + var authInfoReq models.AuthenticationInfoRequest + + // 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.UeauLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&authInfoReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UeauLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UeauLog.Infoln("Handle GenerateAuthDataRequest") + + // step 2: retrieve request + supiOrSuci := c.Param("supiOrSuci") + + // step 3: handle the message + response, problemDetails := GenerateAuthDataProcedure(authInfoReq, supiOrSuci) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} diff --git a/internal/sbi/processor/gpsi_to_supi_translation.go b/internal/sbi/processor/gpsi_to_supi_translation.go new file mode 100644 index 0000000..ab53f7c --- /dev/null +++ b/internal/sbi/processor/gpsi_to_supi_translation.go @@ -0,0 +1,41 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + +// GetIdTranslationResult - retrieve a UE's SUPI +func HTTPGetIdTranslationResult(c *gin.Context) { + //req.Query.Set("SupportedFeatures", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetIdTranslationResultRequest") + + // step 2: retrieve request + gpsi := c.Params.ByName("gpsi") + + // step 3: handle the message + response, problemDetails := getIdTranslationResultProcedure(gpsi) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go new file mode 100644 index 0000000..d982e95 --- /dev/null +++ b/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go @@ -0,0 +1,62 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// UpdateAmf3gppAccess - Update a parameter in the AMF registration for 3GPP access +func HTTPUpdateAmf3gppAccess(c *gin.Context) { + var amf3GppAccessRegistrationModification models.Amf3GppAccessRegistrationModification + + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amf3GppAccessRegistrationModification, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle UpdateAmf3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + + // step 3: handle the message + problemDetails := UpdateAmf3gppAccessProcedure(amf3GppAccessRegistrationModification, ueID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } + +} diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go new file mode 100644 index 0000000..92e91e5 --- /dev/null +++ b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go @@ -0,0 +1,61 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access +func HTTPUpdateAmfNon3gppAccess(c *gin.Context) { + var amfNon3GppAccessRegistrationModification models.AmfNon3GppAccessRegistrationModification + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amfNon3GppAccessRegistrationModification, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle UpdateAmfNon3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + + // step 3: handle the message + problemDetails := UpdateAmfNon3gppAccessProcedure(amfNon3GppAccessRegistrationModification, ueID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } + +} diff --git a/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go b/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go new file mode 100644 index 0000000..5cec75d --- /dev/null +++ b/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// Info - Nudm_Sdm Info service operation +func HTTPInfo(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go b/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go new file mode 100644 index 0000000..909536e --- /dev/null +++ b/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// PutUpuAck - Nudm_Sdm Info for UPU service operation +func HTTPPutUpuAck(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/retrieval_of_multiple_data_sets.go b/internal/sbi/processor/retrieval_of_multiple_data_sets.go new file mode 100644 index 0000000..32fce7c --- /dev/null +++ b/internal/sbi/processor/retrieval_of_multiple_data_sets.go @@ -0,0 +1,53 @@ +package processor + +import ( + "net/http" + "net/url" + "strings" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetSupi - retrieve multiple data sets +func HTTPGetSupi(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("dataset-names", c.Query("dataset-names")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetSupiRequest") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + dataSetNames := strings.Split(query.Get("dataset-names"), ",") + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := getSupiProcedure(supi, plmnID, dataSetNames, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} diff --git a/internal/sbi/processor/retrieval_of_shared_data.go b/internal/sbi/processor/retrieval_of_shared_data.go new file mode 100644 index 0000000..9d2013f --- /dev/null +++ b/internal/sbi/processor/retrieval_of_shared_data.go @@ -0,0 +1,38 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetSharedData - retrieve shared data +func HTTPGetSharedData(c *gin.Context) { + // step 1: log + logger.SdmLog.Infof("Handle GetSharedData") + + // step 2: retrieve request + sharedDataIds := c.QueryArray("shared-data-ids") + supportedFeatures := c.QueryArray("supported-features") + // step 3: handle the message + response, problemDetails := getSharedDataProcedure(sharedDataIds, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} diff --git a/internal/sbi/processor/session_management_subscription_data_retrieval.go b/internal/sbi/processor/session_management_subscription_data_retrieval.go new file mode 100644 index 0000000..1c7ab1c --- /dev/null +++ b/internal/sbi/processor/session_management_subscription_data_retrieval.go @@ -0,0 +1,55 @@ +package processor + +import ( + "net/http" + "net/url" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetSmData - retrieve a UE's Session Management Subscription Data +func HTTPGetSmData(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("dnn", c.Query("dnn")) + query.Set("single-nssai", c.Query("single-nssai")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetSmData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + Dnn := query.Get("dnn") + Snssai := query.Get("single-nssai") + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := getSmDataProcedure(supi, plmnID, Dnn, Snssai, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go new file mode 100644 index 0000000..1bd15e1 --- /dev/null +++ b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go @@ -0,0 +1,51 @@ +package processor + +import ( + "net/http" + "net/url" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetNssai - retrieve a UE's subscribed NSSAI +func HTTPGetNssai(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetNssai") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := getNssaiProcedure(supi, plmnID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/smf_deregistration.go b/internal/sbi/processor/smf_deregistration.go new file mode 100644 index 0000000..eb9d3f1 --- /dev/null +++ b/internal/sbi/processor/smf_deregistration.go @@ -0,0 +1,32 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// DeregistrationSmfRegistrations - delete an SMF registration +func HTTPDeregistrationSmfRegistrations(c *gin.Context) { + + // step 1: log + logger.UecmLog.Infof("Handle DeregistrationSmfRegistrations") + + // step 2: retrieve request + ueID := c.Params.ByName("ueId") + pduSessionID := c.Params.ByName("pduSessionId") + + // step 3: handle the message + problemDetails := DeregistrationSmfRegistrationsProcedure(ueID, pduSessionID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } + +} diff --git a/internal/sbi/processor/smf_registration.go b/internal/sbi/processor/smf_registration.go new file mode 100644 index 0000000..4554d7a --- /dev/null +++ b/internal/sbi/processor/smf_registration.go @@ -0,0 +1,71 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// RegistrationSmfRegistrations - register as SMF +func HTTPRegistrationSmfRegistrations(c *gin.Context) { + var smfRegistration models.SmfRegistration + + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&smfRegistration, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle RegistrationSmfRegistrations") + + // step 2: retrieve request + ueID := c.Params.ByName("ueId") + pduSessionID := c.Params.ByName("pduSessionId") + + // step 3: handle the message + header, response, problemDetails := RegistrationSmfRegistrationsProcedure(&smfRegistration, ueID, pduSessionID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + // all nil + c.Status(http.StatusNoContent) + return + } + +} diff --git a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go new file mode 100644 index 0000000..ba49bfd --- /dev/null +++ b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go @@ -0,0 +1,51 @@ +package processor + +import ( + "net/http" + "net/url" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data +func HTTPGetSmfSelectData(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetSmfSelectData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := getSmfSelectDataProcedure(supi, plmnID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/sms_management_subscription_data_retrieval.go b/internal/sbi/processor/sms_management_subscription_data_retrieval.go new file mode 100644 index 0000000..28eb043 --- /dev/null +++ b/internal/sbi/processor/sms_management_subscription_data_retrieval.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// GetSmsMngData - retrieve a UE's SMS Management Subscription Data +func HTTPGetSmsMngData(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/sms_subscription_data_retrieval.go b/internal/sbi/processor/sms_subscription_data_retrieval.go new file mode 100644 index 0000000..dd90686 --- /dev/null +++ b/internal/sbi/processor/sms_subscription_data_retrieval.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// GetSmsData - retrieve a UE's SMS Subscription Data +func HTTPGetSmsData(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go new file mode 100644 index 0000000..2facab5 --- /dev/null +++ b/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// GetSmsf3gppAccess - retrieve the SMSF registration for 3GPP access information +func HTTPGetSmsf3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go b/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go new file mode 100644 index 0000000..de771d0 --- /dev/null +++ b/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// DeregistrationSmsf3gppAccess - delete the SMSF registration for 3GPP access +func HTTPDeregistrationSmsf3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go b/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go new file mode 100644 index 0000000..343e9ea --- /dev/null +++ b/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// DeregistrationSmsfNon3gppAccess - delete SMSF registration for non 3GPP access +func HTTPDeregistrationSmsfNon3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go new file mode 100644 index 0000000..7135e12 --- /dev/null +++ b/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// GetSmsfNon3gppAccess - retrieve the SMSF registration for non-3GPP access information +func HTTPGetSmsfNon3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/smsf_registration_for3_gpp_access.go b/internal/sbi/processor/smsf_registration_for3_gpp_access.go new file mode 100644 index 0000000..9d194bc --- /dev/null +++ b/internal/sbi/processor/smsf_registration_for3_gpp_access.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// UpdateSMSFReg3GPP - register as SMSF for 3GPP access +func HTTPUpdateSMSFReg3GPP(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go b/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go new file mode 100644 index 0000000..8f7f957 --- /dev/null +++ b/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// RegistrationSmsfNon3gppAccess - register as SMSF for non-3GPP access +func HTTPRegistrationSmsfNon3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} diff --git a/internal/sbi/processor/subscription_creation.go b/internal/sbi/processor/subscription_creation.go new file mode 100644 index 0000000..26c5899 --- /dev/null +++ b/internal/sbi/processor/subscription_creation.go @@ -0,0 +1,68 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// Subscribe - subscribe to notifications +func HTTPSubscribe(c *gin.Context) { + var sdmSubscriptionReq models.SdmSubscription + + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sdmSubscriptionReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle Subscribe") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + + // step 3: handle the message + header, response, problemDetails := subscribeProcedure(&sdmSubscriptionReq, supi) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNotFound) + return + } +} diff --git a/internal/sbi/processor/subscription_creation_for_shared_data.go b/internal/sbi/processor/subscription_creation_for_shared_data.go new file mode 100644 index 0000000..16497c4 --- /dev/null +++ b/internal/sbi/processor/subscription_creation_for_shared_data.go @@ -0,0 +1,75 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/free5gc/util/httpwrapper" + "github.com/gin-gonic/gin" +) + +// SubscribeToSharedData - subscribe to notifications for shared data +func HTTPSubscribeToSharedData(c *gin.Context) { + var sharedDataSubsReq models.SdmSubscription + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sharedDataSubsReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle SubscribeToSharedData") + + // step 2: retrieve request + + // step 3: handle the message + header, response, problemDetails := subscribeToSharedDataProcedure(&sharedDataSubsReq) + + var rsp *httpwrapper.Response + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + // step 5: response + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/subscription_deletion.go b/internal/sbi/processor/subscription_deletion.go new file mode 100644 index 0000000..4c0e9cf --- /dev/null +++ b/internal/sbi/processor/subscription_deletion.go @@ -0,0 +1,30 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// Unsubscribe - unsubscribe from notifications +func HTTPUnsubscribe(c *gin.Context) { + + logger.SdmLog.Infof("Handle Unsubscribe") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + subscriptionID := c.Params.ByName("subscriptionId") + + // step 3: handle the message + problemDetails := unsubscribeProcedure(supi, subscriptionID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} diff --git a/internal/sbi/processor/subscription_deletion_for_shared_data.go b/internal/sbi/processor/subscription_deletion_for_shared_data.go new file mode 100644 index 0000000..90bb0e1 --- /dev/null +++ b/internal/sbi/processor/subscription_deletion_for_shared_data.go @@ -0,0 +1,28 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// UnsubscribeForSharedData - unsubscribe from notifications for shared data +func HTTPUnsubscribeForSharedData(c *gin.Context) { + logger.SdmLog.Infof("Handle UnsubscribeForSharedData") + + // step 2: retrieve request + subscriptionID := c.Params.ByName("subscriptionId") + // step 3: handle the message + problemDetails := unsubscribeForSharedDataProcedure(subscriptionID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } + +} diff --git a/internal/sbi/processor/subscription_modification.go b/internal/sbi/processor/subscription_modification.go new file mode 100644 index 0000000..563d528 --- /dev/null +++ b/internal/sbi/processor/subscription_modification.go @@ -0,0 +1,129 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// Modify - modify the subscription +func HTTPModify(c *gin.Context) { + var sdmSubsModificationReq models.SdmSubsModification + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sdmSubsModificationReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle Modify") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + subscriptionID := c.Params.ByName("subscriptionId") + + // step 3: handle the message + response, problemDetails := modifyProcedure(&sdmSubsModificationReq, supi, subscriptionID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// ModifyForSharedData - modify the subscription +func HTTPModifyForSharedData(c *gin.Context) { + var sharedDataSubscriptions models.SdmSubsModification + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sharedDataSubscriptions, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle ModifyForSharedData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + subscriptionID := c.Params.ByName("subscriptionId") + + // step 3: handle the message + response, problemDetails := modifyForSharedDataProcedure(&sharedDataSubscriptions, supi, subscriptionID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} diff --git a/internal/sbi/processor/trace_configuration_data_retrieval.go b/internal/sbi/processor/trace_configuration_data_retrieval.go new file mode 100644 index 0000000..e130c6c --- /dev/null +++ b/internal/sbi/processor/trace_configuration_data_retrieval.go @@ -0,0 +1,40 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetTraceData - retrieve a UE's Trace Configuration Data +func HTTPGetTraceData(c *gin.Context) { + // step 1: log + logger.SdmLog.Infof("Handle GetTraceData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnID := c.Query("plmn-id") + + // step 3: handle the message + response, problemDetails := getTraceDataProcedure(supi, plmnID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go new file mode 100644 index 0000000..53f3d01 --- /dev/null +++ b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go @@ -0,0 +1,41 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" + "github.com/gin-gonic/gin" +) + +// GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data +func HTTPGetUeContextInSmfData(c *gin.Context) { + + // step 1: log + logger.SdmLog.Infof("Handle GetUeContextInSmfData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + supportedFeatures := c.Query("supported-features") + + // step 3: handle the message + response, problemDetails := getUeContextInSmfDataProcedure(supi, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } + +} diff --git a/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go new file mode 100644 index 0000000..3d5a26e --- /dev/null +++ b/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go @@ -0,0 +1,12 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// GetUeContextInSmsfData - retrieve a UE's UE Context In SMSF Data +func HTTPGetUeContextInSmsfData(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} From 1e67491da2d9bd9f96a9753b5c1112cdceb9ab10 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Tue, 30 Apr 2024 07:22:13 +0000 Subject: [PATCH 05/23] feat: change func name http to handle, add (processor) method --- ...ccess_and_mobility_subscription_data_retrieval.go | 6 +++--- .../amf3_gpp_access_registration_info_retrieval.go | 2 +- ...mf_non3_gpp_access_registration_info_retrieval.go | 2 +- .../processor/amf_registration_for3_gpp_access.go | 2 +- .../amf_registration_for_non3_gpp_access.go | 2 +- internal/sbi/processor/confirm_auth.go | 2 +- .../sbi/processor/data_change_notification_to_nf.go | 2 +- internal/sbi/processor/ee_subscription.go | 6 +++--- internal/sbi/processor/generate_auth_data.go | 2 +- internal/sbi/processor/gpsi_to_supi_translation.go | 2 +- ...te_in_the_amf_registration_for_non3_gpp_access.go | 2 +- internal/sbi/processor/processor.go | 12 ++++++++++++ ...oviding_acknowledgement_of_steering_of_roaming.go | 2 +- ...viding_acknowledgement_of_ue_parameters_update.go | 2 +- .../sbi/processor/retrieval_of_multiple_data_sets.go | 2 +- internal/sbi/processor/retrieval_of_shared_data.go | 2 +- ...session_management_subscription_data_retrieval.go | 2 +- .../slice_selection_subscription_data_retrieval.go | 2 +- internal/sbi/processor/smf_deregistration.go | 2 +- internal/sbi/processor/smf_registration.go | 2 +- .../smf_selection_subscription_data_retrieval.go | 2 +- .../sms_management_subscription_data_retrieval.go | 2 +- .../sbi/processor/sms_subscription_data_retrieval.go | 2 +- .../smsf3_gpp_access_registration_info_retrieval.go | 2 +- .../processor/smsf_deregistration_for3_gpp_access.go | 2 +- .../smsf_deregistration_for_non3_gpp_access.go | 2 +- ...sf_non3_gpp_access_registration_info_retrieval.go | 2 +- .../processor/smsf_registration_for3_gpp_access.go | 2 +- .../smsf_registration_for_non3_gpp_access.go | 2 +- internal/sbi/processor/subscription_creation.go | 2 +- .../subscription_creation_for_shared_data.go | 2 +- internal/sbi/processor/subscription_data_update.go | 2 +- internal/sbi/processor/subscription_deletion.go | 2 +- .../subscription_deletion_for_shared_data.go | 2 +- internal/sbi/processor/subscription_modification.go | 2 +- .../processor/trace_configuration_data_retrieval.go | 2 +- .../processor/ue_context_in_smf_data_retrieval.go | 2 +- .../processor/ue_context_in_smsf_data_retrieval.go | 2 +- 38 files changed, 53 insertions(+), 41 deletions(-) create mode 100644 internal/sbi/processor/processor.go diff --git a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go index 5af9601..593b999 100644 --- a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go +++ b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go @@ -12,7 +12,7 @@ import ( ) // GetAmData - retrieve a UE's Access and Mobility Subscription Data -func HTTPGetAmData(c *gin.Context) { +func (p *Processor) HandleGetAmData(c *gin.Context) { var query url.Values query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("plmn-id")) @@ -23,7 +23,7 @@ func HTTPGetAmData(c *gin.Context) { // step 2: retrieve request supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := getPlmnIDStruct(query) + plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) return @@ -52,7 +52,7 @@ func HTTPGetAmData(c *gin.Context) { } } -func getPlmnIDStruct(queryParameters url.Values) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { +func (p *Processor) getPlmnIDStruct(queryParameters url.Values) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { if queryParameters["plmn-id"] != nil { plmnIDJson := queryParameters["plmn-id"][0] plmnIDStruct := &models.PlmnId{} diff --git a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go index 0d36ccf..dadd008 100644 --- a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go @@ -9,7 +9,7 @@ import ( ) // GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information -func HTTPGetAmf3gppAccess(c *gin.Context) { +func (p *Processor) HandleGetAmf3gppAccess(c *gin.Context) { // step 1: log logger.UecmLog.Infof("Handle HandleGetAmf3gppAccessRequest") diff --git a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go index b310882..ad57566 100644 --- a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go @@ -11,7 +11,7 @@ import ( ) // GetAmfNon3gppAccess - retrieve the AMF registration for non-3GPP access information -func HTTPGetAmfNon3gppAccess(c *gin.Context) { +func (p *Processor) HandleGetAmfNon3gppAccess(c *gin.Context) { // step 1: log logger.UecmLog.Infoln("Handle GetAmfNon3gppAccessRequest") diff --git a/internal/sbi/processor/amf_registration_for3_gpp_access.go b/internal/sbi/processor/amf_registration_for3_gpp_access.go index aa6382e..ee88ea7 100644 --- a/internal/sbi/processor/amf_registration_for3_gpp_access.go +++ b/internal/sbi/processor/amf_registration_for3_gpp_access.go @@ -10,7 +10,7 @@ import ( ) // RegistrationAmf3gppAccess - register as AMF for 3GPP access -func HTTPRegistrationAmf3gppAccess(c *gin.Context) { +func (p *Processor) HandleRegistrationAmf3gppAccess(c *gin.Context) { var amf3GppAccessRegistration models.Amf3GppAccessRegistration // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go index 8039d7b..d46227a 100644 --- a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go +++ b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go @@ -10,7 +10,7 @@ import ( ) // Register - register as AMF for non-3GPP access -func HTTPRegistrationAmfNon3gppAccess(c *gin.Context) { +func (p *Processor) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { var amfNon3GppAccessRegistration models.AmfNon3GppAccessRegistration // step 1: retrieve http request body diff --git a/internal/sbi/processor/confirm_auth.go b/internal/sbi/processor/confirm_auth.go index c2966d6..2df67db 100644 --- a/internal/sbi/processor/confirm_auth.go +++ b/internal/sbi/processor/confirm_auth.go @@ -11,7 +11,7 @@ import ( ) // ConfirmAuth - Create a new confirmation event -func HTTPConfirmAuth(c *gin.Context) { +func (p *Processor) HandleConfirmAuth(c *gin.Context) { var authEvent models.AuthEvent // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/processor/data_change_notification_to_nf.go b/internal/sbi/processor/data_change_notification_to_nf.go index 33ec788..c97ca73 100644 --- a/internal/sbi/processor/data_change_notification_to_nf.go +++ b/internal/sbi/processor/data_change_notification_to_nf.go @@ -10,7 +10,7 @@ import ( "github.com/free5gc/udm/internal/logger" ) -func HTTPDataChangeNotificationToNF(c *gin.Context) { +func (p *Processor) HandleDataChangeNotificationToNF(c *gin.Context) { var dataChangeNotify models.DataChangeNotify // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/processor/ee_subscription.go b/internal/sbi/processor/ee_subscription.go index 02c5d10..8a5ac75 100644 --- a/internal/sbi/processor/ee_subscription.go +++ b/internal/sbi/processor/ee_subscription.go @@ -20,7 +20,7 @@ import ( ) // HTTPCreateEeSubscription - Subscribe -func HTTPCreateEeSubscription(c *gin.Context) { +func (p *Processor) HandleCreateEeSubscription(c *gin.Context) { var eesubscription models.EeSubscription requestBody, err := c.GetRawData() @@ -71,7 +71,7 @@ func HTTPCreateEeSubscription(c *gin.Context) { } } -func HTTPDeleteEeSubscription(c *gin.Context) { +func (p *Processor) HandleDeleteEeSubscription(c *gin.Context) { ueIdentity := c.Params.ByName("ueIdentity") subscriptionID := c.Params.ByName("subscriptionId") @@ -81,7 +81,7 @@ func HTTPDeleteEeSubscription(c *gin.Context) { c.Status(http.StatusNoContent) } -func HTTPUpdateEeSubscription(c *gin.Context) { +func (p *Processor) HandleUpdateEeSubscription(c *gin.Context) { var patchList []models.PatchItem requestBody, err := c.GetRawData() diff --git a/internal/sbi/processor/generate_auth_data.go b/internal/sbi/processor/generate_auth_data.go index 18dec45..b570f1c 100644 --- a/internal/sbi/processor/generate_auth_data.go +++ b/internal/sbi/processor/generate_auth_data.go @@ -11,7 +11,7 @@ import ( ) // GenerateAuthData - Generate authentication data for the UE -func HttpGenerateAuthData(c *gin.Context) { +func (p *Processor) HandleGenerateAuthData(c *gin.Context) { var authInfoReq models.AuthenticationInfoRequest // step 1: retrieve http request body diff --git a/internal/sbi/processor/gpsi_to_supi_translation.go b/internal/sbi/processor/gpsi_to_supi_translation.go index ab53f7c..d9d30f2 100644 --- a/internal/sbi/processor/gpsi_to_supi_translation.go +++ b/internal/sbi/processor/gpsi_to_supi_translation.go @@ -10,7 +10,7 @@ import ( ) // GetIdTranslationResult - retrieve a UE's SUPI -func HTTPGetIdTranslationResult(c *gin.Context) { +func (p *Processor) HandleGetIdTranslationResult(c *gin.Context) { //req.Query.Set("SupportedFeatures", c.Query("supported-features")) // step 1: log diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go index 92e91e5..7444c74 100644 --- a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go +++ b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go @@ -10,7 +10,7 @@ import ( ) // UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access -func HTTPUpdateAmfNon3gppAccess(c *gin.Context) { +func (p *Processor) HandleUpdateAmfNon3gppAccess(c *gin.Context) { var amfNon3GppAccessRegistrationModification models.AmfNon3GppAccessRegistrationModification // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go new file mode 100644 index 0000000..b3583d1 --- /dev/null +++ b/internal/sbi/processor/processor.go @@ -0,0 +1,12 @@ +package processor + +import ( + "github.com/free5gc/udm/internal/repository" +) + +type Processor struct { +} + +func NewProcessor(runtimeRepo *repository.RuntimeRepository) *Processor { + return &Processor{} +} diff --git a/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go b/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go index 5cec75d..8689cb6 100644 --- a/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go +++ b/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go @@ -7,6 +7,6 @@ import ( ) // Info - Nudm_Sdm Info service operation -func HTTPInfo(c *gin.Context) { +func (p *Processor) HandleInfo(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go b/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go index 909536e..97d9b3a 100644 --- a/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go +++ b/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go @@ -7,6 +7,6 @@ import ( ) // PutUpuAck - Nudm_Sdm Info for UPU service operation -func HTTPPutUpuAck(c *gin.Context) { +func (p *Processor) HandlePutUpuAck(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/retrieval_of_multiple_data_sets.go b/internal/sbi/processor/retrieval_of_multiple_data_sets.go index 32fce7c..040b5e2 100644 --- a/internal/sbi/processor/retrieval_of_multiple_data_sets.go +++ b/internal/sbi/processor/retrieval_of_multiple_data_sets.go @@ -11,7 +11,7 @@ import ( ) // GetSupi - retrieve multiple data sets -func HTTPGetSupi(c *gin.Context) { +func (p *Processor) HandleGetSupi(c *gin.Context) { var query url.Values query.Set("plmn-id", c.Query("plmn-id")) query.Set("dataset-names", c.Query("dataset-names")) diff --git a/internal/sbi/processor/retrieval_of_shared_data.go b/internal/sbi/processor/retrieval_of_shared_data.go index 9d2013f..beca6eb 100644 --- a/internal/sbi/processor/retrieval_of_shared_data.go +++ b/internal/sbi/processor/retrieval_of_shared_data.go @@ -9,7 +9,7 @@ import ( ) // GetSharedData - retrieve shared data -func HTTPGetSharedData(c *gin.Context) { +func (p *Processor) HandleGetSharedData(c *gin.Context) { // step 1: log logger.SdmLog.Infof("Handle GetSharedData") diff --git a/internal/sbi/processor/session_management_subscription_data_retrieval.go b/internal/sbi/processor/session_management_subscription_data_retrieval.go index 1c7ab1c..c02c771 100644 --- a/internal/sbi/processor/session_management_subscription_data_retrieval.go +++ b/internal/sbi/processor/session_management_subscription_data_retrieval.go @@ -10,7 +10,7 @@ import ( ) // GetSmData - retrieve a UE's Session Management Subscription Data -func HTTPGetSmData(c *gin.Context) { +func (p *Processor) HandleGetSmData(c *gin.Context) { var query url.Values query.Set("plmn-id", c.Query("plmn-id")) query.Set("dnn", c.Query("dnn")) diff --git a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go index 1bd15e1..a4694a3 100644 --- a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go +++ b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go @@ -10,7 +10,7 @@ import ( ) // GetNssai - retrieve a UE's subscribed NSSAI -func HTTPGetNssai(c *gin.Context) { +func (p *Processor) HandleGetNssai(c *gin.Context) { var query url.Values query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("supported-features")) diff --git a/internal/sbi/processor/smf_deregistration.go b/internal/sbi/processor/smf_deregistration.go index eb9d3f1..3d4428b 100644 --- a/internal/sbi/processor/smf_deregistration.go +++ b/internal/sbi/processor/smf_deregistration.go @@ -8,7 +8,7 @@ import ( ) // DeregistrationSmfRegistrations - delete an SMF registration -func HTTPDeregistrationSmfRegistrations(c *gin.Context) { +func (p *Processor) HandleDeregistrationSmfRegistrations(c *gin.Context) { // step 1: log logger.UecmLog.Infof("Handle DeregistrationSmfRegistrations") diff --git a/internal/sbi/processor/smf_registration.go b/internal/sbi/processor/smf_registration.go index 4554d7a..fad963a 100644 --- a/internal/sbi/processor/smf_registration.go +++ b/internal/sbi/processor/smf_registration.go @@ -10,7 +10,7 @@ import ( ) // RegistrationSmfRegistrations - register as SMF -func HTTPRegistrationSmfRegistrations(c *gin.Context) { +func (p *Processor) HandleRegistrationSmfRegistrations(c *gin.Context) { var smfRegistration models.SmfRegistration // step 1: retrieve http request body diff --git a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go index ba49bfd..abeee75 100644 --- a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go +++ b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go @@ -10,7 +10,7 @@ import ( ) // GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data -func HTTPGetSmfSelectData(c *gin.Context) { +func (p *Processor) HandleGetSmfSelectData(c *gin.Context) { var query url.Values query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("supported-features")) diff --git a/internal/sbi/processor/sms_management_subscription_data_retrieval.go b/internal/sbi/processor/sms_management_subscription_data_retrieval.go index 28eb043..771112c 100644 --- a/internal/sbi/processor/sms_management_subscription_data_retrieval.go +++ b/internal/sbi/processor/sms_management_subscription_data_retrieval.go @@ -7,6 +7,6 @@ import ( ) // GetSmsMngData - retrieve a UE's SMS Management Subscription Data -func HTTPGetSmsMngData(c *gin.Context) { +func (p *Processor) HandleGetSmsMngData(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/sms_subscription_data_retrieval.go b/internal/sbi/processor/sms_subscription_data_retrieval.go index dd90686..66c6567 100644 --- a/internal/sbi/processor/sms_subscription_data_retrieval.go +++ b/internal/sbi/processor/sms_subscription_data_retrieval.go @@ -7,6 +7,6 @@ import ( ) // GetSmsData - retrieve a UE's SMS Subscription Data -func HTTPGetSmsData(c *gin.Context) { +func (p *Processor) HandleGetSmsData(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go index 2facab5..72a6909 100644 --- a/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go @@ -7,6 +7,6 @@ import ( ) // GetSmsf3gppAccess - retrieve the SMSF registration for 3GPP access information -func HTTPGetSmsf3gppAccess(c *gin.Context) { +func (p *Processor) HandleGetSmsf3gppAccess(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go b/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go index de771d0..a0263e7 100644 --- a/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go +++ b/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go @@ -7,6 +7,6 @@ import ( ) // DeregistrationSmsf3gppAccess - delete the SMSF registration for 3GPP access -func HTTPDeregistrationSmsf3gppAccess(c *gin.Context) { +func (p *Processor) HandleDeregistrationSmsf3gppAccess(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go b/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go index 343e9ea..4a12cf3 100644 --- a/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go +++ b/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go @@ -7,6 +7,6 @@ import ( ) // DeregistrationSmsfNon3gppAccess - delete SMSF registration for non 3GPP access -func HTTPDeregistrationSmsfNon3gppAccess(c *gin.Context) { +func (p *Processor) HandleDeregistrationSmsfNon3gppAccess(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go index 7135e12..492d071 100644 --- a/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go @@ -7,6 +7,6 @@ import ( ) // GetSmsfNon3gppAccess - retrieve the SMSF registration for non-3GPP access information -func HTTPGetSmsfNon3gppAccess(c *gin.Context) { +func (p *Processor) HandleGetSmsfNon3gppAccess(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/smsf_registration_for3_gpp_access.go b/internal/sbi/processor/smsf_registration_for3_gpp_access.go index 9d194bc..ab2a13b 100644 --- a/internal/sbi/processor/smsf_registration_for3_gpp_access.go +++ b/internal/sbi/processor/smsf_registration_for3_gpp_access.go @@ -7,6 +7,6 @@ import ( ) // UpdateSMSFReg3GPP - register as SMSF for 3GPP access -func HTTPUpdateSMSFReg3GPP(c *gin.Context) { +func (p *Processor) HandleUpdateSMSFReg3GPP(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go b/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go index 8f7f957..65e2023 100644 --- a/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go +++ b/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go @@ -7,6 +7,6 @@ import ( ) // RegistrationSmsfNon3gppAccess - register as SMSF for non-3GPP access -func HTTPRegistrationSmsfNon3gppAccess(c *gin.Context) { +func (p *Processor) HandleRegistrationSmsfNon3gppAccess(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } diff --git a/internal/sbi/processor/subscription_creation.go b/internal/sbi/processor/subscription_creation.go index 26c5899..cbd1ca9 100644 --- a/internal/sbi/processor/subscription_creation.go +++ b/internal/sbi/processor/subscription_creation.go @@ -10,7 +10,7 @@ import ( ) // Subscribe - subscribe to notifications -func HTTPSubscribe(c *gin.Context) { +func (p *Processor) HandleSubscribe(c *gin.Context) { var sdmSubscriptionReq models.SdmSubscription // step 1: retrieve http request body diff --git a/internal/sbi/processor/subscription_creation_for_shared_data.go b/internal/sbi/processor/subscription_creation_for_shared_data.go index 16497c4..fd594c9 100644 --- a/internal/sbi/processor/subscription_creation_for_shared_data.go +++ b/internal/sbi/processor/subscription_creation_for_shared_data.go @@ -11,7 +11,7 @@ import ( ) // SubscribeToSharedData - subscribe to notifications for shared data -func HTTPSubscribeToSharedData(c *gin.Context) { +func (p *Processor) HandleSubscribeToSharedData(c *gin.Context) { var sharedDataSubsReq models.SdmSubscription // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/processor/subscription_data_update.go b/internal/sbi/processor/subscription_data_update.go index 770de17..55c430f 100644 --- a/internal/sbi/processor/subscription_data_update.go +++ b/internal/sbi/processor/subscription_data_update.go @@ -10,7 +10,7 @@ import ( "github.com/free5gc/udm/internal/logger" ) -func HTTPUpdate(c *gin.Context) { +func (p *Processor) HandleUpdate(c *gin.Context) { var ppDataReq models.PpData // step 1: retrieve http request body diff --git a/internal/sbi/processor/subscription_deletion.go b/internal/sbi/processor/subscription_deletion.go index 4c0e9cf..e929ebb 100644 --- a/internal/sbi/processor/subscription_deletion.go +++ b/internal/sbi/processor/subscription_deletion.go @@ -8,7 +8,7 @@ import ( ) // Unsubscribe - unsubscribe from notifications -func HTTPUnsubscribe(c *gin.Context) { +func (p *Processor) HandleUnsubscribe(c *gin.Context) { logger.SdmLog.Infof("Handle Unsubscribe") diff --git a/internal/sbi/processor/subscription_deletion_for_shared_data.go b/internal/sbi/processor/subscription_deletion_for_shared_data.go index 90bb0e1..3f425a3 100644 --- a/internal/sbi/processor/subscription_deletion_for_shared_data.go +++ b/internal/sbi/processor/subscription_deletion_for_shared_data.go @@ -8,7 +8,7 @@ import ( ) // UnsubscribeForSharedData - unsubscribe from notifications for shared data -func HTTPUnsubscribeForSharedData(c *gin.Context) { +func (p *Processor) HandleUnsubscribeForSharedData(c *gin.Context) { logger.SdmLog.Infof("Handle UnsubscribeForSharedData") // step 2: retrieve request diff --git a/internal/sbi/processor/subscription_modification.go b/internal/sbi/processor/subscription_modification.go index 563d528..364f4ba 100644 --- a/internal/sbi/processor/subscription_modification.go +++ b/internal/sbi/processor/subscription_modification.go @@ -10,7 +10,7 @@ import ( ) // Modify - modify the subscription -func HTTPModify(c *gin.Context) { +func (p *Processor) HandleModify(c *gin.Context) { var sdmSubsModificationReq models.SdmSubsModification // step 1: retrieve http request body requestBody, err := c.GetRawData() diff --git a/internal/sbi/processor/trace_configuration_data_retrieval.go b/internal/sbi/processor/trace_configuration_data_retrieval.go index e130c6c..0d5cfc8 100644 --- a/internal/sbi/processor/trace_configuration_data_retrieval.go +++ b/internal/sbi/processor/trace_configuration_data_retrieval.go @@ -9,7 +9,7 @@ import ( ) // GetTraceData - retrieve a UE's Trace Configuration Data -func HTTPGetTraceData(c *gin.Context) { +func (p *Processor) HandleGetTraceData(c *gin.Context) { // step 1: log logger.SdmLog.Infof("Handle GetTraceData") diff --git a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go index 53f3d01..525df2c 100644 --- a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go +++ b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go @@ -9,7 +9,7 @@ import ( ) // GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data -func HTTPGetUeContextInSmfData(c *gin.Context) { +func (p *Processor) HandleGetUeContextInSmfData(c *gin.Context) { // step 1: log logger.SdmLog.Infof("Handle GetUeContextInSmfData") diff --git a/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go index 3d5a26e..a4ded32 100644 --- a/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go +++ b/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go @@ -7,6 +7,6 @@ import ( ) // GetUeContextInSmsfData - retrieve a UE's UE Context In SMSF Data -func HTTPGetUeContextInSmsfData(c *gin.Context) { +func (p *Processor) HandleGetUeContextInSmsfData(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } From 2d42b1a89f7aa851786d22f172eaa99adae11509 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Mon, 13 May 2024 08:17:11 +0000 Subject: [PATCH 06/23] feat: refactor server, processsor, consumer, router --- cmd/main.go | 18 +- go.mod | 2 +- go.sum | 2 + internal/sbi/api_eventexposure.go | 38 +++ internal/sbi/api_httpcallback.go | 21 ++ internal/sbi/api_parameterprovision.go | 21 ++ internal/sbi/api_subscriberdatamanagement.go | 12 + internal/sbi/api_ueauthentication.go | 21 ++ internal/sbi/api_uecontextmanagement.go | 112 +++++++ internal/sbi/consumer/consumer.go | 18 +- internal/sbi/consumer/nrf_service.go | 6 +- internal/sbi/consumer/udm_service.go | 4 +- internal/sbi/consumer/udr_service.go | 276 +++++++++++++++++- ...nd_mobility_subscription_data_retrieval.go | 2 +- ..._gpp_access_registration_info_retrieval.go | 2 +- ..._gpp_access_registration_info_retrieval.go | 3 +- .../amf_registration_for3_gpp_access.go | 2 +- .../amf_registration_for_non3_gpp_access.go | 2 +- internal/sbi/processor/confirm_auth.go | 2 +- .../data_change_notification_to_nf.go | 2 +- internal/sbi/processor/ee_subscription.go | 6 +- internal/sbi/processor/generate_auth_data.go | 2 +- .../sbi/processor/gpsi_to_supi_translation.go | 2 +- internal/sbi/processor/index.go | 11 + ...in_the_amf_registration_for3_gpp_access.go | 4 +- ...he_amf_registration_for_non3_gpp_access.go | 2 +- internal/sbi/processor/processor.go | 22 +- .../retrieval_of_multiple_data_sets.go | 4 +- .../sbi/processor/retrieval_of_shared_data.go | 2 +- ..._management_subscription_data_retrieval.go | 4 +- ...e_selection_subscription_data_retrieval.go | 4 +- internal/sbi/processor/smf_deregistration.go | 2 +- internal/sbi/processor/smf_registration.go | 2 +- ...f_selection_subscription_data_retrieval.go | 4 +- .../sbi/processor/subscription_creation.go | 2 +- .../subscription_creation_for_shared_data.go | 5 +- .../sbi/processor/subscription_data_update.go | 2 +- .../sbi/processor/subscription_deletion.go | 2 +- .../subscription_deletion_for_shared_data.go | 2 +- .../processor/subscription_modification.go | 6 +- .../trace_configuration_data_retrieval.go | 2 +- .../ue_context_in_smf_data_retrieval.go | 2 +- internal/sbi/processor/ueau_route.go | 18 ++ internal/sbi/router.go | 74 +++++ internal/sbi/server.go | 242 ++++++++++++--- pkg/app/app.go | 18 ++ pkg/factory/config.go | 54 ++++ pkg/service/init.go | 145 ++++++--- 48 files changed, 1059 insertions(+), 152 deletions(-) create mode 100644 internal/sbi/api_eventexposure.go create mode 100644 internal/sbi/api_httpcallback.go create mode 100644 internal/sbi/api_parameterprovision.go create mode 100644 internal/sbi/api_subscriberdatamanagement.go create mode 100644 internal/sbi/api_ueauthentication.go create mode 100644 internal/sbi/api_uecontextmanagement.go create mode 100644 internal/sbi/processor/index.go create mode 100644 internal/sbi/processor/ueau_route.go create mode 100644 internal/sbi/router.go create mode 100644 pkg/app/app.go diff --git a/cmd/main.go b/cmd/main.go index 1ce895d..7873784 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,9 +1,12 @@ package main import ( + "context" "os" + "os/signal" "path/filepath" "runtime/debug" + "syscall" "github.com/urfave/cli" @@ -52,18 +55,29 @@ func action(cliCtx *cli.Context) error { logger.MainLog.Infoln("UDM version: ", version.GetVersion()) + ctx, cancel := context.WithCancel(context.Background()) + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + + go func() { + <-sigCh // Wait for interrupt signal to gracefully shutdown + cancel() // Notify each goroutine and wait them stopped + }() + cfg, err := factory.ReadConfig(cliCtx.String("config")) if err != nil { return err } factory.UdmConfig = cfg - udm, err := service.NewApp(cfg) + + udm, err := service.NewApp(ctx, cfg, tlsKeyLogPath) if err != nil { return err } UDM = udm - udm.Start(tlsKeyLogPath) + udm.Start() + UDM.WaitRoutineStopped() return nil } diff --git a/go.mod b/go.mod index 9210590..05cd775 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/free5gc/udm -go 1.17 +go 1.21 require ( github.com/antihax/optional v1.0.0 diff --git a/go.sum b/go.sum index dfe1722..eff2cca 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,7 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= @@ -42,6 +43,7 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/internal/sbi/api_eventexposure.go b/internal/sbi/api_eventexposure.go new file mode 100644 index 0000000..b3cdefa --- /dev/null +++ b/internal/sbi/api_eventexposure.go @@ -0,0 +1,38 @@ +package sbi + +import ( + "strings" +) + +func (s *Server) getEventExposureRoutes() []Route { + return []Route{ + { + "Index", + "GET", + "/", + s.Processor().HandleIndex, + }, + + { + "HTTPCreateEeSubscription", + strings.ToUpper("Post"), + "/:ueIdentity/ee-subscriptions", + s.Processor().HandleCreateEeSubscription, + }, + + { + "HTTPDeleteEeSubscription", + strings.ToUpper("Delete"), + "/:ueIdentity/ee-subscriptions/:subscriptionId", + s.Processor().HandleDeleteEeSubscription, + }, + + { + "HTTPUpdateEeSubscription", + strings.ToUpper("Patch"), + "/:ueIdentity/ee-subscriptions/:subscriptionId", + s.Processor().HandleUpdateEeSubscription, + }, + } + +} diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go new file mode 100644 index 0000000..5d149e8 --- /dev/null +++ b/internal/sbi/api_httpcallback.go @@ -0,0 +1,21 @@ +package sbi + +import "strings" + +func (s *Server) getHttpCallBackRoutes() []Route { + return []Route{ + { + "Index", + "GET", + "/", + s.Processor().HandleIndex, + }, + + { + "DataChangeNotificationToNF", + strings.ToUpper("Post"), + "/sdm-subscriptions", + s.Processor().HandleDataChangeNotificationToNF, + }, + } +} diff --git a/internal/sbi/api_parameterprovision.go b/internal/sbi/api_parameterprovision.go new file mode 100644 index 0000000..3d627d1 --- /dev/null +++ b/internal/sbi/api_parameterprovision.go @@ -0,0 +1,21 @@ +package sbi + +import "strings" + +func (s *Server) getParameterProvisionRoutes() []Route { + return []Route{ + { + "Index", + "GET", + "/", + s.Processor().HandleIndex, + }, + + { + "Update", + strings.ToUpper("Patch"), + "/:gpsi/pp-data", + s.Processor().HandleUpdate, + }, + } +} diff --git a/internal/sbi/api_subscriberdatamanagement.go b/internal/sbi/api_subscriberdatamanagement.go new file mode 100644 index 0000000..a7c0361 --- /dev/null +++ b/internal/sbi/api_subscriberdatamanagement.go @@ -0,0 +1,12 @@ +package sbi + +func (s *Server) getSubscriberDataManagementRoutes() []Route { + return []Route{ + { + "Index", + "GET", + "/", + s.Processor().HandleIndex, + }, + } +} diff --git a/internal/sbi/api_ueauthentication.go b/internal/sbi/api_ueauthentication.go new file mode 100644 index 0000000..6b490ce --- /dev/null +++ b/internal/sbi/api_ueauthentication.go @@ -0,0 +1,21 @@ +package sbi + +import "strings" + +func (s *Server) getUEAuthenticationRoutes() []Route { + return []Route{ + { + "Index", + "GET", + "/", + s.Processor().HandleIndex, + }, + + { + "ConfirmAuth", + strings.ToUpper("Post"), + "/:supi/auth-events", + s.Processor().HandleConfirmAuth, + }, + } +} diff --git a/internal/sbi/api_uecontextmanagement.go b/internal/sbi/api_uecontextmanagement.go new file mode 100644 index 0000000..5d87060 --- /dev/null +++ b/internal/sbi/api_uecontextmanagement.go @@ -0,0 +1,112 @@ +package sbi + +import "strings" + +func (s *Server) getUEContextManagementRoutes() []Route { + return []Route{ + { + "Index", + "GET", + "/", + s.Processor().HandleIndex, + }, + + { + "GetAmf3gppAccess", + strings.ToUpper("Get"), + "/:ueId/registrations/amf-3gpp-access", + s.Processor().HandleGetAmf3gppAccess, + }, + + { + "GetAmfNon3gppAccess", + strings.ToUpper("Get"), + "/:ueId/registrations/amf-non-3gpp-access", + s.Processor().HandleGetAmfNon3gppAccess, + }, + + { + "RegistrationAmf3gppAccess", + strings.ToUpper("Put"), + "/:ueId/registrations/amf-3gpp-access", + s.Processor().HandleRegistrationAmf3gppAccess, + }, + + { + "Register", + strings.ToUpper("Put"), + "/:ueId/registrations/amf-non-3gpp-access", + s.Processor().HandleRegistrationAmfNon3gppAccess, + }, + + { + "UpdateAmf3gppAccess", + strings.ToUpper("Patch"), + "/:ueId/registrations/amf-3gpp-access", + s.Processor().HandleUpdateAmf3gppAccess, + }, + + { + "UpdateAmfNon3gppAccess", + strings.ToUpper("Patch"), + "/:ueId/registrations/amf-non-3gpp-access", + s.Processor().HandleUpdateAmfNon3gppAccess, + }, + + { + "DeregistrationSmfRegistrations", + strings.ToUpper("Delete"), + "/:ueId/registrations/smf-registrations/:pduSessionId", + s.Processor().HandleDeregistrationSmfRegistrations, + }, + + { + "RegistrationSmfRegistrations", + strings.ToUpper("Put"), + "/:ueId/registrations/smf-registrations/:pduSessionId", + s.Processor().HandleRegistrationSmfRegistrations, + }, + + { + "GetSmsf3gppAccess", + strings.ToUpper("Get"), + "/:ueId/registrations/smsf-3gpp-access", + s.Processor().HandleGetSmsf3gppAccess, + }, + + { + "DeregistrationSmsf3gppAccess", + strings.ToUpper("Delete"), + "/:ueId/registrations/smsf-3gpp-access", + s.Processor().HandleDeregistrationSmsf3gppAccess, + }, + + { + "DeregistrationSmsfNon3gppAccess", + strings.ToUpper("Delete"), + "/:ueId/registrations/smsf-non-3gpp-access", + s.Processor().HandleDeregistrationSmsfNon3gppAccess, + }, + + { + "GetSmsfNon3gppAccess", + strings.ToUpper("Get"), + "/:ueId/registrations/smsf-non-3gpp-access", + s.Processor().HandleGetSmsfNon3gppAccess, + }, + + { + "UpdateSMSFReg3GPP", + strings.ToUpper("Put"), + "/:ueId/registrations/smsf-3gpp-access", + s.Processor().HandleUpdateSMSFReg3GPP, + }, + + { + "RegistrationSmsfNon3gppAccess", + strings.ToUpper("Put"), + "/:ueId/registrations/smsf-non-3gpp-access", + s.Processor().HandleRegistrationSmsfNon3gppAccess, + }, + } +} diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go index c17d8b6..64d9e71 100644 --- a/internal/sbi/consumer/consumer.go +++ b/internal/sbi/consumer/consumer.go @@ -1,26 +1,20 @@ package consumer import ( - "context" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" "github.com/free5gc/openapi/Nnrf_NFManagement" "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" "github.com/free5gc/openapi/Nudm_UEContextManagement" "github.com/free5gc/openapi/Nudr_DataRepository" - "github.com/free5gc/udm/pkg/factory" - - udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/pkg/app" ) -type udm interface { - Config() *factory.Config - Context() *udm_context.UDMContext - CancelContext() context.Context +type ConsumerUdm interface { + app.App } type Consumer struct { - udm + ConsumerUdm // consumer services *nnrfService @@ -28,9 +22,9 @@ type Consumer struct { *nudmService } -func NewConsumer(udm udm) (*Consumer, error) { +func NewConsumer(udm ConsumerUdm) (*Consumer, error) { c := &Consumer{ - udm: udm, + ConsumerUdm: udm, } c.nnrfService = &nnrfService{ diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index e4b1cb3..1371bf0 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -75,7 +75,7 @@ func (s *nnrfService) SendSearchNFInstances( nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( *models.SearchResult, error) { // Set client and set url - chfContext := s.consumer.udm.Context() + chfContext := s.consumer.Context() client := s.getNFDiscClient(chfContext.NrfUri) @@ -108,7 +108,7 @@ func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.Problem return pd, err } - udmContext := s.consumer.udm.Context() + udmContext := s.consumer.Context() client := s.getNFManagementClient(udmContext.NrfUri) var res *http.Response @@ -135,7 +135,7 @@ func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.Problem func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( resouceNrfUri string, retrieveNfInstanceID string, err error) { - udmContext := s.consumer.udm.Context() + udmContext := s.consumer.Context() client := s.getNFManagementClient(udmContext.NrfUri) nfProfile, err := s.buildNfProfile(udmContext) if err != nil { diff --git a/internal/sbi/consumer/udm_service.go b/internal/sbi/consumer/udm_service.go index 0ee2c48..6359af4 100644 --- a/internal/sbi/consumer/udm_service.go +++ b/internal/sbi/consumer/udm_service.go @@ -66,7 +66,7 @@ func (s *nudmService) getUECMClient(uri string) *Nudm_UEContextManagement.APICli return client } -func (s *nudmService) subscribeToSharedDataProcedure(sdmSubscription *models.SdmSubscription) ( +func (s *nudmService) SubscribeToSharedDataProcedure(sdmSubscription *models.SdmSubscription) ( header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) @@ -121,7 +121,7 @@ func (s *nudmService) subscribeToSharedDataProcedure(sdmSubscription *models.Sdm } } -func (s *nudmService) unsubscribeForSharedDataProcedure(subscriptionID string) *models.ProblemDetails { +func (s *nudmService) UnsubscribeForSharedDataProcedure(subscriptionID string) *models.ProblemDetails { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { return pd diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go index 09d4a1c..14919bf 100644 --- a/internal/sbi/consumer/udr_service.go +++ b/internal/sbi/consumer/udr_service.go @@ -168,6 +168,204 @@ func (s *nudrService) strictHex(ss string, n int) string { } } +// EE service +func (s *nudrService) CreateEeSubscriptionProcedure(ueIdentity string, + eesubscription models.EeSubscription, +) (*models.CreatedEeSubscription, *models.ProblemDetails) { + udmSelf := udm_context.GetSelf() + logger.EeLog.Debugf("udIdentity: %s", ueIdentity) + switch { + // GPSI (MSISDN identifier) represents a single UE + case strings.HasPrefix(ueIdentity, "msisdn-"): + fallthrough + // GPSI (External identifier) represents a single UE + case strings.HasPrefix(ueIdentity, "extid-"): + if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { + id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() + if err != nil { + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + return nil, problemDetails + } + + subscriptionID := strconv.Itoa(int(id)) + ue.EeSubscriptions[subscriptionID] = &eesubscription + createdEeSubscription := &models.CreatedEeSubscription{ + EeSubscription: &eesubscription, + } + return createdEeSubscription, nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + return nil, problemDetails + } + // external groupID represents a group of UEs + case strings.HasPrefix(ueIdentity, "extgroupid-"): + id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() + if err != nil { + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + return nil, problemDetails + } + subscriptionID := strconv.Itoa(int(id)) + createdEeSubscription := &models.CreatedEeSubscription{ + EeSubscription: &eesubscription, + } + + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if ue.ExternalGroupID == ueIdentity { + ue.EeSubscriptions[subscriptionID] = &eesubscription + } + return true + }) + return createdEeSubscription, nil + // represents any UEs + case ueIdentity == "anyUE": + id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() + if err != nil { + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + return nil, problemDetails + } + subscriptionID := strconv.Itoa(int(id)) + createdEeSubscription := &models.CreatedEeSubscription{ + EeSubscription: &eesubscription, + } + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + ue.EeSubscriptions[subscriptionID] = &eesubscription + return true + }) + return createdEeSubscription, nil + default: + problemDetails := &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "MANDATORY_IE_INCORRECT", + InvalidParams: []models.InvalidParam{ + { + Param: "ueIdentity", + Reason: "incorrect format", + }, + }, + } + return nil, problemDetails + } +} + +// TODO: complete this procedure based on TS 29503 5.5 +func (s *nudrService) DeleteEeSubscriptionProcedure(ueIdentity string, subscriptionID string) { + udmSelf := udm_context.GetSelf() + + switch { + case strings.HasPrefix(ueIdentity, "msisdn-"): + fallthrough + case strings.HasPrefix(ueIdentity, "extid-"): + if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { + delete(ue.EeSubscriptions, subscriptionID) + } + case strings.HasPrefix(ueIdentity, "extgroupid-"): + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if ue.ExternalGroupID == ueIdentity { + delete(ue.EeSubscriptions, subscriptionID) + } + return true + }) + case ueIdentity == "anyUE": + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + delete(ue.EeSubscriptions, subscriptionID) + return true + }) + } + if id, err := strconv.ParseInt(subscriptionID, 10, 64); err != nil { + logger.EeLog.Warnf("subscriptionID covert type error: %+v", err) + } else { + udmSelf.EeSubscriptionIDGenerator.FreeID(id) + } +} + +// TODO: complete this procedure based on TS 29503 5.5 +func (s *nudrService) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptionID string, + patchList []models.PatchItem, +) *models.ProblemDetails { + udmSelf := udm_context.GetSelf() + + switch { + case strings.HasPrefix(ueIdentity, "msisdn-"): + fallthrough + case strings.HasPrefix(ueIdentity, "extid-"): + if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { + if _, ok := ue.EeSubscriptions[subscriptionID]; ok { + for _, patchItem := range patchList { + logger.EeLog.Debugf("patch item: %+v", patchItem) + // TODO: patch the Eesubscription + } + return nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "SUBSCRIPTION_NOT_FOUND", + } + return problemDetails + } + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "SUBSCRIPTION_NOT_FOUND", + } + return problemDetails + } + case strings.HasPrefix(ueIdentity, "extgroupid-"): + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if ue.ExternalGroupID == ueIdentity { + if _, ok := ue.EeSubscriptions[subscriptionID]; ok { + for _, patchItem := range patchList { + logger.EeLog.Debugf("patch item: %+v", patchItem) + // TODO: patch the Eesubscription + } + } + } + return true + }) + return nil + case ueIdentity == "anyUE": + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if _, ok := ue.EeSubscriptions[subscriptionID]; ok { + for _, patchItem := range patchList { + logger.EeLog.Debugf("patch item: %+v", patchItem) + // TODO: patch the Eesubscription + } + } + return true + }) + return nil + default: + problemDetails := &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "MANDATORY_IE_INCORRECT", + InvalidParams: []models.InvalidParam{ + { + Param: "ueIdentity", + Reason: "incorrect format", + }, + }, + } + return problemDetails + } +} + func (s *nudrService) ConfirmAuthDataProcedure(authEvent models.AuthEvent, supi string) (problemDetails *models.ProblemDetails) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { @@ -667,7 +865,7 @@ func (s *nudrService) UpdateProcedure(updateRequest models.PpData, gpsi string) return nil } -func (s *nudrService) getAmDataProcedure(supi string, plmnID string, supportedFeatures string) ( +func (s *nudrService) GetAmDataProcedure(supi string, plmnID string, supportedFeatures string) ( response *models.AccessAndMobilitySubscriptionData, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -720,7 +918,7 @@ func (s *nudrService) getAmDataProcedure(supi string, plmnID string, supportedFe } } -func (s *nudrService) getIdTranslationResultProcedure(gpsi string) (response *models.IdTranslationResult, +func (s *nudrService) GetIdTranslationResultProcedure(gpsi string) (response *models.IdTranslationResult, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -783,7 +981,7 @@ func (s *nudrService) getIdTranslationResultProcedure(gpsi string) (response *mo } } -func (s *nudrService) getSupiProcedure(supi string, plmnID string, dataSetNames []string, supportedFeatures string) ( +func (s *nudrService) GetSupiProcedure(supi string, plmnID string, dataSetNames []string, supportedFeatures string) ( response *models.SubscriptionDataSets, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1065,7 +1263,7 @@ func (s *nudrService) getSupiProcedure(supi string, plmnID string, dataSetNames return &subscriptionDataSets, nil } -func (s *nudrService) getSharedDataProcedure(sharedDataIds []string, supportedFeatures string) ( +func (s *nudrService) GetSharedDataProcedure(sharedDataIds []string, supportedFeatures string) ( response []models.SharedData, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1117,7 +1315,7 @@ func (s *nudrService) getSharedDataProcedure(sharedDataIds []string, supportedFe } } -func (s *nudrService) getSmDataProcedure(supi string, plmnID string, Dnn string, Snssai string, supportedFeatures string) ( +func (s *nudrService) GetSmDataProcedure(supi string, plmnID string, Dnn string, Snssai string, supportedFeatures string) ( response interface{}, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1201,7 +1399,7 @@ func (s *nudrService) getSmDataProcedure(supi string, plmnID string, Dnn string, } } -func (s *nudrService) getNssaiProcedure(supi string, plmnID string, supportedFeatures string) ( +func (s *nudrService) GetNssaiProcedure(supi string, plmnID string, supportedFeatures string) ( *models.Nssai, *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1258,7 +1456,7 @@ func (s *nudrService) getNssaiProcedure(supi string, plmnID string, supportedFea } } -func (s *nudrService) getSmfSelectDataProcedure(supi string, plmnID string, supportedFeatures string) ( +func (s *nudrService) GetSmfSelectDataProcedure(supi string, plmnID string, supportedFeatures string) ( response *models.SmfSelectionSubscriptionData, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1316,7 +1514,7 @@ func (s *nudrService) getSmfSelectDataProcedure(supi string, plmnID string, supp } } -func (s *nudrService) subscribeProcedure(sdmSubscription *models.SdmSubscription, supi string) ( +func (s *nudrService) SubscribeProcedure(sdmSubscription *models.SdmSubscription, supi string) ( header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1375,7 +1573,7 @@ func (s *nudrService) subscribeProcedure(sdmSubscription *models.SdmSubscription } } -func (s *nudrService) unsubscribeProcedure(supi string, subscriptionID string) *models.ProblemDetails { +func (s *nudrService) UnsubscribeProcedure(supi string, subscriptionID string) *models.ProblemDetails { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return pd @@ -1418,7 +1616,7 @@ func (s *nudrService) unsubscribeProcedure(supi string, subscriptionID string) * } } -func (s *nudrService) modifyProcedure(sdmSubsModification *models.SdmSubsModification, supi string, subscriptionID string) ( +func (s *nudrService) ModifyProcedure(sdmSubsModification *models.SdmSubsModification, supi string, subscriptionID string) ( response *models.SdmSubscription, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1469,7 +1667,7 @@ func (s *nudrService) modifyProcedure(sdmSubsModification *models.SdmSubsModific } } -func (s *nudrService) getTraceDataProcedure(supi string, plmnID string) ( +func (s *nudrService) GetTraceDataProcedure(supi string, plmnID string) ( response *models.TraceData, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1528,7 +1726,7 @@ func (s *nudrService) getTraceDataProcedure(supi string, plmnID string) ( } } -func (s *nudrService) getUeContextInSmfDataProcedure(supi string, supportedFeatures string) ( +func (s *nudrService) GetUeContextInSmfDataProcedure(supi string, supportedFeatures string) ( response *models.UeContextInSmfData, problemDetails *models.ProblemDetails, ) { var body models.UeContextInSmfData @@ -2089,3 +2287,57 @@ func (s *nudrService) RegistrationSmfRegistrationsProcedure(request *models.SmfR return header, request, nil } } + +// TS 29.503 5.2.2.7.3 +// Modification of a subscription to notifications of shared data change +func (s *nudrService) ModifyForSharedDataProcedure(sdmSubsModification *models.SdmSubsModification, supi string, + subscriptionID string, +) (response *models.SdmSubscription, problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := s.createUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var sdmSubscription models.SdmSubscription + sdmSubs := models.SdmSubscription{} + body := Nudr_DataRepository.UpdatesdmsubscriptionsParamOpts{ + SdmSubscription: optional.NewInterface(sdmSubs), + } + + res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( + ctx, supi, subscriptionID, &body) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + return &sdmSubscription, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } +} diff --git a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go index 593b999..b4e1e21 100644 --- a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go +++ b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go @@ -32,7 +32,7 @@ func (p *Processor) HandleGetAmData(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := getAmDataProcedure(supi, plmnID, supportedFeatures) + response, problemDetails := p.consumer.GetAmDataProcedure(supi, plmnID, supportedFeatures) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go index dadd008..9704536 100644 --- a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go @@ -19,7 +19,7 @@ func (p *Processor) HandleGetAmf3gppAccess(c *gin.Context) { supportedFeatures := c.Query("supported-features") // step 3: handle the message - response, problemDetails := GetAmf3gppAccessProcedure(ueID, supportedFeatures) + response, problemDetails := p.consumer.GetAmf3gppAccessProcedure(ueID, supportedFeatures) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go index ad57566..640882e 100644 --- a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go @@ -23,7 +23,8 @@ func (p *Processor) HandleGetAmfNon3gppAccess(c *gin.Context) { var queryAmfContextNon3gppParamOpts Nudr_DataRepository.QueryAmfContextNon3gppParamOpts queryAmfContextNon3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) // step 3: handle the message - response, problemDetails := GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts, ueId) + + response, problemDetails := p.consumer.GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts, ueId) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/amf_registration_for3_gpp_access.go b/internal/sbi/processor/amf_registration_for3_gpp_access.go index ee88ea7..bca1894 100644 --- a/internal/sbi/processor/amf_registration_for3_gpp_access.go +++ b/internal/sbi/processor/amf_registration_for3_gpp_access.go @@ -48,7 +48,7 @@ func (p *Processor) HandleRegistrationAmf3gppAccess(c *gin.Context) { logger.UecmLog.Info("UEID: ", ueID) // step 3: handle the message - header, response, problemDetails := RegistrationAmf3gppAccessProcedure(amf3GppAccessRegistration, ueID) + header, response, problemDetails := p.consumer.RegistrationAmf3gppAccessProcedure(amf3GppAccessRegistration, ueID) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go index d46227a..95ad707 100644 --- a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go +++ b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go @@ -47,7 +47,7 @@ func (p *Processor) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { ueID := c.Param("ueId") // step 3: handle the message - header, response, problemDetails := RegisterAmfNon3gppAccessProcedure(amfNon3GppAccessRegistration, ueID) + header, response, problemDetails := p.consumer.RegisterAmfNon3gppAccessProcedure(amfNon3GppAccessRegistration, ueID) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/confirm_auth.go b/internal/sbi/processor/confirm_auth.go index 2df67db..8edf229 100644 --- a/internal/sbi/processor/confirm_auth.go +++ b/internal/sbi/processor/confirm_auth.go @@ -45,7 +45,7 @@ func (p *Processor) HandleConfirmAuth(c *gin.Context) { logger.UeauLog.Infoln("Handle ConfirmAuthDataRequest") - problemDetails := ConfirmAuthDataProcedure(authEvent, supi) + problemDetails := p.consumer.ConfirmAuthDataProcedure(authEvent, supi) if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) diff --git a/internal/sbi/processor/data_change_notification_to_nf.go b/internal/sbi/processor/data_change_notification_to_nf.go index c97ca73..b3385a0 100644 --- a/internal/sbi/processor/data_change_notification_to_nf.go +++ b/internal/sbi/processor/data_change_notification_to_nf.go @@ -44,7 +44,7 @@ func (p *Processor) HandleDataChangeNotificationToNF(c *gin.Context) { logger.CallbackLog.Infof("Handle DataChangeNotificationToNF") - problemDetails := DataChangeNotificationProcedure(dataChangeNotify.NotifyItems, supi) + problemDetails := p.consumer.DataChangeNotificationProcedure(dataChangeNotify.NotifyItems, supi) // step 4: process the return value from step 3 if problemDetails != nil { diff --git a/internal/sbi/processor/ee_subscription.go b/internal/sbi/processor/ee_subscription.go index 8a5ac75..c5249f0 100644 --- a/internal/sbi/processor/ee_subscription.go +++ b/internal/sbi/processor/ee_subscription.go @@ -54,7 +54,7 @@ func (p *Processor) HandleCreateEeSubscription(c *gin.Context) { ueIdentity := c.Params.ByName("ueIdentity") - createdEESubscription, problemDetails := CreateEeSubscriptionProcedure(ueIdentity, eesubscription) + createdEESubscription, problemDetails := p.consumer.CreateEeSubscriptionProcedure(ueIdentity, eesubscription) if createdEESubscription != nil { c.JSON(http.StatusCreated, createdEESubscription) return @@ -76,7 +76,7 @@ func (p *Processor) HandleDeleteEeSubscription(c *gin.Context) { ueIdentity := c.Params.ByName("ueIdentity") subscriptionID := c.Params.ByName("subscriptionId") - DeleteEeSubscriptionProcedure(ueIdentity, subscriptionID) + p.consumer.DeleteEeSubscriptionProcedure(ueIdentity, subscriptionID) // only return 204 no content c.Status(http.StatusNoContent) } @@ -116,7 +116,7 @@ func (p *Processor) HandleUpdateEeSubscription(c *gin.Context) { logger.EeLog.Infoln("Handle Update EE subscription") logger.EeLog.Warnln("Update EE Subscription is not implemented") - problemDetails := UpdateEeSubscriptionProcedure(ueIdentity, subscriptionID, patchList) + problemDetails := p.consumer.UpdateEeSubscriptionProcedure(ueIdentity, subscriptionID, patchList) if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) return diff --git a/internal/sbi/processor/generate_auth_data.go b/internal/sbi/processor/generate_auth_data.go index b570f1c..8168c4b 100644 --- a/internal/sbi/processor/generate_auth_data.go +++ b/internal/sbi/processor/generate_auth_data.go @@ -49,7 +49,7 @@ func (p *Processor) HandleGenerateAuthData(c *gin.Context) { supiOrSuci := c.Param("supiOrSuci") // step 3: handle the message - response, problemDetails := GenerateAuthDataProcedure(authInfoReq, supiOrSuci) + response, problemDetails := p.consumer.GenerateAuthDataProcedure(authInfoReq, supiOrSuci) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/gpsi_to_supi_translation.go b/internal/sbi/processor/gpsi_to_supi_translation.go index d9d30f2..5649f6a 100644 --- a/internal/sbi/processor/gpsi_to_supi_translation.go +++ b/internal/sbi/processor/gpsi_to_supi_translation.go @@ -20,7 +20,7 @@ func (p *Processor) HandleGetIdTranslationResult(c *gin.Context) { gpsi := c.Params.ByName("gpsi") // step 3: handle the message - response, problemDetails := getIdTranslationResultProcedure(gpsi) + response, problemDetails := p.consumer.GetIdTranslationResultProcedure(gpsi) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/index.go b/internal/sbi/processor/index.go new file mode 100644 index 0000000..dcf7781 --- /dev/null +++ b/internal/sbi/processor/index.go @@ -0,0 +1,11 @@ +package processor + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (p *Processor) HandleIndex(c *gin.Context) { + c.String(http.StatusOK, "Hello World!") +} diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go index d982e95..4b6508c 100644 --- a/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go +++ b/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go @@ -10,7 +10,7 @@ import ( ) // UpdateAmf3gppAccess - Update a parameter in the AMF registration for 3GPP access -func HTTPUpdateAmf3gppAccess(c *gin.Context) { +func (p *Processor) HandleUpdateAmf3gppAccess(c *gin.Context) { var amf3GppAccessRegistrationModification models.Amf3GppAccessRegistrationModification // step 1: retrieve http request body @@ -48,7 +48,7 @@ func HTTPUpdateAmf3gppAccess(c *gin.Context) { ueID := c.Param("ueId") // step 3: handle the message - problemDetails := UpdateAmf3gppAccessProcedure(amf3GppAccessRegistrationModification, ueID) + problemDetails := p.consumer.UpdateAmf3gppAccessProcedure(amf3GppAccessRegistrationModification, ueID) // step 4: process the return value from step 3 if problemDetails != nil { diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go index 7444c74..db28db9 100644 --- a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go +++ b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go @@ -47,7 +47,7 @@ func (p *Processor) HandleUpdateAmfNon3gppAccess(c *gin.Context) { ueID := c.Param("ueId") // step 3: handle the message - problemDetails := UpdateAmfNon3gppAccessProcedure(amfNon3GppAccessRegistrationModification, ueID) + problemDetails := p.consumer.UpdateAmfNon3gppAccessProcedure(amfNon3GppAccessRegistrationModification, ueID) // step 4: process the return value from step 3 if problemDetails != nil { diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go index b3583d1..2e450ed 100644 --- a/internal/sbi/processor/processor.go +++ b/internal/sbi/processor/processor.go @@ -1,12 +1,28 @@ package processor import ( - "github.com/free5gc/udm/internal/repository" + "github.com/free5gc/udm/internal/sbi/consumer" + "github.com/free5gc/udm/pkg/app" ) +type ProcessorUdm interface { + app.App +} + type Processor struct { + ProcessorUdm + consumer *consumer.Consumer +} + +type HandlerResponse struct { + Status int + Headers map[string][]string + Body interface{} } -func NewProcessor(runtimeRepo *repository.RuntimeRepository) *Processor { - return &Processor{} +func NewProcessor(udm ProcessorUdm) (*Processor, error) { + p := &Processor{ + ProcessorUdm: udm, + } + return p, nil } diff --git a/internal/sbi/processor/retrieval_of_multiple_data_sets.go b/internal/sbi/processor/retrieval_of_multiple_data_sets.go index 040b5e2..280e696 100644 --- a/internal/sbi/processor/retrieval_of_multiple_data_sets.go +++ b/internal/sbi/processor/retrieval_of_multiple_data_sets.go @@ -22,7 +22,7 @@ func (p *Processor) HandleGetSupi(c *gin.Context) { // step 2: retrieve request supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := getPlmnIDStruct(query) + plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) return @@ -32,7 +32,7 @@ func (p *Processor) HandleGetSupi(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := getSupiProcedure(supi, plmnID, dataSetNames, supportedFeatures) + response, problemDetails := p.consumer.GetSupiProcedure(supi, plmnID, dataSetNames, supportedFeatures) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/retrieval_of_shared_data.go b/internal/sbi/processor/retrieval_of_shared_data.go index beca6eb..da91f9d 100644 --- a/internal/sbi/processor/retrieval_of_shared_data.go +++ b/internal/sbi/processor/retrieval_of_shared_data.go @@ -17,7 +17,7 @@ func (p *Processor) HandleGetSharedData(c *gin.Context) { sharedDataIds := c.QueryArray("shared-data-ids") supportedFeatures := c.QueryArray("supported-features") // step 3: handle the message - response, problemDetails := getSharedDataProcedure(sharedDataIds, supportedFeatures) + response, problemDetails := p.consumer.GetSharedDataProcedure(sharedDataIds, supportedFeatures[0]) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/session_management_subscription_data_retrieval.go b/internal/sbi/processor/session_management_subscription_data_retrieval.go index c02c771..fb77adb 100644 --- a/internal/sbi/processor/session_management_subscription_data_retrieval.go +++ b/internal/sbi/processor/session_management_subscription_data_retrieval.go @@ -22,7 +22,7 @@ func (p *Processor) HandleGetSmData(c *gin.Context) { // step 2: retrieve request supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := getPlmnIDStruct(query) + plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) return @@ -33,7 +33,7 @@ func (p *Processor) HandleGetSmData(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := getSmDataProcedure(supi, plmnID, Dnn, Snssai, supportedFeatures) + response, problemDetails := p.consumer.GetSmDataProcedure(supi, plmnID, Dnn, Snssai, supportedFeatures) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go index a4694a3..6254334 100644 --- a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go +++ b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go @@ -20,7 +20,7 @@ func (p *Processor) HandleGetNssai(c *gin.Context) { // step 2: retrieve request supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := getPlmnIDStruct(query) + plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) return @@ -29,7 +29,7 @@ func (p *Processor) HandleGetNssai(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := getNssaiProcedure(supi, plmnID, supportedFeatures) + response, problemDetails := p.consumer.GetNssaiProcedure(supi, plmnID, supportedFeatures) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/smf_deregistration.go b/internal/sbi/processor/smf_deregistration.go index 3d4428b..a4e70e2 100644 --- a/internal/sbi/processor/smf_deregistration.go +++ b/internal/sbi/processor/smf_deregistration.go @@ -18,7 +18,7 @@ func (p *Processor) HandleDeregistrationSmfRegistrations(c *gin.Context) { pduSessionID := c.Params.ByName("pduSessionId") // step 3: handle the message - problemDetails := DeregistrationSmfRegistrationsProcedure(ueID, pduSessionID) + problemDetails := p.consumer.DeregistrationSmfRegistrationsProcedure(ueID, pduSessionID) // step 4: process the return value from step 3 if problemDetails != nil { diff --git a/internal/sbi/processor/smf_registration.go b/internal/sbi/processor/smf_registration.go index fad963a..0561001 100644 --- a/internal/sbi/processor/smf_registration.go +++ b/internal/sbi/processor/smf_registration.go @@ -49,7 +49,7 @@ func (p *Processor) HandleRegistrationSmfRegistrations(c *gin.Context) { pduSessionID := c.Params.ByName("pduSessionId") // step 3: handle the message - header, response, problemDetails := RegistrationSmfRegistrationsProcedure(&smfRegistration, ueID, pduSessionID) + header, response, problemDetails := p.consumer.RegistrationSmfRegistrationsProcedure(&smfRegistration, ueID, pduSessionID) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go index abeee75..c262dc2 100644 --- a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go +++ b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go @@ -20,7 +20,7 @@ func (p *Processor) HandleGetSmfSelectData(c *gin.Context) { // step 2: retrieve request supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := getPlmnIDStruct(query) + plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) if problemDetails != nil { c.JSON(int(problemDetails.Status), problemDetails) return @@ -29,7 +29,7 @@ func (p *Processor) HandleGetSmfSelectData(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := getSmfSelectDataProcedure(supi, plmnID, supportedFeatures) + response, problemDetails := p.consumer.GetSmfSelectDataProcedure(supi, plmnID, supportedFeatures) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/subscription_creation.go b/internal/sbi/processor/subscription_creation.go index cbd1ca9..578accf 100644 --- a/internal/sbi/processor/subscription_creation.go +++ b/internal/sbi/processor/subscription_creation.go @@ -48,7 +48,7 @@ func (p *Processor) HandleSubscribe(c *gin.Context) { supi := c.Params.ByName("supi") // step 3: handle the message - header, response, problemDetails := subscribeProcedure(&sdmSubscriptionReq, supi) + header, response, problemDetails := p.consumer.SubscribeProcedure(&sdmSubscriptionReq, supi) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/subscription_creation_for_shared_data.go b/internal/sbi/processor/subscription_creation_for_shared_data.go index fd594c9..232b9ef 100644 --- a/internal/sbi/processor/subscription_creation_for_shared_data.go +++ b/internal/sbi/processor/subscription_creation_for_shared_data.go @@ -6,7 +6,6 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/util/httpwrapper" "github.com/gin-gonic/gin" ) @@ -47,9 +46,9 @@ func (p *Processor) HandleSubscribeToSharedData(c *gin.Context) { // step 2: retrieve request // step 3: handle the message - header, response, problemDetails := subscribeToSharedDataProcedure(&sharedDataSubsReq) + header, response, problemDetails := p.consumer.SubscribeToSharedDataProcedure(&sharedDataSubsReq) - var rsp *httpwrapper.Response + //var rsp *httpwrapper.Response // step 4: process the return value from step 3 if response != nil { // status code is based on SPEC, and option headers diff --git a/internal/sbi/processor/subscription_data_update.go b/internal/sbi/processor/subscription_data_update.go index 55c430f..47a30da 100644 --- a/internal/sbi/processor/subscription_data_update.go +++ b/internal/sbi/processor/subscription_data_update.go @@ -46,7 +46,7 @@ func (p *Processor) HandleUpdate(c *gin.Context) { logger.PpLog.Infoln("Handle UpdateRequest") // step 3: handle the message - problemDetails := UpdateProcedure(ppDataReq, gpsi) + problemDetails := p.consumer.UpdateProcedure(ppDataReq, gpsi) // step 4: process the return value from step 3 if problemDetails != nil { diff --git a/internal/sbi/processor/subscription_deletion.go b/internal/sbi/processor/subscription_deletion.go index e929ebb..b06373e 100644 --- a/internal/sbi/processor/subscription_deletion.go +++ b/internal/sbi/processor/subscription_deletion.go @@ -17,7 +17,7 @@ func (p *Processor) HandleUnsubscribe(c *gin.Context) { subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - problemDetails := unsubscribeProcedure(supi, subscriptionID) + problemDetails := p.consumer.UnsubscribeProcedure(supi, subscriptionID) // step 4: process the return value from step 3 if problemDetails != nil { diff --git a/internal/sbi/processor/subscription_deletion_for_shared_data.go b/internal/sbi/processor/subscription_deletion_for_shared_data.go index 3f425a3..70e2d9e 100644 --- a/internal/sbi/processor/subscription_deletion_for_shared_data.go +++ b/internal/sbi/processor/subscription_deletion_for_shared_data.go @@ -14,7 +14,7 @@ func (p *Processor) HandleUnsubscribeForSharedData(c *gin.Context) { // step 2: retrieve request subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - problemDetails := unsubscribeForSharedDataProcedure(subscriptionID) + problemDetails := p.consumer.UnsubscribeForSharedDataProcedure(subscriptionID) // step 4: process the return value from step 3 if problemDetails != nil { diff --git a/internal/sbi/processor/subscription_modification.go b/internal/sbi/processor/subscription_modification.go index 364f4ba..8c44732 100644 --- a/internal/sbi/processor/subscription_modification.go +++ b/internal/sbi/processor/subscription_modification.go @@ -48,7 +48,7 @@ func (p *Processor) HandleModify(c *gin.Context) { subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - response, problemDetails := modifyProcedure(&sdmSubsModificationReq, supi, subscriptionID) + response, problemDetails := p.consumer.ModifyProcedure(&sdmSubsModificationReq, supi, subscriptionID) // step 4: process the return value from step 3 if response != nil { @@ -70,7 +70,7 @@ func (p *Processor) HandleModify(c *gin.Context) { } // ModifyForSharedData - modify the subscription -func HTTPModifyForSharedData(c *gin.Context) { +func (p *Processor) HandleModifyForSharedData(c *gin.Context) { var sharedDataSubscriptions models.SdmSubsModification // step 1: retrieve http request body requestBody, err := c.GetRawData() @@ -108,7 +108,7 @@ func HTTPModifyForSharedData(c *gin.Context) { subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - response, problemDetails := modifyForSharedDataProcedure(&sharedDataSubscriptions, supi, subscriptionID) + response, problemDetails := p.consumer.ModifyForSharedDataProcedure(&sharedDataSubscriptions, supi, subscriptionID) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/trace_configuration_data_retrieval.go b/internal/sbi/processor/trace_configuration_data_retrieval.go index 0d5cfc8..9617e71 100644 --- a/internal/sbi/processor/trace_configuration_data_retrieval.go +++ b/internal/sbi/processor/trace_configuration_data_retrieval.go @@ -18,7 +18,7 @@ func (p *Processor) HandleGetTraceData(c *gin.Context) { plmnID := c.Query("plmn-id") // step 3: handle the message - response, problemDetails := getTraceDataProcedure(supi, plmnID) + response, problemDetails := p.consumer.GetTraceDataProcedure(supi, plmnID) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go index 525df2c..eef77d2 100644 --- a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go +++ b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go @@ -19,7 +19,7 @@ func (p *Processor) HandleGetUeContextInSmfData(c *gin.Context) { supportedFeatures := c.Query("supported-features") // step 3: handle the message - response, problemDetails := getUeContextInSmfDataProcedure(supi, supportedFeatures) + response, problemDetails := p.consumer.GetUeContextInSmfDataProcedure(supi, supportedFeatures) // step 4: process the return value from step 3 if response != nil { diff --git a/internal/sbi/processor/ueau_route.go b/internal/sbi/processor/ueau_route.go new file mode 100644 index 0000000..e4f91a9 --- /dev/null +++ b/internal/sbi/processor/ueau_route.go @@ -0,0 +1,18 @@ +package processor + +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" +) + +func (p *Processor) genAuthDataHandlerFunc(c *gin.Context) { + c.Params = append(c.Params, gin.Param{Key: "supiOrSuci", Value: c.Param("supi")}) + if strings.ToUpper("Post") == c.Request.Method { + p.HandleGenerateAuthData(c) + return + } + + c.String(http.StatusNotFound, "404 page not found") +} diff --git a/internal/sbi/router.go b/internal/sbi/router.go new file mode 100644 index 0000000..604c834 --- /dev/null +++ b/internal/sbi/router.go @@ -0,0 +1,74 @@ +package sbi + +import ( + "github.com/gin-gonic/gin" +) + +// 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 +} + +type RouteGroup interface { + AddService(engine *gin.Engine) *gin.RouterGroup +} + +func AddService(group *gin.RouterGroup, routes []Route) { + 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) + } + } + +} + +func AddSDMService(group *gin.RouterGroup, routes []Route) { + 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) + } + } +} + +func AddUEAUService(group *gin.RouterGroup, routes []Route) { + 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) + } + } + +} diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 90f215b..9dd492e 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -2,64 +2,240 @@ package sbi import ( "context" + "fmt" + "log" "net/http" + "runtime/debug" + "sync" + "time" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/pkg/app" "github.com/free5gc/udm/pkg/factory" + "github.com/free5gc/util/httpwrapper" + "github.com/sirupsen/logrus" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" + "github.com/free5gc/udm/internal/sbi/consumer" + "github.com/free5gc/udm/internal/sbi/processor" + "github.com/free5gc/udm/internal/util" logger_util "github.com/free5gc/util/logger" "github.com/gin-gonic/gin" ) -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 udm interface { Config() *factory.Config Context() *udm_context.UdmNFContext CancelContext() context.Context //Consumer() *consumer.Consumer - //Processor() *processor.Processor + // Processor() *processor.Processor +} + +type ServerUdm interface { + app.App + + Consumer() *consumer.Consumer + Processor() *processor.Processor } type Server struct { - udm + ServerUdm httpServer *http.Server router *gin.Engine } -func NewServer(udm udm, tlsKeyLogPath string) (*Server, error) { +func NewServer(udm ServerUdm, tlsKeyLogPath string) (*Server, error) { s := &Server{ - udm: udm, - router: logger_util.NewGinWithLogrus(logger.GinLog), + ServerUdm: udm, + router: logger_util.NewGinWithLogrus(logger.GinLog), + } + + 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) + + /*server, err := bindRouter(s.Config(), s.router, tlsKeyLogPath) + s.httpServer = server + + if err != nil { + logger.SBILog.Errorf("bind Router Error: %+v", err) + panic("Server initialization failed") + }*/ + + return s, err + +} + +func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { + logger.SBILog.Info("Starting server...") + + var err error + _, s.Context().NfId, err = s.Consumer().RegisterNFInstance(context.Background()) + if err != nil { + logger.InitLog.Errorf("UDM register to NRF Error[%s]", err.Error()) } - //endpoints := s.getConvergenChargingEndpoints() + wg.Add(1) + go s.startServer(wg) + /*go func() { + defer wg.Done() + + err := s.serve() + if err != http.ErrServerClosed { + logger.SBILog.Panicf("HTTP server setup failed: %+v", err) + } + }()*/ + + return nil +} + +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())) + s.Terminate() + } + wg.Done() + }() + + logger.SBILog.Infof("Start SBI server (listen on %s)", s.httpServer.Addr) + + s.router = newRouter(s) + + 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 (s *Server) Shutdown() { + s.shutdownHttpServer() +} + +func (s *Server) Stop() { + 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) shutdownHttpServer() { + const shutdownTimeout time.Duration = 2 * time.Second + + if s.httpServer == nil { + return + } + + shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) + defer cancel() + + err := s.httpServer.Shutdown(shutdownCtx) + if err != nil { + logger.SBILog.Errorf("HTTP server shutdown failed: %+v", err) + } +} + +func bindRouter(cfg *factory.Config, router *gin.Engine, tlsKeyLogPath string) (*http.Server, error) { + sbiConfig := cfg.Configuration.Sbi + bindAddr := fmt.Sprintf("%s:%d", sbiConfig.BindingIPv4, sbiConfig.Port) + + return httpwrapper.NewHttp2Server(bindAddr, tlsKeyLogPath, router) +} + +func newRouter(s *Server) *gin.Engine { + router := logger_util.NewGinWithLogrus(logger.GinLog) + + udmEERoutes := s.getEventExposureRoutes() + udmEEGroup := s.router.Group(factory.UdmEeResUriPrefix) + routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_EE) + udmEEGroup.Use(func(c *gin.Context) { + routerAuthorizationCheck.Check(c, udm_context.GetSelf()) + }) + AddService(udmEEGroup, udmEERoutes) + + udmCallBackRoutes := s.getHttpCallBackRoutes() + udmCallNackGroup := s.router.Group("") + AddService(udmCallNackGroup, udmCallBackRoutes) + + udmUEAURoutes := s.getUEAuthenticationRoutes() + udmUEAUGroup := s.router.Group(factory.UdmUeauResUriPrefix) + routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_UEAU) + udmUEAUGroup.Use(func(c *gin.Context) { + routerAuthorizationCheck.Check(c, udm_context.GetSelf()) + }) + AddService(udmUEAUGroup, udmUEAURoutes) + + udmUECMRoutes := s.getUEContextManagementRoutes() + udmUECMGroup := s.router.Group(factory.UdmUecmResUriPrefix) + routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_UECM) + udmUECMGroup.Use(func(c *gin.Context) { + routerAuthorizationCheck.Check(c, udm_context.GetSelf()) + }) + AddService(udmUECMGroup, udmUECMRoutes) + + udmSDMRoutes := s.getSubscriberDataManagementRoutes() + udmSDMGroup := s.router.Group(factory.UdmSdmResUriPrefix) + routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_SDM) + udmSDMGroup.Use(func(c *gin.Context) { + routerAuthorizationCheck.Check(c, udm_context.GetSelf()) + }) + AddService(udmSDMGroup, udmSDMRoutes) + + udmPPRoutes := s.getParameterProvisionRoutes() + udmPPGroup := s.router.Group(factory.UdmPpResUriPrefix) + routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_PP) + udmPPGroup.Use(func(c *gin.Context) { + routerAuthorizationCheck.Check(c, udm_context.GetSelf()) + }) + AddService(udmPPGroup, udmPPRoutes) + + return router +} + +func (s *Server) unsecureServe() error { + return s.httpServer.ListenAndServe() +} + +func (s *Server) secureServe() error { + sbiConfig := s.Config().Configuration.Sbi + + pemPath := sbiConfig.Tls.Pem + if pemPath == "" { + pemPath = factory.UdmConfig.GetCertKeyPath() + } + + keyPath := sbiConfig.Tls.Key + if keyPath == "" { + keyPath = factory.UdmConfig.GetCertKeyPath() + } + return s.httpServer.ListenAndServeTLS(pemPath, keyPath) } diff --git a/pkg/app/app.go b/pkg/app/app.go new file mode 100644 index 0000000..f1b030e --- /dev/null +++ b/pkg/app/app.go @@ -0,0 +1,18 @@ +package app + +import ( + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/pkg/factory" +) + +type App interface { + SetLogEnable(enable bool) + SetLogLevel(level string) + SetReportCaller(reportCaller bool) + + Start() + Terminate() + + Context() *udm_context.UDMContext + Config() *factory.Config +} diff --git a/pkg/factory/config.go b/pkg/factory/config.go index 6f4652d..f1f7675 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -6,6 +6,8 @@ package factory import ( "fmt" + "os" + "strconv" "sync" "github.com/asaskevich/govalidator" @@ -122,6 +124,17 @@ func (c *Configuration) validate() (bool, error) { result, err := govalidator.ValidateStruct(c) return result, err } +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 +} type Sbi struct { Scheme string `yaml:"scheme" valid:"scheme"` @@ -255,3 +268,44 @@ func (c *Config) GetLogReportCaller() bool { } return c.Logger.ReportCaller } + +func (c *Config) GetSbiBindingAddr() string { + c.RLock() + defer c.RUnlock() + return c.GetSbiBindingIP() + ":" + strconv.Itoa(c.GetSbiPort()) +} + +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 UdmSbiDefaultPort +} + +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 UdmSbiDefaultScheme +} diff --git a/pkg/service/init.go b/pkg/service/init.go index 2a4164f..8283b81 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -2,43 +2,49 @@ package service import ( "context" - "fmt" "io" "os" - "os/signal" "runtime/debug" "sync" - "syscall" "github.com/sirupsen/logrus" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" + "github.com/free5gc/udm/internal/sbi" "github.com/free5gc/udm/internal/sbi/consumer" - "github.com/free5gc/udm/internal/sbi/eventexposure" - "github.com/free5gc/udm/internal/sbi/httpcallback" - "github.com/free5gc/udm/internal/sbi/parameterprovision" - "github.com/free5gc/udm/internal/sbi/subscriberdatamanagement" - "github.com/free5gc/udm/internal/sbi/ueauthentication" - "github.com/free5gc/udm/internal/sbi/uecontextmanagement" + "github.com/free5gc/udm/internal/sbi/processor" + "github.com/free5gc/udm/pkg/app" "github.com/free5gc/udm/pkg/factory" - "github.com/free5gc/util/httpwrapper" - logger_util "github.com/free5gc/util/logger" ) +var UDM *UdmApp + +var _ app.App = &UdmApp{} + type UdmApp struct { - cfg *factory.Config + app.App + consumer.ConsumerUdm + processor.ProcessorUdm + sbi.ServerUdm + udmCtx *udm_context.UDMContext + cfg *factory.Config + ctx context.Context cancel context.CancelFunc + wg sync.WaitGroup + + sbiServer *sbi.Server + consumer *consumer.Consumer + processor *processor.Processor +} - //sbiServer *sbi.Server - consumer *consumer.Consumer - //processor *processor.Processor - wg sync.WaitGroup +func GetApp() *UdmApp { + return UDM } -func NewApp(cfg *factory.Config) (*UdmApp, error) { +func NewApp(ctx context.Context, cfg *factory.Config, tlsKeyLogPath string) (*UdmApp, error) { udm := &UdmApp{ cfg: cfg, wg: sync.WaitGroup{}, @@ -47,8 +53,11 @@ func NewApp(cfg *factory.Config) (*UdmApp, error) { udm.SetLogLevel(cfg.GetLogLevel()) udm.SetReportCaller(cfg.GetLogReportCaller()) - udm_context.Init() - udm.udmCtx = udm_context.GetSelf() + processor, err_p := processor.NewProcessor(udm) + if err_p != nil { + return udm, err_p + } + udm.processor = processor consumer, err := consumer.NewConsumer(udm) if err != nil { @@ -56,29 +65,18 @@ func NewApp(cfg *factory.Config) (*UdmApp, error) { } udm.consumer = consumer - return udm, nil -} - -func (a *UdmApp) Config() *factory.Config { - return a.cfg -} + udm.ctx, udm.cancel = context.WithCancel(ctx) + udm.udmCtx = udm_context.GetSelf() -func (a *UdmApp) Context() *udm_context.UDMContext { - return a.udmCtx -} + if udm.sbiServer, err = sbi.NewServer(udm, tlsKeyLogPath); err != nil { + return nil, err + } -func (a *UdmApp) CancelContext() context.Context { - return a.ctx -} + UDM = udm -func (a *UdmApp) Consumer() *consumer.Consumer { - return a.consumer + return udm, nil } -/*func (a *UdmApp) Processor() *processor.Processor { - return a.processor -}*/ - func (a *UdmApp) SetLogEnable(enable bool) { logger.MainLog.Infof("Log enable is set to [%v]", enable) if enable && logger.Log.Out == os.Stderr { @@ -120,8 +118,16 @@ func (a *UdmApp) SetReportCaller(reportCaller bool) { logger.Log.SetReportCaller(reportCaller) } -func (a *UdmApp) Start(tlsKeyLogPath string) { - config := factory.UdmConfig +func (a *UdmApp) 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.MainLog.Fatalf("Run SBI server failed: %+v", err) + } + /*config := factory.UdmConfig configuration := config.Configuration sbi := configuration.Sbi @@ -198,19 +204,66 @@ func (a *UdmApp) Start(tlsKeyLogPath string) { if err != nil { logger.InitLog.Fatalf("HTTP server setup failed: %+v", err) - } + }*/ } func (a *UdmApp) Terminate() { - logger.InitLog.Infof("Terminating UDM...") + logger.MainLog.Infof("Terminating UDM...") + a.cancel() + a.CallServerStop() + // 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) + logger.MainLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails) } else if err != nil { - logger.InitLog.Errorf("Deregister NF instance Error[%+v]", err) + logger.MainLog.Errorf("Deregister NF instance Error[%+v]", err) } else { - logger.InitLog.Infof("Deregister from NRF successfully") + logger.MainLog.Infof("Deregister from NRF successfully") + } + logger.MainLog.Infof("CHF SBI Server terminated") +} + +func (a *UdmApp) listenShutdownEvent() { + defer func() { + if p := recover(); p != nil { + // Print stack for panic to log. Fatalf() will let program exit. + logger.MainLog.Fatalf("panic: %v\n%s", p, string(debug.Stack())) + } + a.wg.Done() + }() + + <-a.ctx.Done() + a.Terminate() +} + +func (a *UdmApp) CallServerStop() { + if a.sbiServer != nil { + a.sbiServer.Stop() } - logger.InitLog.Infof("UDM terminated") +} + +func (a *UdmApp) WaitRoutineStopped() { + a.wg.Wait() + logger.MainLog.Infof("CHF App is terminated") +} + +func (a *UdmApp) Config() *factory.Config { + return a.cfg +} + +func (a *UdmApp) Context() *udm_context.UDMContext { + return a.udmCtx +} + +func (a *UdmApp) CancelContext() context.Context { + return a.ctx +} + +func (a *UdmApp) Consumer() *consumer.Consumer { + return a.consumer +} + +func (a *UdmApp) Processor() *processor.Processor { + return a.processor } From 407621376fef120b5bc6277a97e5831a6a41743b Mon Sep 17 00:00:00 2001 From: ubuntu Date: Wed, 15 May 2024 10:55:12 +0000 Subject: [PATCH 07/23] feat: refactor router --- .../api_create_ee_subscription.go | 32 +-- internal/sbi/processor/sdm_route.go | 203 ++++++++++++++++++ internal/sbi/processor/ueau_route.go | 2 +- internal/sbi/server.go | 18 ++ 4 files changed, 240 insertions(+), 15 deletions(-) create mode 100644 internal/sbi/processor/sdm_route.go diff --git a/internal/sbi/eventexposure/api_create_ee_subscription.go b/internal/sbi/eventexposure/api_create_ee_subscription.go index 3f876b2..10b2828 100644 --- a/internal/sbi/eventexposure/api_create_ee_subscription.go +++ b/internal/sbi/eventexposure/api_create_ee_subscription.go @@ -18,12 +18,11 @@ import ( "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" ) // HTTPCreateEeSubscription - Subscribe func HTTPCreateEeSubscription(c *gin.Context) { - var eeSubscriptionReq models.EeSubscription + var eesubscription models.EeSubscription requestBody, err := c.GetRawData() if err != nil { @@ -38,7 +37,8 @@ func HTTPCreateEeSubscription(c *gin.Context) { return } - err = openapi.Deserialize(&eeSubscriptionReq, requestBody, "application/json") + //err = openapi.Deserialize(&eeSubscription, requestBody, "application/json") + err = openapi.Deserialize(nil, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() rsp := models.ProblemDetails{ @@ -51,21 +51,25 @@ func HTTPCreateEeSubscription(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, eeSubscriptionReq) - req.Params["ueIdentity"] = c.Params.ByName("ueIdentity") + // Start + logger.EeLog.Infoln("Handle Create EE Subscription") - rsp := producer.HandleCreateEeSubscription(req) + ueIdentity := c.Params.ByName("ueIdentity") - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.EeLog.Errorln(err) - problemDetails := models.ProblemDetails{ + createdEESubscription, problemDetails := producer.CreateEeSubscriptionProcedure(ueIdentity, eesubscription) + + if createdEESubscription != nil { + c.JSON(http.StatusCreated, createdEESubscription) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), + Cause: "UNSPECIFIED_NF_FAILURE", } c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) + return } } diff --git a/internal/sbi/processor/sdm_route.go b/internal/sbi/processor/sdm_route.go new file mode 100644 index 0000000..995f830 --- /dev/null +++ b/internal/sbi/processor/sdm_route.go @@ -0,0 +1,203 @@ +package processor + +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" +) + +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 +} + +func (p *Processor) OneLayerPathHandlerFunc(c *gin.Context) { + supi := c.Param("supi") + oneLayerPathRouter := p.getOneLayerRoutes() + for _, route := range oneLayerPathRouter { + if strings.Contains(route.Pattern, supi) && route.Method == c.Request.Method { + route.HandlerFunc(c) + return + } + } + + // special case for :supi + if c.Request.Method == strings.ToUpper("Get") { + p.HandleGetSupi(c) + return + } + + c.String(http.StatusNotFound, "404 page not found") +} + +func (p *Processor) TwoLayerPathHandlerFunc(c *gin.Context) { + supi := c.Param("supi") + op := c.Param("subscriptionId") + + // for "/shared-data-subscriptions/:subscriptionId" + if supi == "shared-data-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { + p.HandleUnsubscribeForSharedData(c) + return + } + + // for "/shared-data-subscriptions/:subscriptionId" + if supi == "shared-data-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { + p.HandleModifyForSharedData(c) + return + } + + // for "/:gpsi/id-translation-result" + if op == "id-translation-result" && strings.ToUpper("Get") == c.Request.Method { + c.Params = append(c.Params, gin.Param{Key: "gpsi", Value: c.Param("supi")}) + p.HandleGetIdTranslationResult(c) + return + } + + twoLayerPathRouter := p.getTwoLayerRoutes() + for _, route := range twoLayerPathRouter { + if strings.Contains(route.Pattern, op) && route.Method == c.Request.Method { + route.HandlerFunc(c) + return + } + } + + c.String(http.StatusNotFound, "404 page not found") +} + +func (p *Processor) ThreeLayerPathHandlerFunc(c *gin.Context) { + op := c.Param("subscriptionId") + + // for "/:supi/sdm-subscriptions/:subscriptionId" + if op == "sdm-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { + var tmpParams gin.Params + tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) + tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) + c.Params = tmpParams + p.HandleUnsubscribe(c) + return + } + + // for "/:supi/am-data/sor-ack" + if op == "am-data" && strings.ToUpper("Put") == c.Request.Method { + p.HandleInfo(c) + return + } + + // for "/:supi/sdm-subscriptions/:subscriptionId" + if op == "sdm-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { + var tmpParams gin.Params + tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) + tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) + c.Params = tmpParams + p.HandleModify(c) + return + } + + c.String(http.StatusNotFound, "404 page not found") +} + +func (p *Processor) getOneLayerRoutes() []Route { + return []Route{ + { + "GetSupi", + strings.ToUpper("Get"), + "/:supi", + p.HandleGetSupi, + }, + + { + "GetSharedData", + strings.ToUpper("Get"), + "/shared-data", + p.HandleGetSharedData, + }, + + { + "SubscribeToSharedData", + strings.ToUpper("Post"), + "/shared-data-subscriptions", + p.HandleSubscribeToSharedData, + }, + } +} + +func (p *Processor) getTwoLayerRoutes() []Route { + return []Route{ + { + "GetAmData", + strings.ToUpper("Get"), + "/:supi/am-data", + p.HandleGetAmData, + }, + + { + "GetSmfSelectData", + strings.ToUpper("Get"), + "/:supi/smf-select-data", + p.HandleGetSmfSelectData, + }, + + { + "GetSmsMngData", + strings.ToUpper("Get"), + "/:supi/sms-mng-data", + p.HandleGetSmsMngData, + }, + + { + "GetSmsData", + strings.ToUpper("Get"), + "/:supi/sms-data", + p.HandleGetSmsData, + }, + + { + "GetSmData", + strings.ToUpper("Get"), + "/:supi/sm-data", + p.HandleGetSmData, + }, + + { + "GetNssai", + strings.ToUpper("Get"), + "/:supi/nssai", + p.HandleGetNssai, + }, + + { + "Subscribe", + strings.ToUpper("Post"), + "/:supi/sdm-subscriptions", + p.HandleSubscribe, + }, + + { + "GetTraceData", + strings.ToUpper("Get"), + "/:supi/trace-data", + p.HandleGetTraceData, + }, + + { + "GetUeContextInSmfData", + strings.ToUpper("Get"), + "/:supi/ue-context-in-smf-data", + p.HandleGetUeContextInSmfData, + }, + + { + "GetUeContextInSmsfData", + strings.ToUpper("Get"), + "/:supi/ue-context-in-smsf-data", + p.HandleGetUeContextInSmsfData, + }, + } +} diff --git a/internal/sbi/processor/ueau_route.go b/internal/sbi/processor/ueau_route.go index e4f91a9..a35d08a 100644 --- a/internal/sbi/processor/ueau_route.go +++ b/internal/sbi/processor/ueau_route.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" ) -func (p *Processor) genAuthDataHandlerFunc(c *gin.Context) { +func (p *Processor) GenAuthDataHandlerFunc(c *gin.Context) { c.Params = append(c.Params, gin.Param{Key: "supiOrSuci", Value: c.Param("supi")}) if strings.ToUpper("Post") == c.Request.Method { p.HandleGenerateAuthData(c) diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 9dd492e..ca0d3e2 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -173,6 +173,7 @@ func bindRouter(cfg *factory.Config, router *gin.Engine, tlsKeyLogPath string) ( func newRouter(s *Server) *gin.Engine { router := logger_util.NewGinWithLogrus(logger.GinLog) + // EE udmEERoutes := s.getEventExposureRoutes() udmEEGroup := s.router.Group(factory.UdmEeResUriPrefix) routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_EE) @@ -181,10 +182,12 @@ func newRouter(s *Server) *gin.Engine { }) AddService(udmEEGroup, udmEERoutes) + // Callback udmCallBackRoutes := s.getHttpCallBackRoutes() udmCallNackGroup := s.router.Group("") AddService(udmCallNackGroup, udmCallBackRoutes) + // UEAU udmUEAURoutes := s.getUEAuthenticationRoutes() udmUEAUGroup := s.router.Group(factory.UdmUeauResUriPrefix) routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_UEAU) @@ -193,6 +196,10 @@ func newRouter(s *Server) *gin.Engine { }) AddService(udmUEAUGroup, udmUEAURoutes) + genAuthDataPath := "/:supi/security-information/generate-auth-data" + udmUEAUGroup.Any(genAuthDataPath, s.Processor().GenAuthDataHandlerFunc) + + // UECM udmUECMRoutes := s.getUEContextManagementRoutes() udmUECMGroup := s.router.Group(factory.UdmUecmResUriPrefix) routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_UECM) @@ -201,6 +208,7 @@ func newRouter(s *Server) *gin.Engine { }) AddService(udmUECMGroup, udmUECMRoutes) + // SDM udmSDMRoutes := s.getSubscriberDataManagementRoutes() udmSDMGroup := s.router.Group(factory.UdmSdmResUriPrefix) routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_SDM) @@ -209,6 +217,16 @@ func newRouter(s *Server) *gin.Engine { }) AddService(udmSDMGroup, udmSDMRoutes) + oneLayerPath := "/:supi" + udmSDMGroup.Any(oneLayerPath, s.Processor().OneLayerPathHandlerFunc) + + twoLayerPath := "/:supi/:subscriptionId" + udmSDMGroup.Any(twoLayerPath, s.Processor().TwoLayerPathHandlerFunc) + + threeLayerPath := "/:supi/:subscriptionId/:thirdLayer" + udmSDMGroup.Any(threeLayerPath, s.Processor().ThreeLayerPathHandlerFunc) + + // PP udmPPRoutes := s.getParameterProvisionRoutes() udmPPGroup := s.router.Group(factory.UdmPpResUriPrefix) routerAuthorizationCheck = util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_PP) From c563d3ee8fd6e6bd5f1e7bbf54f4958f3270ad4b Mon Sep 17 00:00:00 2001 From: ubuntu Date: Wed, 15 May 2024 11:25:14 +0000 Subject: [PATCH 08/23] fix: fix lint error --- internal/sbi/api_eventexposure.go | 1 - internal/sbi/consumer/nrf_service.go | 9 ++-- internal/sbi/consumer/udm_service.go | 9 +++- internal/sbi/consumer/udr_service.go | 53 +++++++++++++++---- .../api_create_ee_subscription.go | 2 +- ...nd_mobility_subscription_data_retrieval.go | 4 +- ..._gpp_access_registration_info_retrieval.go | 5 +- ..._gpp_access_registration_info_retrieval.go | 5 +- .../amf_registration_for3_gpp_access.go | 3 +- .../amf_registration_for_non3_gpp_access.go | 4 +- internal/sbi/processor/ee_subscription.go | 2 - .../sbi/processor/gpsi_to_supi_translation.go | 2 +- ...in_the_amf_registration_for3_gpp_access.go | 4 +- ...he_amf_registration_for_non3_gpp_access.go | 4 +- .../retrieval_of_multiple_data_sets.go | 3 +- .../sbi/processor/retrieval_of_shared_data.go | 3 +- ..._management_subscription_data_retrieval.go | 4 +- ...e_selection_subscription_data_retrieval.go | 4 +- internal/sbi/processor/smf_deregistration.go | 5 +- internal/sbi/processor/smf_registration.go | 10 ++-- ...f_selection_subscription_data_retrieval.go | 4 +- .../sbi/processor/subscription_creation.go | 3 +- .../subscription_creation_for_shared_data.go | 6 +-- .../sbi/processor/subscription_deletion.go | 4 +- .../subscription_deletion_for_shared_data.go | 4 +- .../processor/subscription_modification.go | 4 +- .../trace_configuration_data_retrieval.go | 4 +- .../ue_context_in_smf_data_retrieval.go | 5 +- internal/sbi/router.go | 2 - internal/sbi/server.go | 46 ++-------------- pkg/factory/config.go | 1 + pkg/service/init.go | 1 - 32 files changed, 113 insertions(+), 107 deletions(-) diff --git a/internal/sbi/api_eventexposure.go b/internal/sbi/api_eventexposure.go index b3cdefa..f4d2a4b 100644 --- a/internal/sbi/api_eventexposure.go +++ b/internal/sbi/api_eventexposure.go @@ -34,5 +34,4 @@ func (s *Server) getEventExposureRoutes() []Route { s.Processor().HandleUpdateEeSubscription, }, } - } diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 1371bf0..79f0117 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -8,13 +8,14 @@ import ( "sync" "time" + "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" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" - "github.com/pkg/errors" ) type nnrfService struct { @@ -73,7 +74,8 @@ func (s *nnrfService) getNFDiscClient(uri string) *Nnrf_NFDiscovery.APIClient { func (s *nnrfService) SendSearchNFInstances( nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( - *models.SearchResult, error) { + *models.SearchResult, error, +) { // Set client and set url chfContext := s.consumer.Context() @@ -134,7 +136,8 @@ func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.Problem } func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( - resouceNrfUri string, retrieveNfInstanceID string, err error) { + resouceNrfUri string, retrieveNfInstanceID string, err error, +) { udmContext := s.consumer.Context() client := s.getNFManagementClient(udmContext.NrfUri) nfProfile, err := s.buildNfProfile(udmContext) diff --git a/internal/sbi/consumer/udm_service.go b/internal/sbi/consumer/udm_service.go index 6359af4..e347c8e 100644 --- a/internal/sbi/consumer/udm_service.go +++ b/internal/sbi/consumer/udm_service.go @@ -101,7 +101,9 @@ func (s *nudmService) SubscribeToSharedDataProcedure(sdmSubscription *models.Sdm if res.StatusCode == http.StatusCreated { header = make(http.Header) udm_context.GetSelf().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) - reourceUri := udm_context.GetSelf().GetSDMUri() + "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId + reourceUri := udm_context.GetSelf(). + GetSDMUri() + + "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId header.Set("Location", reourceUri) return header, &sdmSubscriptionResp, nil } else if res.StatusCode == http.StatusNotFound { @@ -163,7 +165,10 @@ func (s *nudmService) UnsubscribeForSharedDataProcedure(subscriptionID string) * } } -func (s *nudmService) DataChangeNotificationProcedure(notifyItems []models.NotifyItem, supi string) *models.ProblemDetails { +func (s *nudmService) DataChangeNotificationProcedure( + notifyItems []models.NotifyItem, + supi string, +) *models.ProblemDetails { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { return pd diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go index 14919bf..2a52bdf 100644 --- a/internal/sbi/consumer/udr_service.go +++ b/internal/sbi/consumer/udr_service.go @@ -14,6 +14,7 @@ import ( "time" "github.com/antihax/optional" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudr_DataRepository" "github.com/free5gc/openapi/models" @@ -366,7 +367,10 @@ func (s *nudrService) UpdateEeSubscriptionProcedure(ueIdentity string, subscript } } -func (s *nudrService) ConfirmAuthDataProcedure(authEvent models.AuthEvent, supi string) (problemDetails *models.ProblemDetails) { +func (s *nudrService) ConfirmAuthDataProcedure( + authEvent models.AuthEvent, + supi string, +) (problemDetails *models.ProblemDetails) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return pd @@ -411,7 +415,7 @@ func (s *nudrService) GenerateAuthDataProcedure(authInfoRequest models.Authentic logger.UeauLog.Traceln("In GenerateAuthDataProcedure") response = &models.AuthenticationInfoResult{} - rand.Seed(time.Now().UnixNano()) + rand.New(rand.NewSource(time.Now().UnixNano())) supi, err := suci.ToSupi(supiOrSuci, udm_context.GetSelf().SuciProfiles) if err != nil { problemDetails = &models.ProblemDetails{ @@ -839,7 +843,10 @@ func (s *nudrService) GenerateAuthDataProcedure(authInfoRequest models.Authentic return response, nil } -func (s *nudrService) UpdateProcedure(updateRequest models.PpData, gpsi string) (problemDetails *models.ProblemDetails) { +func (s *nudrService) UpdateProcedure( + updateRequest models.PpData, + gpsi string, +) (problemDetails *models.ProblemDetails) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return pd @@ -1315,7 +1322,13 @@ func (s *nudrService) GetSharedDataProcedure(sharedDataIds []string, supportedFe } } -func (s *nudrService) GetSmDataProcedure(supi string, plmnID string, Dnn string, Snssai string, supportedFeatures string) ( +func (s *nudrService) GetSmDataProcedure( + supi string, + plmnID string, + Dnn string, + Snssai string, + supportedFeatures string, +) ( response interface{}, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1616,7 +1629,11 @@ func (s *nudrService) UnsubscribeProcedure(supi string, subscriptionID string) * } } -func (s *nudrService) ModifyProcedure(sdmSubsModification *models.SdmSubsModification, supi string, subscriptionID string) ( +func (s *nudrService) ModifyProcedure( + sdmSubsModification *models.SdmSubsModification, + supi string, + subscriptionID string, +) ( response *models.SdmSubscription, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1873,7 +1890,10 @@ func (s *nudrService) GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOp return &amfNon3GppAccessRegistration, nil } -func (s *nudrService) RegistrationAmf3gppAccessProcedure(registerRequest models.Amf3GppAccessRegistration, ueID string) ( +func (s *nudrService) RegistrationAmf3gppAccessProcedure( + registerRequest models.Amf3GppAccessRegistration, + ueID string, +) ( header http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -1951,7 +1971,10 @@ func (s *nudrService) RegistrationAmf3gppAccessProcedure(registerRequest models. } } -func (s *nudrService) RegisterAmfNon3gppAccessProcedure(registerRequest models.AmfNon3GppAccessRegistration, ueID string) ( +func (s *nudrService) RegisterAmfNon3gppAccessProcedure( + registerRequest models.AmfNon3GppAccessRegistration, + ueID string, +) ( header http.Header, response *models.AmfNon3GppAccessRegistration, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -2112,7 +2135,10 @@ func (s *nudrService) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessR return nil } -func (s *nudrService) UpdateAmfNon3gppAccessProcedure(request models.AmfNon3GppAccessRegistrationModification, ueID string) ( +func (s *nudrService) UpdateAmfNon3gppAccessProcedure( + request models.AmfNon3GppAccessRegistrationModification, + ueID string, +) ( problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) @@ -2206,7 +2232,10 @@ func (s *nudrService) UpdateAmfNon3gppAccessProcedure(request models.AmfNon3GppA return problemDetails } -func (s *nudrService) DeregistrationSmfRegistrationsProcedure(ueID string, pduSessionID string) (problemDetails *models.ProblemDetails) { +func (s *nudrService) DeregistrationSmfRegistrationsProcedure( + ueID string, + pduSessionID string, +) (problemDetails *models.ProblemDetails) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { return pd @@ -2234,7 +2263,11 @@ func (s *nudrService) DeregistrationSmfRegistrationsProcedure(ueID string, pduSe return nil } -func (s *nudrService) RegistrationSmfRegistrationsProcedure(request *models.SmfRegistration, ueID string, pduSessionID string) ( +func (s *nudrService) RegistrationSmfRegistrationsProcedure( + request *models.SmfRegistration, + ueID string, + pduSessionID string, +) ( header http.Header, response *models.SmfRegistration, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) diff --git a/internal/sbi/eventexposure/api_create_ee_subscription.go b/internal/sbi/eventexposure/api_create_ee_subscription.go index 10b2828..2e11a38 100644 --- a/internal/sbi/eventexposure/api_create_ee_subscription.go +++ b/internal/sbi/eventexposure/api_create_ee_subscription.go @@ -37,7 +37,7 @@ func HTTPCreateEeSubscription(c *gin.Context) { return } - //err = openapi.Deserialize(&eeSubscription, requestBody, "application/json") + // err = openapi.Deserialize(&eeSubscription, requestBody, "application/json") err = openapi.Deserialize(nil, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() diff --git a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go index b4e1e21..31fed99 100644 --- a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go +++ b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go @@ -52,7 +52,9 @@ func (p *Processor) HandleGetAmData(c *gin.Context) { } } -func (p *Processor) getPlmnIDStruct(queryParameters url.Values) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { +func (p *Processor) getPlmnIDStruct( + queryParameters url.Values, +) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { if queryParameters["plmn-id"] != nil { plmnIDJson := queryParameters["plmn-id"][0] plmnIDStruct := &models.PlmnId{} diff --git a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go index 9704536..61a4fbd 100644 --- a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go @@ -3,14 +3,14 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information func (p *Processor) HandleGetAmf3gppAccess(c *gin.Context) { - // step 1: log logger.UecmLog.Infof("Handle HandleGetAmf3gppAccessRequest") @@ -37,5 +37,4 @@ func (p *Processor) HandleGetAmf3gppAccess(c *gin.Context) { c.JSON(http.StatusForbidden, problemDetails) return } - } diff --git a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go index 640882e..bf04668 100644 --- a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go +++ b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go @@ -4,15 +4,15 @@ import ( "net/http" "github.com/antihax/optional" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/Nudr_DataRepository" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetAmfNon3gppAccess - retrieve the AMF registration for non-3GPP access information func (p *Processor) HandleGetAmfNon3gppAccess(c *gin.Context) { - // step 1: log logger.UecmLog.Infoln("Handle GetAmfNon3gppAccessRequest") @@ -42,5 +42,4 @@ func (p *Processor) HandleGetAmfNon3gppAccess(c *gin.Context) { c.JSON(http.StatusForbidden, problemDetails) return } - } diff --git a/internal/sbi/processor/amf_registration_for3_gpp_access.go b/internal/sbi/processor/amf_registration_for3_gpp_access.go index bca1894..2e65a09 100644 --- a/internal/sbi/processor/amf_registration_for3_gpp_access.go +++ b/internal/sbi/processor/amf_registration_for3_gpp_access.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // RegistrationAmf3gppAccess - register as AMF for 3GPP access diff --git a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go index 95ad707..45dd8c2 100644 --- a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go +++ b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // Register - register as AMF for non-3GPP access @@ -64,5 +65,4 @@ func (p *Processor) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { c.Status(http.StatusNoContent) return } - } diff --git a/internal/sbi/processor/ee_subscription.go b/internal/sbi/processor/ee_subscription.go index c5249f0..10a7d8e 100644 --- a/internal/sbi/processor/ee_subscription.go +++ b/internal/sbi/processor/ee_subscription.go @@ -72,7 +72,6 @@ func (p *Processor) HandleCreateEeSubscription(c *gin.Context) { } func (p *Processor) HandleDeleteEeSubscription(c *gin.Context) { - ueIdentity := c.Params.ByName("ueIdentity") subscriptionID := c.Params.ByName("subscriptionId") @@ -124,5 +123,4 @@ func (p *Processor) HandleUpdateEeSubscription(c *gin.Context) { c.Status(http.StatusNoContent) return } - } diff --git a/internal/sbi/processor/gpsi_to_supi_translation.go b/internal/sbi/processor/gpsi_to_supi_translation.go index 5649f6a..bda7afd 100644 --- a/internal/sbi/processor/gpsi_to_supi_translation.go +++ b/internal/sbi/processor/gpsi_to_supi_translation.go @@ -11,7 +11,7 @@ import ( // GetIdTranslationResult - retrieve a UE's SUPI func (p *Processor) HandleGetIdTranslationResult(c *gin.Context) { - //req.Query.Set("SupportedFeatures", c.Query("supported-features")) + // req.Query.Set("SupportedFeatures", c.Query("supported-features")) // step 1: log logger.SdmLog.Infof("Handle GetIdTranslationResultRequest") diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go index 4b6508c..06b07e5 100644 --- a/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go +++ b/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // UpdateAmf3gppAccess - Update a parameter in the AMF registration for 3GPP access @@ -58,5 +59,4 @@ func (p *Processor) HandleUpdateAmf3gppAccess(c *gin.Context) { c.Status(http.StatusNoContent) return } - } diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go index db28db9..9fddc79 100644 --- a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go +++ b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access @@ -57,5 +58,4 @@ func (p *Processor) HandleUpdateAmfNon3gppAccess(c *gin.Context) { c.Status(http.StatusNoContent) return } - } diff --git a/internal/sbi/processor/retrieval_of_multiple_data_sets.go b/internal/sbi/processor/retrieval_of_multiple_data_sets.go index 280e696..7497837 100644 --- a/internal/sbi/processor/retrieval_of_multiple_data_sets.go +++ b/internal/sbi/processor/retrieval_of_multiple_data_sets.go @@ -5,9 +5,10 @@ import ( "net/url" "strings" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetSupi - retrieve multiple data sets diff --git a/internal/sbi/processor/retrieval_of_shared_data.go b/internal/sbi/processor/retrieval_of_shared_data.go index da91f9d..314b9e8 100644 --- a/internal/sbi/processor/retrieval_of_shared_data.go +++ b/internal/sbi/processor/retrieval_of_shared_data.go @@ -3,9 +3,10 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetSharedData - retrieve shared data diff --git a/internal/sbi/processor/session_management_subscription_data_retrieval.go b/internal/sbi/processor/session_management_subscription_data_retrieval.go index fb77adb..de3a147 100644 --- a/internal/sbi/processor/session_management_subscription_data_retrieval.go +++ b/internal/sbi/processor/session_management_subscription_data_retrieval.go @@ -4,9 +4,10 @@ import ( "net/http" "net/url" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetSmData - retrieve a UE's Session Management Subscription Data @@ -51,5 +52,4 @@ func (p *Processor) HandleGetSmData(c *gin.Context) { c.JSON(http.StatusForbidden, problemDetails) return } - } diff --git a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go index 6254334..8b66fbe 100644 --- a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go +++ b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go @@ -4,9 +4,10 @@ import ( "net/http" "net/url" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetNssai - retrieve a UE's subscribed NSSAI @@ -47,5 +48,4 @@ func (p *Processor) HandleGetNssai(c *gin.Context) { c.JSON(http.StatusForbidden, problemDetails) return } - } diff --git a/internal/sbi/processor/smf_deregistration.go b/internal/sbi/processor/smf_deregistration.go index a4e70e2..c5e6dda 100644 --- a/internal/sbi/processor/smf_deregistration.go +++ b/internal/sbi/processor/smf_deregistration.go @@ -3,13 +3,13 @@ package processor import ( "net/http" - "github.com/free5gc/udm/internal/logger" "github.com/gin-gonic/gin" + + "github.com/free5gc/udm/internal/logger" ) // DeregistrationSmfRegistrations - delete an SMF registration func (p *Processor) HandleDeregistrationSmfRegistrations(c *gin.Context) { - // step 1: log logger.UecmLog.Infof("Handle DeregistrationSmfRegistrations") @@ -28,5 +28,4 @@ func (p *Processor) HandleDeregistrationSmfRegistrations(c *gin.Context) { c.Status(http.StatusNoContent) return } - } diff --git a/internal/sbi/processor/smf_registration.go b/internal/sbi/processor/smf_registration.go index 0561001..ce8038f 100644 --- a/internal/sbi/processor/smf_registration.go +++ b/internal/sbi/processor/smf_registration.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // RegistrationSmfRegistrations - register as SMF @@ -49,7 +50,11 @@ func (p *Processor) HandleRegistrationSmfRegistrations(c *gin.Context) { pduSessionID := c.Params.ByName("pduSessionId") // step 3: handle the message - header, response, problemDetails := p.consumer.RegistrationSmfRegistrationsProcedure(&smfRegistration, ueID, pduSessionID) + header, response, problemDetails := p.consumer.RegistrationSmfRegistrationsProcedure( + &smfRegistration, + ueID, + pduSessionID, + ) // step 4: process the return value from step 3 if response != nil { @@ -67,5 +72,4 @@ func (p *Processor) HandleRegistrationSmfRegistrations(c *gin.Context) { c.Status(http.StatusNoContent) return } - } diff --git a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go index c262dc2..3b2b16f 100644 --- a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go +++ b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go @@ -4,9 +4,10 @@ import ( "net/http" "net/url" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data @@ -47,5 +48,4 @@ func (p *Processor) HandleGetSmfSelectData(c *gin.Context) { c.JSON(http.StatusForbidden, problemDetails) return } - } diff --git a/internal/sbi/processor/subscription_creation.go b/internal/sbi/processor/subscription_creation.go index 578accf..bc40cd9 100644 --- a/internal/sbi/processor/subscription_creation.go +++ b/internal/sbi/processor/subscription_creation.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // Subscribe - subscribe to notifications diff --git a/internal/sbi/processor/subscription_creation_for_shared_data.go b/internal/sbi/processor/subscription_creation_for_shared_data.go index 232b9ef..45ac439 100644 --- a/internal/sbi/processor/subscription_creation_for_shared_data.go +++ b/internal/sbi/processor/subscription_creation_for_shared_data.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // SubscribeToSharedData - subscribe to notifications for shared data @@ -48,7 +49,7 @@ func (p *Processor) HandleSubscribeToSharedData(c *gin.Context) { // step 3: handle the message header, response, problemDetails := p.consumer.SubscribeToSharedDataProcedure(&sharedDataSubsReq) - //var rsp *httpwrapper.Response + // var rsp *httpwrapper.Response // step 4: process the return value from step 3 if response != nil { // status code is based on SPEC, and option headers @@ -70,5 +71,4 @@ func (p *Processor) HandleSubscribeToSharedData(c *gin.Context) { c.JSON(http.StatusInternalServerError, problemDetails) return } - } diff --git a/internal/sbi/processor/subscription_deletion.go b/internal/sbi/processor/subscription_deletion.go index b06373e..71553e5 100644 --- a/internal/sbi/processor/subscription_deletion.go +++ b/internal/sbi/processor/subscription_deletion.go @@ -3,13 +3,13 @@ package processor import ( "net/http" - "github.com/free5gc/udm/internal/logger" "github.com/gin-gonic/gin" + + "github.com/free5gc/udm/internal/logger" ) // Unsubscribe - unsubscribe from notifications func (p *Processor) HandleUnsubscribe(c *gin.Context) { - logger.SdmLog.Infof("Handle Unsubscribe") // step 2: retrieve request diff --git a/internal/sbi/processor/subscription_deletion_for_shared_data.go b/internal/sbi/processor/subscription_deletion_for_shared_data.go index 70e2d9e..3a6d5ce 100644 --- a/internal/sbi/processor/subscription_deletion_for_shared_data.go +++ b/internal/sbi/processor/subscription_deletion_for_shared_data.go @@ -3,8 +3,9 @@ package processor import ( "net/http" - "github.com/free5gc/udm/internal/logger" "github.com/gin-gonic/gin" + + "github.com/free5gc/udm/internal/logger" ) // UnsubscribeForSharedData - unsubscribe from notifications for shared data @@ -24,5 +25,4 @@ func (p *Processor) HandleUnsubscribeForSharedData(c *gin.Context) { c.Status(http.StatusNoContent) return } - } diff --git a/internal/sbi/processor/subscription_modification.go b/internal/sbi/processor/subscription_modification.go index 8c44732..29eaac7 100644 --- a/internal/sbi/processor/subscription_modification.go +++ b/internal/sbi/processor/subscription_modification.go @@ -3,10 +3,11 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // Modify - modify the subscription @@ -59,7 +60,6 @@ func (p *Processor) HandleModify(c *gin.Context) { c.JSON(int(problemDetails.Status), problemDetails) return } else { - problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", diff --git a/internal/sbi/processor/trace_configuration_data_retrieval.go b/internal/sbi/processor/trace_configuration_data_retrieval.go index 9617e71..92672a6 100644 --- a/internal/sbi/processor/trace_configuration_data_retrieval.go +++ b/internal/sbi/processor/trace_configuration_data_retrieval.go @@ -3,9 +3,10 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetTraceData - retrieve a UE's Trace Configuration Data @@ -36,5 +37,4 @@ func (p *Processor) HandleGetTraceData(c *gin.Context) { c.JSON(http.StatusForbidden, problemDetails) return } - } diff --git a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go index eef77d2..1a6e50f 100644 --- a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go +++ b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go @@ -3,14 +3,14 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" "github.com/free5gc/udm/internal/logger" - "github.com/gin-gonic/gin" ) // GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data func (p *Processor) HandleGetUeContextInSmfData(c *gin.Context) { - // step 1: log logger.SdmLog.Infof("Handle GetUeContextInSmfData") @@ -37,5 +37,4 @@ func (p *Processor) HandleGetUeContextInSmfData(c *gin.Context) { c.JSON(http.StatusForbidden, problemDetails) return } - } diff --git a/internal/sbi/router.go b/internal/sbi/router.go index 604c834..4be6bdf 100644 --- a/internal/sbi/router.go +++ b/internal/sbi/router.go @@ -35,7 +35,6 @@ func AddService(group *gin.RouterGroup, routes []Route) { group.PATCH(route.Pattern, route.HandlerFunc) } } - } func AddSDMService(group *gin.RouterGroup, routes []Route) { @@ -70,5 +69,4 @@ func AddUEAUService(group *gin.RouterGroup, routes []Route) { group.PATCH(route.Pattern, route.HandlerFunc) } } - } diff --git a/internal/sbi/server.go b/internal/sbi/server.go index ca0d3e2..ba5755e 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -9,29 +9,21 @@ import ( "sync" "time" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/pkg/app" - "github.com/free5gc/udm/pkg/factory" - "github.com/free5gc/util/httpwrapper" + "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/free5gc/openapi/models" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" "github.com/free5gc/udm/internal/sbi/consumer" "github.com/free5gc/udm/internal/sbi/processor" "github.com/free5gc/udm/internal/util" + "github.com/free5gc/udm/pkg/app" + "github.com/free5gc/udm/pkg/factory" + "github.com/free5gc/util/httpwrapper" logger_util "github.com/free5gc/util/logger" - "github.com/gin-gonic/gin" ) -type udm interface { - Config() *factory.Config - Context() *udm_context.UdmNFContext - CancelContext() context.Context - //Consumer() *consumer.Consumer - // Processor() *processor.Processor -} - type ServerUdm interface { app.App @@ -71,7 +63,6 @@ func NewServer(udm ServerUdm, tlsKeyLogPath string) (*Server, error) { }*/ return s, err - } func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { @@ -163,13 +154,6 @@ func (s *Server) shutdownHttpServer() { } } -func bindRouter(cfg *factory.Config, router *gin.Engine, tlsKeyLogPath string) (*http.Server, error) { - sbiConfig := cfg.Configuration.Sbi - bindAddr := fmt.Sprintf("%s:%d", sbiConfig.BindingIPv4, sbiConfig.Port) - - return httpwrapper.NewHttp2Server(bindAddr, tlsKeyLogPath, router) -} - func newRouter(s *Server) *gin.Engine { router := logger_util.NewGinWithLogrus(logger.GinLog) @@ -237,23 +221,3 @@ func newRouter(s *Server) *gin.Engine { return router } - -func (s *Server) unsecureServe() error { - return s.httpServer.ListenAndServe() -} - -func (s *Server) secureServe() error { - sbiConfig := s.Config().Configuration.Sbi - - pemPath := sbiConfig.Tls.Pem - if pemPath == "" { - pemPath = factory.UdmConfig.GetCertKeyPath() - } - - keyPath := sbiConfig.Tls.Key - if keyPath == "" { - keyPath = factory.UdmConfig.GetCertKeyPath() - } - - return s.httpServer.ListenAndServeTLS(pemPath, keyPath) -} diff --git a/pkg/factory/config.go b/pkg/factory/config.go index f1f7675..3aeb89a 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -124,6 +124,7 @@ func (c *Configuration) validate() (bool, error) { result, err := govalidator.ValidateStruct(c) return result, err } + func (c *Config) GetCertPemPath() string { c.RLock() defer c.RUnlock() diff --git a/pkg/service/init.go b/pkg/service/init.go index 64eba23..8283b81 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -1,7 +1,6 @@ package service import ( - "context" "io" "os" From dfb83129fa93938bf4ab8411291e8b48abaa227e Mon Sep 17 00:00:00 2001 From: ubuntu Date: Wed, 22 May 2024 07:53:28 +0000 Subject: [PATCH 09/23] feat: move procedure, hand func --- internal/sbi/api_eventexposure.go | 125 +- internal/sbi/api_httpcallback.go | 61 +- internal/sbi/api_parameterprovision.go | 63 +- internal/sbi/api_subscriberdatamanagement.go | 851 +++++- internal/sbi/api_ueauthentication.go | 130 +- internal/sbi/api_uecontextmanagement.go | 442 +++- internal/sbi/consumer/udm_service.go | 197 +- internal/sbi/consumer/udr_service.go | 2285 +---------------- ...nd_mobility_subscription_data_retrieval.go | 74 - ..._gpp_access_registration_info_retrieval.go | 40 - ..._gpp_access_registration_info_retrieval.go | 45 - .../amf_registration_for3_gpp_access.go | 73 - .../amf_registration_for_non3_gpp_access.go | 68 - internal/sbi/processor/callback.go | 98 + internal/sbi/processor/confirm_auth.go | 57 - .../data_change_notification_to_nf.go | 57 - internal/sbi/processor/ee_subscription.go | 126 - internal/sbi/processor/enent_exposure.go | 209 ++ internal/sbi/processor/generate_auth_data.go | 563 +++- .../sbi/processor/gpsi_to_supi_translation.go | 41 - internal/sbi/processor/index.go | 11 - internal/sbi/processor/parameter_provision.go | 37 + ...in_the_amf_registration_for3_gpp_access.go | 62 - ...he_amf_registration_for_non3_gpp_access.go | 61 - ..._acknowledgement_of_steering_of_roaming.go | 12 - ...acknowledgement_of_ue_parameters_update.go | 12 - .../retrieval_of_multiple_data_sets.go | 54 - .../sbi/processor/retrieval_of_shared_data.go | 39 - internal/sbi/processor/sdm_route.go | 203 -- ..._management_subscription_data_retrieval.go | 55 - ...e_selection_subscription_data_retrieval.go | 51 - internal/sbi/processor/smf_deregistration.go | 31 - internal/sbi/processor/smf_registration.go | 75 - ...f_selection_subscription_data_retrieval.go | 51 - ..._management_subscription_data_retrieval.go | 12 - .../sms_subscription_data_retrieval.go | 12 - ..._gpp_access_registration_info_retrieval.go | 12 - .../smsf_deregistration_for3_gpp_access.go | 12 - ...smsf_deregistration_for_non3_gpp_access.go | 12 - ..._gpp_access_registration_info_retrieval.go | 12 - .../smsf_registration_for3_gpp_access.go | 12 - .../smsf_registration_for_non3_gpp_access.go | 12 - .../processor/subscriber_data_management.go | 1127 ++++++++ .../sbi/processor/subscription_creation.go | 69 - .../subscription_creation_for_shared_data.go | 74 - .../sbi/processor/subscription_data_update.go | 59 - .../sbi/processor/subscription_deletion.go | 30 - .../subscription_deletion_for_shared_data.go | 28 - .../processor/subscription_modification.go | 129 - .../trace_configuration_data_retrieval.go | 40 - .../ue_context_in_smf_data_retrieval.go | 40 - .../ue_context_in_smsf_data_retrieval.go | 12 - .../sbi/processor/ue_context_management.go | 513 ++++ internal/sbi/processor/ueau_route.go | 18 - internal/sbi/server.go | 8 +- 55 files changed, 4156 insertions(+), 4446 deletions(-) delete mode 100644 internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go delete mode 100644 internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/processor/amf_registration_for3_gpp_access.go delete mode 100644 internal/sbi/processor/amf_registration_for_non3_gpp_access.go create mode 100644 internal/sbi/processor/callback.go delete mode 100644 internal/sbi/processor/confirm_auth.go delete mode 100644 internal/sbi/processor/data_change_notification_to_nf.go delete mode 100644 internal/sbi/processor/ee_subscription.go create mode 100644 internal/sbi/processor/enent_exposure.go delete mode 100644 internal/sbi/processor/gpsi_to_supi_translation.go delete mode 100644 internal/sbi/processor/index.go create mode 100644 internal/sbi/processor/parameter_provision.go delete mode 100644 internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go delete mode 100644 internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go delete mode 100644 internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go delete mode 100644 internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go delete mode 100644 internal/sbi/processor/retrieval_of_multiple_data_sets.go delete mode 100644 internal/sbi/processor/retrieval_of_shared_data.go delete mode 100644 internal/sbi/processor/sdm_route.go delete mode 100644 internal/sbi/processor/session_management_subscription_data_retrieval.go delete mode 100644 internal/sbi/processor/slice_selection_subscription_data_retrieval.go delete mode 100644 internal/sbi/processor/smf_deregistration.go delete mode 100644 internal/sbi/processor/smf_registration.go delete mode 100644 internal/sbi/processor/smf_selection_subscription_data_retrieval.go delete mode 100644 internal/sbi/processor/sms_management_subscription_data_retrieval.go delete mode 100644 internal/sbi/processor/sms_subscription_data_retrieval.go delete mode 100644 internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/processor/smsf_deregistration_for3_gpp_access.go delete mode 100644 internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go delete mode 100644 internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/processor/smsf_registration_for3_gpp_access.go delete mode 100644 internal/sbi/processor/smsf_registration_for_non3_gpp_access.go create mode 100644 internal/sbi/processor/subscriber_data_management.go delete mode 100644 internal/sbi/processor/subscription_creation.go delete mode 100644 internal/sbi/processor/subscription_creation_for_shared_data.go delete mode 100644 internal/sbi/processor/subscription_data_update.go delete mode 100644 internal/sbi/processor/subscription_deletion.go delete mode 100644 internal/sbi/processor/subscription_deletion_for_shared_data.go delete mode 100644 internal/sbi/processor/subscription_modification.go delete mode 100644 internal/sbi/processor/trace_configuration_data_retrieval.go delete mode 100644 internal/sbi/processor/ue_context_in_smf_data_retrieval.go delete mode 100644 internal/sbi/processor/ue_context_in_smsf_data_retrieval.go create mode 100644 internal/sbi/processor/ue_context_management.go delete mode 100644 internal/sbi/processor/ueau_route.go diff --git a/internal/sbi/api_eventexposure.go b/internal/sbi/api_eventexposure.go index f4d2a4b..056b0df 100644 --- a/internal/sbi/api_eventexposure.go +++ b/internal/sbi/api_eventexposure.go @@ -1,7 +1,14 @@ package sbi import ( + "net/http" "strings" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" ) func (s *Server) getEventExposureRoutes() []Route { @@ -10,28 +17,138 @@ func (s *Server) getEventExposureRoutes() []Route { "Index", "GET", "/", - s.Processor().HandleIndex, + s.HandleIndex, }, { "HTTPCreateEeSubscription", strings.ToUpper("Post"), "/:ueIdentity/ee-subscriptions", - s.Processor().HandleCreateEeSubscription, + s.HandleCreateEeSubscription, }, { "HTTPDeleteEeSubscription", strings.ToUpper("Delete"), "/:ueIdentity/ee-subscriptions/:subscriptionId", - s.Processor().HandleDeleteEeSubscription, + s.HandleDeleteEeSubscription, }, { "HTTPUpdateEeSubscription", strings.ToUpper("Patch"), "/:ueIdentity/ee-subscriptions/:subscriptionId", - s.Processor().HandleUpdateEeSubscription, + s.HandleUpdateEeSubscription, }, } } + +// HTTPCreateEeSubscription - Subscribe +func (s *Server) HandleCreateEeSubscription(c *gin.Context) { + var eesubscription models.EeSubscription + + requestBody, err := c.GetRawData() + if err != nil { + logger.EeLog.Errorf("Get Request Body error: %+v", err) + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&eesubscription, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.EeLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // Start + logger.EeLog.Infoln("Handle Create EE Subscription") + + ueIdentity := c.Params.ByName("ueIdentity") + + createdEESubscription, problemDetails := s.Processor().CreateEeSubscriptionProcedure(ueIdentity, eesubscription) + if createdEESubscription != nil { + c.JSON(http.StatusCreated, createdEESubscription) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + c.JSON(http.StatusInternalServerError, problemDetails) + return + } +} + +func (s *Server) HandleDeleteEeSubscription(c *gin.Context) { + ueIdentity := c.Params.ByName("ueIdentity") + subscriptionID := c.Params.ByName("subscriptionId") + + s.Processor().DeleteEeSubscriptionProcedure(ueIdentity, subscriptionID) + // only return 204 no content + c.Status(http.StatusNoContent) +} + +func (s *Server) HandleUpdateEeSubscription(c *gin.Context) { + var patchList []models.PatchItem + + requestBody, err := c.GetRawData() + if err != nil { + logger.EeLog.Errorf("Get Request Body error: %+v", err) + problemDetail := models.ProblemDetails{ + Title: "System failure", + Status: http.StatusInternalServerError, + Detail: err.Error(), + Cause: "SYSTEM_FAILURE", + } + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + err = openapi.Deserialize(&patchList, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.EeLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + ueIdentity := c.Params.ByName("ueIdentity") + subscriptionID := c.Params.ByName("subscriptionId") + + logger.EeLog.Infoln("Handle Update EE subscription") + logger.EeLog.Warnln("Update EE Subscription is not implemented") + + problemDetails := s.Processor().UpdateEeSubscriptionProcedure(ueIdentity, subscriptionID, patchList) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +func (s *Server) HandleIndex(c *gin.Context) { + c.String(http.StatusOK, "Hello World!") +} diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index 5d149e8..b07e2b1 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -1,6 +1,15 @@ package sbi -import "strings" +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) func (s *Server) getHttpCallBackRoutes() []Route { return []Route{ @@ -8,14 +17,60 @@ func (s *Server) getHttpCallBackRoutes() []Route { "Index", "GET", "/", - s.Processor().HandleIndex, + s.HandleIndex, }, { "DataChangeNotificationToNF", strings.ToUpper("Post"), "/sdm-subscriptions", - s.Processor().HandleDataChangeNotificationToNF, + s.HandleDataChangeNotificationToNF, }, } } + +func (s *Server) HandleDataChangeNotificationToNF(c *gin.Context) { + var dataChangeNotify models.DataChangeNotify + // 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.CallbackLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&dataChangeNotify, 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 + } + + supi := c.Params.ByName("supi") + + logger.CallbackLog.Infof("Handle DataChangeNotificationToNF") + + problemDetails := s.Processor().DataChangeNotificationProcedure(dataChangeNotify.NotifyItems, supi) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} diff --git a/internal/sbi/api_parameterprovision.go b/internal/sbi/api_parameterprovision.go index 3d627d1..b272ec6 100644 --- a/internal/sbi/api_parameterprovision.go +++ b/internal/sbi/api_parameterprovision.go @@ -1,6 +1,15 @@ package sbi -import "strings" +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) func (s *Server) getParameterProvisionRoutes() []Route { return []Route{ @@ -8,14 +17,62 @@ func (s *Server) getParameterProvisionRoutes() []Route { "Index", "GET", "/", - s.Processor().HandleIndex, + s.HandleIndex, }, { "Update", strings.ToUpper("Patch"), "/:gpsi/pp-data", - s.Processor().HandleUpdate, + s.HandleUpdate, }, } } + +func (s *Server) HandleUpdate(c *gin.Context) { + var ppDataReq models.PpData + + // 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.PpLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&ppDataReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.PpLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + gpsi := c.Params.ByName("gpsi") + + logger.PpLog.Infoln("Handle UpdateRequest") + + // step 3: handle the message + problemDetails := s.Processor().UpdateProcedure(ppDataReq, gpsi) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} diff --git a/internal/sbi/api_subscriberdatamanagement.go b/internal/sbi/api_subscriberdatamanagement.go index a7c0361..6b4c8da 100644 --- a/internal/sbi/api_subscriberdatamanagement.go +++ b/internal/sbi/api_subscriberdatamanagement.go @@ -1,12 +1,861 @@ package sbi +import ( + "encoding/json" + "net/http" + "net/url" + "strings" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) + func (s *Server) getSubscriberDataManagementRoutes() []Route { return []Route{ { "Index", "GET", "/", - s.Processor().HandleIndex, + s.HandleIndex, + }, + } +} + +// GetAmData - retrieve a UE's Access and Mobility Subscription Data +func (s *Server) HandleGetAmData(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("supported-features", c.Query("plmn-id")) + + // step 1: log + logger.SdmLog.Infof("Handle GetAmData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + + plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := s.Processor().GetAmDataProcedure(supi, plmnID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +func (s *Server) getPlmnIDStruct( + queryParameters url.Values, +) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { + if queryParameters["plmn-id"] != nil { + plmnIDJson := queryParameters["plmn-id"][0] + plmnIDStruct := &models.PlmnId{} + err := json.Unmarshal([]byte(plmnIDJson), plmnIDStruct) + if err != nil { + logger.SdmLog.Warnln("Unmarshal Error in targetPlmnListtruct: ", err) + } + return plmnIDStruct, nil + } else { + problemDetails := &models.ProblemDetails{ + Title: "Invalid Parameter", + Status: http.StatusBadRequest, + Cause: "No get plmn-id", + } + return nil, problemDetails + } +} + +// Info - Nudm_Sdm Info service operation +func (s *Server) HandleInfo(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// PutUpuAck - Nudm_Sdm Info for UPU service operation +func (s *Server) HandlePutUpuAck(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data +func (s *Server) HandleGetSmfSelectData(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetSmfSelectData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := s.Processor().GetSmfSelectDataProcedure(supi, plmnID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// GetSmsMngData - retrieve a UE's SMS Management Subscription Data +func (s *Server) HandleGetSmsMngData(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// GetSmsData - retrieve a UE's SMS Subscription Data +func (s *Server) HandleGetSmsData(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// GetSupi - retrieve multiple data sets +func (s *Server) HandleGetSupi(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("dataset-names", c.Query("dataset-names")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetSupiRequest") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + dataSetNames := strings.Split(query.Get("dataset-names"), ",") + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := s.Processor().GetSupiProcedure(supi, plmnID, dataSetNames, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// GetSharedData - retrieve shared data +func (s *Server) HandleGetSharedData(c *gin.Context) { + // step 1: log + logger.SdmLog.Infof("Handle GetSharedData") + + // step 2: retrieve request + sharedDataIds := c.QueryArray("shared-data-ids") + supportedFeatures := c.QueryArray("supported-features") + // step 3: handle the message + response, problemDetails := s.Processor().GetSharedDataProcedure(sharedDataIds, supportedFeatures[0]) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// SubscribeToSharedData - subscribe to notifications for shared data +func (s *Server) HandleSubscribeToSharedData(c *gin.Context) { + var sharedDataSubsReq models.SdmSubscription + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sharedDataSubsReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle SubscribeToSharedData") + + // step 2: retrieve request + + // step 3: handle the message + header, response, problemDetails := s.Processor().SubscribeToSharedDataProcedure(&sharedDataSubsReq) + + // var rsp *httpwrapper.Response + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + // step 5: response + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + return + } +} + +// Subscribe - subscribe to notifications +func (s *Server) HandleSubscribe(c *gin.Context) { + var sdmSubscriptionReq models.SdmSubscription + + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sdmSubscriptionReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle Subscribe") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + + // step 3: handle the message + header, response, problemDetails := s.Processor().SubscribeProcedure(&sdmSubscriptionReq, supi) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNotFound) + return + } +} + +// Unsubscribe - unsubscribe from notifications +func (s *Server) HandleUnsubscribe(c *gin.Context) { + logger.SdmLog.Infof("Handle Unsubscribe") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + subscriptionID := c.Params.ByName("subscriptionId") + + // step 3: handle the message + problemDetails := s.Processor().UnsubscribeProcedure(supi, subscriptionID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +// UnsubscribeForSharedData - unsubscribe from notifications for shared data +func (s *Server) HandleUnsubscribeForSharedData(c *gin.Context) { + logger.SdmLog.Infof("Handle UnsubscribeForSharedData") + + // step 2: retrieve request + subscriptionID := c.Params.ByName("subscriptionId") + // step 3: handle the message + problemDetails := s.Processor().UnsubscribeForSharedDataProcedure(subscriptionID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +// Modify - modify the subscription +func (s *Server) HandleModify(c *gin.Context) { + var sdmSubsModificationReq models.SdmSubsModification + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sdmSubsModificationReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle Modify") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + subscriptionID := c.Params.ByName("subscriptionId") + + // step 3: handle the message + response, problemDetails := s.Processor().ModifyProcedure(&sdmSubsModificationReq, supi, subscriptionID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// ModifyForSharedData - modify the subscription +func (s *Server) HandleModifyForSharedData(c *gin.Context) { + var sharedDataSubscriptions models.SdmSubsModification + // 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.SdmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&sharedDataSubscriptions, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.SdmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.SdmLog.Infof("Handle ModifyForSharedData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + subscriptionID := c.Params.ByName("subscriptionId") + + // step 3: handle the message + response, problemDetails := s.Processor().ModifyForSharedDataProcedure(&sharedDataSubscriptions, supi, subscriptionID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// GetTraceData - retrieve a UE's Trace Configuration Data +func (s *Server) HandleGetTraceData(c *gin.Context) { + // step 1: log + logger.SdmLog.Infof("Handle GetTraceData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnID := c.Query("plmn-id") + + // step 3: handle the message + response, problemDetails := s.Processor().GetTraceDataProcedure(supi, plmnID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data +func (s *Server) HandleGetUeContextInSmfData(c *gin.Context) { + // step 1: log + logger.SdmLog.Infof("Handle GetUeContextInSmfData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + supportedFeatures := c.Query("supported-features") + + // step 3: handle the message + response, problemDetails := s.Processor().GetUeContextInSmfDataProcedure(supi, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// GetUeContextInSmsfData - retrieve a UE's UE Context In SMSF Data +func (s *Server) HandleGetUeContextInSmsfData(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// GetNssai - retrieve a UE's subscribed NSSAI +func (s *Server) HandleGetNssai(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetNssai") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := s.Processor().GetNssaiProcedure(supi, plmnID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// GetSmData - retrieve a UE's Session Management Subscription Data +func (s *Server) HandleGetSmData(c *gin.Context) { + var query url.Values + query.Set("plmn-id", c.Query("plmn-id")) + query.Set("dnn", c.Query("dnn")) + query.Set("single-nssai", c.Query("single-nssai")) + query.Set("supported-features", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetSmData") + + // step 2: retrieve request + supi := c.Params.ByName("supi") + plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } + plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc + Dnn := query.Get("dnn") + Snssai := query.Get("single-nssai") + supportedFeatures := query.Get("supported-features") + + // step 3: handle the message + response, problemDetails := s.Processor().GetSmDataProcedure(supi, plmnID, Dnn, Snssai, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// GetIdTranslationResult - retrieve a UE's SUPI +func (s *Server) HandleGetIdTranslationResult(c *gin.Context) { + // req.Query.Set("SupportedFeatures", c.Query("supported-features")) + + // step 1: log + logger.SdmLog.Infof("Handle GetIdTranslationResultRequest") + + // step 2: retrieve request + gpsi := c.Params.ByName("gpsi") + + // step 3: handle the message + response, problemDetails := s.Processor().GetIdTranslationResultProcedure(gpsi) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +func (s *Server) OneLayerPathHandlerFunc(c *gin.Context) { + supi := c.Param("supi") + oneLayerPathRouter := s.getOneLayerRoutes() + for _, route := range oneLayerPathRouter { + if strings.Contains(route.Pattern, supi) && route.Method == c.Request.Method { + route.HandlerFunc(c) + return + } + } + + // special case for :supi + if c.Request.Method == strings.ToUpper("Get") { + s.HandleGetSupi(c) + return + } + + c.String(http.StatusNotFound, "404 page not found") +} + +func (s *Server) TwoLayerPathHandlerFunc(c *gin.Context) { + supi := c.Param("supi") + op := c.Param("subscriptionId") + + // for "/shared-data-subscriptions/:subscriptionId" + if supi == "shared-data-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { + s.HandleUnsubscribeForSharedData(c) + return + } + + // for "/shared-data-subscriptions/:subscriptionId" + if supi == "shared-data-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { + s.HandleModifyForSharedData(c) + return + } + + // for "/:gpsi/id-translation-result" + if op == "id-translation-result" && strings.ToUpper("Get") == c.Request.Method { + c.Params = append(c.Params, gin.Param{Key: "gpsi", Value: c.Param("supi")}) + s.HandleGetIdTranslationResult(c) + return + } + + twoLayerPathRouter := s.getTwoLayerRoutes() + for _, route := range twoLayerPathRouter { + if strings.Contains(route.Pattern, op) && route.Method == c.Request.Method { + route.HandlerFunc(c) + return + } + } + + c.String(http.StatusNotFound, "404 page not found") +} + +func (s *Server) ThreeLayerPathHandlerFunc(c *gin.Context) { + op := c.Param("subscriptionId") + + // for "/:supi/sdm-subscriptions/:subscriptionId" + if op == "sdm-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { + var tmpParams gin.Params + tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) + tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) + c.Params = tmpParams + s.HandleUnsubscribe(c) + return + } + + // for "/:supi/am-data/sor-ack" + if op == "am-data" && strings.ToUpper("Put") == c.Request.Method { + s.HandleInfo(c) + return + } + + // for "/:supi/sdm-subscriptions/:subscriptionId" + if op == "sdm-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { + var tmpParams gin.Params + tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) + tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) + c.Params = tmpParams + s.HandleModify(c) + return + } + + c.String(http.StatusNotFound, "404 page not found") +} + +func (s *Server) getOneLayerRoutes() []Route { + return []Route{ + { + "GetSupi", + strings.ToUpper("Get"), + "/:supi", + s.HandleGetSupi, + }, + + { + "GetSharedData", + strings.ToUpper("Get"), + "/shared-data", + s.HandleGetSharedData, + }, + + { + "SubscribeToSharedData", + strings.ToUpper("Post"), + "/shared-data-subscriptions", + s.HandleSubscribeToSharedData, + }, + } +} + +func (s *Server) getTwoLayerRoutes() []Route { + return []Route{ + { + "GetAmData", + strings.ToUpper("Get"), + "/:supi/am-data", + s.HandleGetAmData, + }, + + { + "GetSmfSelectData", + strings.ToUpper("Get"), + "/:supi/smf-select-data", + s.HandleGetSmfSelectData, + }, + + { + "GetSmsMngData", + strings.ToUpper("Get"), + "/:supi/sms-mng-data", + s.HandleGetSmsMngData, + }, + + { + "GetSmsData", + strings.ToUpper("Get"), + "/:supi/sms-data", + s.HandleGetSmsData, + }, + + { + "GetSmData", + strings.ToUpper("Get"), + "/:supi/sm-data", + s.HandleGetSmData, + }, + + { + "GetNssai", + strings.ToUpper("Get"), + "/:supi/nssai", + s.HandleGetNssai, + }, + + { + "Subscribe", + strings.ToUpper("Post"), + "/:supi/sdm-subscriptions", + s.HandleSubscribe, + }, + + { + "GetTraceData", + strings.ToUpper("Get"), + "/:supi/trace-data", + s.HandleGetTraceData, + }, + + { + "GetUeContextInSmfData", + strings.ToUpper("Get"), + "/:supi/ue-context-in-smf-data", + s.HandleGetUeContextInSmfData, + }, + + { + "GetUeContextInSmsfData", + strings.ToUpper("Get"), + "/:supi/ue-context-in-smsf-data", + s.HandleGetUeContextInSmsfData, }, } } diff --git a/internal/sbi/api_ueauthentication.go b/internal/sbi/api_ueauthentication.go index 6b490ce..8fa5017 100644 --- a/internal/sbi/api_ueauthentication.go +++ b/internal/sbi/api_ueauthentication.go @@ -1,6 +1,15 @@ package sbi -import "strings" +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) func (s *Server) getUEAuthenticationRoutes() []Route { return []Route{ @@ -8,14 +17,129 @@ func (s *Server) getUEAuthenticationRoutes() []Route { "Index", "GET", "/", - s.Processor().HandleIndex, + s.HandleIndex, }, { "ConfirmAuth", strings.ToUpper("Post"), "/:supi/auth-events", - s.Processor().HandleConfirmAuth, + s.HandleConfirmAuth, }, } } + +// ConfirmAuth - Create a new confirmation event +func (s *Server) HandleConfirmAuth(c *gin.Context) { + var authEvent models.AuthEvent + // 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.UeauLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&authEvent, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UeauLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + supi := c.Params.ByName("supi") + + logger.UeauLog.Infoln("Handle ConfirmAuthDataRequest") + + problemDetails := s.Processor().ConfirmAuthDataProcedure(authEvent, supi) + + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusCreated) + return + } +} + +// GenerateAuthData - Generate authentication data for the UE +func (s *Server) HandleGenerateAuthData(c *gin.Context) { + var authInfoReq models.AuthenticationInfoRequest + + // 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.UeauLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&authInfoReq, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UeauLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UeauLog.Infoln("Handle GenerateAuthDataRequest") + + // step 2: retrieve request + supiOrSuci := c.Param("supiOrSuci") + + // step 3: handle the message + response, problemDetails := s.Processor().GenerateAuthDataProcedure(authInfoReq, supiOrSuci) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +func (s *Server) GenAuthDataHandlerFunc(c *gin.Context) { + c.Params = append(c.Params, gin.Param{Key: "supiOrSuci", Value: c.Param("supi")}) + if strings.ToUpper("Post") == c.Request.Method { + s.HandleGenerateAuthData(c) + return + } + + c.String(http.StatusNotFound, "404 page not found") +} diff --git a/internal/sbi/api_uecontextmanagement.go b/internal/sbi/api_uecontextmanagement.go index 5d87060..00b6cc7 100644 --- a/internal/sbi/api_uecontextmanagement.go +++ b/internal/sbi/api_uecontextmanagement.go @@ -1,6 +1,17 @@ package sbi -import "strings" +import ( + "net/http" + "strings" + + "github.com/antihax/optional" + "github.com/gin-gonic/gin" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nudr_DataRepository" + "github.com/free5gc/openapi/models" + "github.com/free5gc/udm/internal/logger" +) func (s *Server) getUEContextManagementRoutes() []Route { return []Route{ @@ -8,105 +19,504 @@ func (s *Server) getUEContextManagementRoutes() []Route { "Index", "GET", "/", - s.Processor().HandleIndex, + s.HandleIndex, }, { "GetAmf3gppAccess", strings.ToUpper("Get"), "/:ueId/registrations/amf-3gpp-access", - s.Processor().HandleGetAmf3gppAccess, + s.HandleGetAmf3gppAccess, }, { "GetAmfNon3gppAccess", strings.ToUpper("Get"), "/:ueId/registrations/amf-non-3gpp-access", - s.Processor().HandleGetAmfNon3gppAccess, + s.HandleGetAmfNon3gppAccess, }, { "RegistrationAmf3gppAccess", strings.ToUpper("Put"), "/:ueId/registrations/amf-3gpp-access", - s.Processor().HandleRegistrationAmf3gppAccess, + s.HandleRegistrationAmf3gppAccess, }, { "Register", strings.ToUpper("Put"), "/:ueId/registrations/amf-non-3gpp-access", - s.Processor().HandleRegistrationAmfNon3gppAccess, + s.HandleRegistrationAmfNon3gppAccess, }, { "UpdateAmf3gppAccess", strings.ToUpper("Patch"), "/:ueId/registrations/amf-3gpp-access", - s.Processor().HandleUpdateAmf3gppAccess, + s.HandleUpdateAmf3gppAccess, }, { "UpdateAmfNon3gppAccess", strings.ToUpper("Patch"), "/:ueId/registrations/amf-non-3gpp-access", - s.Processor().HandleUpdateAmfNon3gppAccess, + s.HandleUpdateAmfNon3gppAccess, }, { "DeregistrationSmfRegistrations", strings.ToUpper("Delete"), "/:ueId/registrations/smf-registrations/:pduSessionId", - s.Processor().HandleDeregistrationSmfRegistrations, + s.HandleDeregistrationSmfRegistrations, }, { "RegistrationSmfRegistrations", strings.ToUpper("Put"), "/:ueId/registrations/smf-registrations/:pduSessionId", - s.Processor().HandleRegistrationSmfRegistrations, + s.HandleRegistrationSmfRegistrations, }, { "GetSmsf3gppAccess", strings.ToUpper("Get"), "/:ueId/registrations/smsf-3gpp-access", - s.Processor().HandleGetSmsf3gppAccess, + s.HandleGetSmsf3gppAccess, }, { "DeregistrationSmsf3gppAccess", strings.ToUpper("Delete"), "/:ueId/registrations/smsf-3gpp-access", - s.Processor().HandleDeregistrationSmsf3gppAccess, + s.HandleDeregistrationSmsf3gppAccess, }, { "DeregistrationSmsfNon3gppAccess", strings.ToUpper("Delete"), "/:ueId/registrations/smsf-non-3gpp-access", - s.Processor().HandleDeregistrationSmsfNon3gppAccess, + s.HandleDeregistrationSmsfNon3gppAccess, }, { "GetSmsfNon3gppAccess", strings.ToUpper("Get"), "/:ueId/registrations/smsf-non-3gpp-access", - s.Processor().HandleGetSmsfNon3gppAccess, + s.HandleGetSmsfNon3gppAccess, }, { "UpdateSMSFReg3GPP", strings.ToUpper("Put"), "/:ueId/registrations/smsf-3gpp-access", - s.Processor().HandleUpdateSMSFReg3GPP, + s.HandleUpdateSMSFReg3GPP, }, { "RegistrationSmsfNon3gppAccess", strings.ToUpper("Put"), "/:ueId/registrations/smsf-non-3gpp-access", - s.Processor().HandleRegistrationSmsfNon3gppAccess, + s.HandleRegistrationSmsfNon3gppAccess, }, } } + +// GetAmfNon3gppAccess - retrieve the AMF registration for non-3GPP access information +func (s *Server) HandleGetAmfNon3gppAccess(c *gin.Context) { + // step 1: log + logger.UecmLog.Infoln("Handle GetAmfNon3gppAccessRequest") + + // step 2: retrieve request + ueId := c.Param("ueId") + supportedFeatures := c.Query("supported-features") + + var queryAmfContextNon3gppParamOpts Nudr_DataRepository.QueryAmfContextNon3gppParamOpts + queryAmfContextNon3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + // step 3: handle the message + + response, problemDetails := s.Processor().GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts, ueId) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} + +// Register - register as AMF for non-3GPP access +func (s *Server) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { + var amfNon3GppAccessRegistration models.AmfNon3GppAccessRegistration + + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amfNon3GppAccessRegistration, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + logger.UecmLog.Infof("Handle RegisterAmfNon3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + + // step 3: handle the message + header, response, problemDetails := s.Processor().RegisterAmfNon3gppAccessProcedure(amfNon3GppAccessRegistration, ueID) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +// RegistrationAmf3gppAccess - register as AMF for 3GPP access +func (s *Server) HandleRegistrationAmf3gppAccess(c *gin.Context) { + var amf3GppAccessRegistration models.Amf3GppAccessRegistration + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amf3GppAccessRegistration, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle RegistrationAmf3gppAccess") + + // step 2: retrieve request + ueID := c.Param("ueId") + logger.UecmLog.Info("UEID: ", ueID) + + // step 3: handle the message + header, response, problemDetails := s.Processor().RegistrationAmf3gppAccessProcedure(amf3GppAccessRegistration, ueID) + + // step 4: process the return value from step 3 + if response != nil { + if header != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +// UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access +func (s *Server) HandleUpdateAmfNon3gppAccess(c *gin.Context) { + var amfNon3GppAccessRegistrationModification models.AmfNon3GppAccessRegistrationModification + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amfNon3GppAccessRegistrationModification, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle UpdateAmfNon3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + + // step 3: handle the message + problemDetails := s.Processor().UpdateAmfNon3gppAccessProcedure(amfNon3GppAccessRegistrationModification, ueID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +// UpdateAmf3gppAccess - Update a parameter in the AMF registration for 3GPP access +func (s *Server) HandleUpdateAmf3gppAccess(c *gin.Context) { + var amf3GppAccessRegistrationModification models.Amf3GppAccessRegistrationModification + + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&amf3GppAccessRegistrationModification, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle UpdateAmf3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + + // step 3: handle the message + problemDetails := s.Processor().UpdateAmf3gppAccessProcedure(amf3GppAccessRegistrationModification, ueID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +// DeregistrationSmsfNon3gppAccess - delete SMSF registration for non 3GPP access +func (s *Server) HandleDeregistrationSmsfNon3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// DeregistrationSmsf3gppAccess - delete the SMSF registration for 3GPP access +func (s *Server) HandleDeregistrationSmsf3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// GetSmsfNon3gppAccess - retrieve the SMSF registration for non-3GPP access information +func (s *Server) HandleGetSmsfNon3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// RegistrationSmsfNon3gppAccess - register as SMSF for non-3GPP access +func (s *Server) HandleRegistrationSmsfNon3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// UpdateSMSFReg3GPP - register as SMSF for 3GPP access +func (s *Server) HandleUpdateSMSFReg3GPP(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// GetSmsf3gppAccess - retrieve the SMSF registration for 3GPP access information +func (s *Server) HandleGetSmsf3gppAccess(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{}) +} + +// DeregistrationSmfRegistrations - delete an SMF registration +func (s *Server) HandleDeregistrationSmfRegistrations(c *gin.Context) { + // step 1: log + logger.UecmLog.Infof("Handle DeregistrationSmfRegistrations") + + // step 2: retrieve request + ueID := c.Params.ByName("ueId") + pduSessionID := c.Params.ByName("pduSessionId") + + // step 3: handle the message + problemDetails := s.Processor().DeregistrationSmfRegistrationsProcedure(ueID, pduSessionID) + + // step 4: process the return value from step 3 + if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + c.Status(http.StatusNoContent) + return + } +} + +// RegistrationSmfRegistrations - register as SMF +func (s *Server) HandleRegistrationSmfRegistrations(c *gin.Context) { + var smfRegistration models.SmfRegistration + + // 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.UecmLog.Errorf("Get Request Body error: %+v", err) + c.JSON(http.StatusInternalServerError, problemDetail) + return + } + + // step 2: convert requestBody to openapi models + err = openapi.Deserialize(&smfRegistration, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.UecmLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + // step 1: log + logger.UecmLog.Infof("Handle RegistrationSmfRegistrations") + + // step 2: retrieve request + ueID := c.Params.ByName("ueId") + pduSessionID := c.Params.ByName("pduSessionId") + + // step 3: handle the message + header, response, problemDetails := s.Processor().RegistrationSmfRegistrationsProcedure( + &smfRegistration, + ueID, + pduSessionID, + ) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + // all nil + c.Status(http.StatusNoContent) + return + } +} + +// GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information +func (s *Server) HandleGetAmf3gppAccess(c *gin.Context) { + // step 1: log + logger.UecmLog.Infof("Handle HandleGetAmf3gppAccessRequest") + + // step 2: retrieve request + ueID := c.Param("ueId") + supportedFeatures := c.Query("supported-features") + + // step 3: handle the message + response, problemDetails := s.Processor().GetAmf3gppAccessProcedure(ueID, supportedFeatures) + + // step 4: process the return value from step 3 + if response != nil { + // status code is based on SPEC, and option headers + c.JSON(http.StatusOK, response) + return + } else if problemDetails != nil { + c.JSON(int(problemDetails.Status), problemDetails) + return + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "UNSPECIFIED", + } + c.JSON(http.StatusForbidden, problemDetails) + return + } +} diff --git a/internal/sbi/consumer/udm_service.go b/internal/sbi/consumer/udm_service.go index e347c8e..4d13846 100644 --- a/internal/sbi/consumer/udm_service.go +++ b/internal/sbi/consumer/udm_service.go @@ -1,15 +1,10 @@ package consumer import ( - "net/http" "sync" - "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" "github.com/free5gc/openapi/Nudm_UEContextManagement" - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" ) type nudmService struct { @@ -22,7 +17,7 @@ type nudmService struct { nfUECMClients map[string]*Nudm_UEContextManagement.APIClient } -func (s *nudmService) getSDMClient(uri string) *Nudm_SubscriberDataManagement.APIClient { +func (s *nudmService) GetSDMClient(uri string) *Nudm_SubscriberDataManagement.APIClient { if uri == "" { return nil } @@ -44,7 +39,7 @@ func (s *nudmService) getSDMClient(uri string) *Nudm_SubscriberDataManagement.AP return client } -func (s *nudmService) getUECMClient(uri string) *Nudm_UEContextManagement.APIClient { +func (s *nudmService) GetUECMClient(uri string) *Nudm_UEContextManagement.APIClient { if uri == "" { return nil } @@ -65,191 +60,3 @@ func (s *nudmService) getUECMClient(uri string) *Nudm_UEContextManagement.APICli s.nfUECMClients[uri] = client return client } - -func (s *nudmService) SubscribeToSharedDataProcedure(sdmSubscription *models.SdmSubscription) ( - header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) - if err != nil { - return nil, nil, pd - } - - udmClientAPI := s.getSDMClient("subscribeToSharedData") - - sdmSubscriptionResp, res, err := udmClientAPI.SubscriptionCreationForSharedDataApi.SubscribeToSharedData( - ctx, *sdmSubscription) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("SubscribeToSharedData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusCreated { - header = make(http.Header) - udm_context.GetSelf().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) - reourceUri := udm_context.GetSelf(). - GetSDMUri() + - "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId - header.Set("Location", reourceUri) - return header, &sdmSubscriptionResp, nil - } else if res.StatusCode == http.StatusNotFound { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, nil, problemDetails - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotImplemented, - Cause: "UNSUPPORTED_RESOURCE_URI", - } - - return nil, nil, problemDetails - } -} - -func (s *nudmService) UnsubscribeForSharedDataProcedure(subscriptionID string) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) - if err != nil { - return pd - } - - udmClientAPI := s.getSDMClient("unsubscribeForSharedData") - - res, err := udmClientAPI.SubscriptionDeletionForSharedDataApi.UnsubscribeForSharedData( - ctx, subscriptionID) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails := &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("UnsubscribeForSharedData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusNoContent { - return nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return problemDetails - } -} - -func (s *nudmService) DataChangeNotificationProcedure( - notifyItems []models.NotifyItem, - supi string, -) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) - if err != nil { - return pd - } - - ue, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) - - clientAPI := s.getSDMClient("DataChangeNotification") - - var problemDetails *models.ProblemDetails - for _, subscriptionDataSubscription := range ue.UdmSubsToNotify { - onDataChangeNotificationurl := subscriptionDataSubscription.OriginalCallbackReference - dataChangeNotification := models.ModificationNotification{} - dataChangeNotification.NotifyItems = notifyItems - - httpResponse, err := clientAPI.DataChangeNotificationCallbackDocumentApi.OnDataChangeNotification( - ctx, onDataChangeNotificationurl, dataChangeNotification) - if err != nil { - if httpResponse == nil { - logger.HttpLog.Error(err.Error()) - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Detail: err.Error(), - } - } else { - logger.HttpLog.Errorln(err.Error()) - - problemDetails = &models.ProblemDetails{ - Status: int32(httpResponse.StatusCode), - Detail: err.Error(), - } - } - } - defer func() { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.HttpLog.Errorf("OnDataChangeNotification response body cannot close: %+v", rspCloseErr) - } - }() - } - - return problemDetails -} - -func (s *nudmService) SendOnDeregistrationNotification(ueId string, onDeregistrationNotificationUrl string, - deregistData models.DeregistrationData, -) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NfType_UDM) - if err != nil { - return pd - } - - clientAPI := s.getUECMClient("SendOnDeregistrationNotification") - - httpResponse, err := clientAPI.DeregistrationNotificationCallbackApi.DeregistrationNotify( - ctx, onDeregistrationNotificationUrl, deregistData) - if err != nil { - if httpResponse == nil { - logger.HttpLog.Error(err.Error()) - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "DEREGISTRATION_NOTIFICATION_ERROR", - Detail: err.Error(), - } - - return problemDetails - } else { - logger.HttpLog.Errorln(err.Error()) - problemDetails := &models.ProblemDetails{ - Status: int32(httpResponse.StatusCode), - Cause: "DEREGISTRATION_NOTIFICATION_ERROR", - Detail: err.Error(), - } - - return problemDetails - } - } - defer func() { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.HttpLog.Errorf("DeregistrationNotify response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go index 2a52bdf..4e768e2 100644 --- a/internal/sbi/consumer/udr_service.go +++ b/internal/sbi/consumer/udr_service.go @@ -1,29 +1,13 @@ package consumer import ( - cryptoRand "crypto/rand" - "encoding/hex" "fmt" - "math/big" - "math/rand" - "net/http" - "reflect" - "strconv" "strings" "sync" - "time" - "github.com/antihax/optional" - - "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudr_DataRepository" - "github.com/free5gc/openapi/models" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer/callback" - "github.com/free5gc/udm/pkg/suci" - "github.com/free5gc/util/milenage" - "github.com/free5gc/util/ueauth" ) type nudrService struct { @@ -41,20 +25,7 @@ const ( NFDiscoveryToUDRParamGpsi ) -const ( - SqnMAx int64 = 0xFFFFFFFFFFFF - ind int64 = 32 - keyStrLen int = 32 - opStrLen int = 32 - opcStrLen int = 32 -) - -const ( - authenticationRejected string = "AUTHENTICATION_REJECTED" - resyncAMF string = "0000" -) - -func (s *nudrService) createUDMClientToUDR(id string) (*Nudr_DataRepository.APIClient, error) { +func (s *nudrService) CreateUDMClientToUDR(id string) (*Nudr_DataRepository.APIClient, error) { uri := s.getUdrURI(id) if uri == "" { logger.ProcLog.Errorf("ID[%s] does not match any UDR", id) @@ -78,15 +49,6 @@ func (s *nudrService) createUDMClientToUDR(id string) (*Nudr_DataRepository.APIC return client, nil } -func (s *nudrService) containDataSetName(dataSetNames []string, target string) bool { - for _, dataSetName := range dataSetNames { - if dataSetName == target { - return true - } - } - return false -} - func (s *nudrService) getUdrURI(id string) string { if strings.Contains(id, "imsi") || strings.Contains(id, "nai") { // supi ue, ok := udm_context.GetSelf().UdmUeFindBySupi(id) @@ -129,2248 +91,3 @@ func (s *nudrService) getUdrURI(id string) string { } return SendNFIntancesUDR("", NFDiscoveryToUDRParamNone) } - -func (s *nudrService) aucSQN(opc, k, auts, rand []byte) ([]byte, []byte) { - AK, SQNms := make([]byte, 6), make([]byte, 6) - macS := make([]byte, 8) - ConcSQNms := auts[:6] - AMF, err := hex.DecodeString(resyncAMF) - if err != nil { - return nil, nil - } - - logger.UeauLog.Tracef("aucSQN: ConcSQNms=[%x]", ConcSQNms) - - err = milenage.F2345(opc, k, rand, nil, nil, nil, nil, AK) - if err != nil { - logger.UeauLog.Errorln("aucSQN milenage F2345 err:", err) - } - - for i := 0; i < 6; i++ { - SQNms[i] = AK[i] ^ ConcSQNms[i] - } - - logger.UeauLog.Tracef("aucSQN: opc=[%x], k=[%x], rand=[%x], AMF=[%x], SQNms=[%x]\n", opc, k, rand, AMF, SQNms) - // The AMF used to calculate MAC-S assumes a dummy value of all zeros - err = milenage.F1(opc, k, rand, SQNms, AMF, nil, macS) - if err != nil { - logger.UeauLog.Errorln("aucSQN milenage F1 err:", err) - } - logger.UeauLog.Tracef("aucSQN: macS=[%x]\n", macS) - return SQNms, macS -} - -func (s *nudrService) strictHex(ss string, n int) string { - l := len(ss) - if l < n { - return strings.Repeat("0", n-l) + ss - } else { - return ss[l-n : l] - } -} - -// EE service -func (s *nudrService) CreateEeSubscriptionProcedure(ueIdentity string, - eesubscription models.EeSubscription, -) (*models.CreatedEeSubscription, *models.ProblemDetails) { - udmSelf := udm_context.GetSelf() - logger.EeLog.Debugf("udIdentity: %s", ueIdentity) - switch { - // GPSI (MSISDN identifier) represents a single UE - case strings.HasPrefix(ueIdentity, "msisdn-"): - fallthrough - // GPSI (External identifier) represents a single UE - case strings.HasPrefix(ueIdentity, "extid-"): - if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { - id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() - if err != nil { - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - return nil, problemDetails - } - - subscriptionID := strconv.Itoa(int(id)) - ue.EeSubscriptions[subscriptionID] = &eesubscription - createdEeSubscription := &models.CreatedEeSubscription{ - EeSubscription: &eesubscription, - } - return createdEeSubscription, nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - return nil, problemDetails - } - // external groupID represents a group of UEs - case strings.HasPrefix(ueIdentity, "extgroupid-"): - id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() - if err != nil { - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - return nil, problemDetails - } - subscriptionID := strconv.Itoa(int(id)) - createdEeSubscription := &models.CreatedEeSubscription{ - EeSubscription: &eesubscription, - } - - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if ue.ExternalGroupID == ueIdentity { - ue.EeSubscriptions[subscriptionID] = &eesubscription - } - return true - }) - return createdEeSubscription, nil - // represents any UEs - case ueIdentity == "anyUE": - id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() - if err != nil { - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - return nil, problemDetails - } - subscriptionID := strconv.Itoa(int(id)) - createdEeSubscription := &models.CreatedEeSubscription{ - EeSubscription: &eesubscription, - } - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - ue.EeSubscriptions[subscriptionID] = &eesubscription - return true - }) - return createdEeSubscription, nil - default: - problemDetails := &models.ProblemDetails{ - Status: http.StatusBadRequest, - Cause: "MANDATORY_IE_INCORRECT", - InvalidParams: []models.InvalidParam{ - { - Param: "ueIdentity", - Reason: "incorrect format", - }, - }, - } - return nil, problemDetails - } -} - -// TODO: complete this procedure based on TS 29503 5.5 -func (s *nudrService) DeleteEeSubscriptionProcedure(ueIdentity string, subscriptionID string) { - udmSelf := udm_context.GetSelf() - - switch { - case strings.HasPrefix(ueIdentity, "msisdn-"): - fallthrough - case strings.HasPrefix(ueIdentity, "extid-"): - if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { - delete(ue.EeSubscriptions, subscriptionID) - } - case strings.HasPrefix(ueIdentity, "extgroupid-"): - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if ue.ExternalGroupID == ueIdentity { - delete(ue.EeSubscriptions, subscriptionID) - } - return true - }) - case ueIdentity == "anyUE": - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - delete(ue.EeSubscriptions, subscriptionID) - return true - }) - } - if id, err := strconv.ParseInt(subscriptionID, 10, 64); err != nil { - logger.EeLog.Warnf("subscriptionID covert type error: %+v", err) - } else { - udmSelf.EeSubscriptionIDGenerator.FreeID(id) - } -} - -// TODO: complete this procedure based on TS 29503 5.5 -func (s *nudrService) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptionID string, - patchList []models.PatchItem, -) *models.ProblemDetails { - udmSelf := udm_context.GetSelf() - - switch { - case strings.HasPrefix(ueIdentity, "msisdn-"): - fallthrough - case strings.HasPrefix(ueIdentity, "extid-"): - if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { - if _, ok := ue.EeSubscriptions[subscriptionID]; ok { - for _, patchItem := range patchList { - logger.EeLog.Debugf("patch item: %+v", patchItem) - // TODO: patch the Eesubscription - } - return nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "SUBSCRIPTION_NOT_FOUND", - } - return problemDetails - } - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "SUBSCRIPTION_NOT_FOUND", - } - return problemDetails - } - case strings.HasPrefix(ueIdentity, "extgroupid-"): - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if ue.ExternalGroupID == ueIdentity { - if _, ok := ue.EeSubscriptions[subscriptionID]; ok { - for _, patchItem := range patchList { - logger.EeLog.Debugf("patch item: %+v", patchItem) - // TODO: patch the Eesubscription - } - } - } - return true - }) - return nil - case ueIdentity == "anyUE": - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if _, ok := ue.EeSubscriptions[subscriptionID]; ok { - for _, patchItem := range patchList { - logger.EeLog.Debugf("patch item: %+v", patchItem) - // TODO: patch the Eesubscription - } - } - return true - }) - return nil - default: - problemDetails := &models.ProblemDetails{ - Status: http.StatusBadRequest, - Cause: "MANDATORY_IE_INCORRECT", - InvalidParams: []models.InvalidParam{ - { - Param: "ueIdentity", - Reason: "incorrect format", - }, - }, - } - return problemDetails - } -} - -func (s *nudrService) ConfirmAuthDataProcedure( - authEvent models.AuthEvent, - supi string, -) (problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - var createAuthParam Nudr_DataRepository.CreateAuthenticationStatusParamOpts - optInterface := optional.NewInterface(authEvent) - createAuthParam.AuthEvent = optInterface - - client, err := s.createUDMClientToUDR(supi) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := client.AuthenticationStatusDocumentApi.CreateAuthenticationStatus( - ctx, supi, &createAuthParam) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("ConfirmAuth err:", err.Error()) - return problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UeauLog.Errorf("CreateAuthenticationStatus response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} - -func (s *nudrService) GenerateAuthDataProcedure(authInfoRequest models.AuthenticationInfoRequest, supiOrSuci string) ( - response *models.AuthenticationInfoResult, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - logger.UeauLog.Traceln("In GenerateAuthDataProcedure") - - response = &models.AuthenticationInfoResult{} - rand.New(rand.NewSource(time.Now().UnixNano())) - supi, err := suci.ToSupi(supiOrSuci, udm_context.GetSelf().SuciProfiles) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("suciToSupi error: ", err.Error()) - return nil, problemDetails - } - - logger.UeauLog.Tracef("supi conversion => [%s]", supi) - - client, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - authSubs, res, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(ctx, supi, nil) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - switch res.StatusCode { - case http.StatusNotFound: - logger.UeauLog.Warnf("Return from UDR QueryAuthSubsData error") - default: - logger.UeauLog.Errorln("Return from UDR QueryAuthSubsData error") - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAuthSubsData response body cannot close: %+v", rspCloseErr) - } - }() - - /* - K, RAND, CK, IK: 128 bits (16 bytes) (hex len = 32) - SQN, AK: 48 bits (6 bytes) (hex len = 12) TS33.102 - 6.3.2 - AMF: 16 bits (2 bytes) (hex len = 4) TS33.102 - Annex H - */ - - hasK, hasOP, hasOPC := false, false, false - var kStr, opStr, opcStr string - var k, op, opc []byte - - if authSubs.PermanentKey != nil { - kStr = authSubs.PermanentKey.PermanentKeyValue - if len(kStr) == keyStrLen { - k, err = hex.DecodeString(kStr) - if err != nil { - logger.UeauLog.Errorln("err:", err) - } else { - hasK = true - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Errorln("kStr length is ", len(kStr)) - return nil, problemDetails - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Errorln("Nil PermanentKey") - return nil, problemDetails - } - - if authSubs.Milenage != nil { - if authSubs.Milenage.Op != nil && authSubs.Milenage.Op.OpValue != "" { - opStr = authSubs.Milenage.Op.OpValue - if len(opStr) == opStrLen { - op, err = hex.DecodeString(opStr) - if err != nil { - logger.UeauLog.Errorln("err:", err) - } else { - hasOP = true - } - } else { - logger.UeauLog.Errorln("opStr length is ", len(opStr)) - } - } else { - logger.UeauLog.Infoln("Nil Op") - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Infoln("Nil Milenage") - return nil, problemDetails - } - - if authSubs.Opc != nil && authSubs.Opc.OpcValue != "" { - opcStr = authSubs.Opc.OpcValue - if len(opcStr) == opcStrLen { - opc, err = hex.DecodeString(opcStr) - if err != nil { - logger.UeauLog.Errorln("err:", err) - } else { - hasOPC = true - } - } else { - logger.UeauLog.Errorln("opcStr length is ", len(opcStr)) - } - } else { - logger.UeauLog.Infoln("Nil Opc") - } - - if !hasOPC && !hasOP { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - return nil, problemDetails - } - - if !hasOPC { - if hasK && hasOP { - opc, err = milenage.GenerateOPC(k, op) - if err != nil { - logger.UeauLog.Errorln("milenage GenerateOPC err:", err) - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Errorln("Unable to derive OPC") - return nil, problemDetails - } - } - - sqnStr := s.strictHex(authSubs.SequenceNumber, 12) - logger.UeauLog.Traceln("sqnStr", sqnStr) - sqn, err := hex.DecodeString(sqnStr) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - logger.UeauLog.Tracef("K=[%x], sqn=[%x], OP=[%x], OPC=[%x]", k, sqn, op, opc) - - RAND := make([]byte, 16) - _, err = cryptoRand.Read(RAND) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - amfStr := s.strictHex(authSubs.AuthenticationManagementField, 4) - logger.UeauLog.Traceln("amfStr", amfStr) - AMF, err := hex.DecodeString(amfStr) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - logger.UeauLog.Tracef("RAND=[%x], AMF=[%x]", RAND, AMF) - - // re-synchronization - if authInfoRequest.ResynchronizationInfo != nil { - logger.UeauLog.Infof("Authentication re-synchronization") - - Auts, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Auts) - if deCodeErr != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: deCodeErr.Error(), - } - - logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails - } - - randHex, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Rand) - if deCodeErr != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: deCodeErr.Error(), - } - - logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails - } - - SQNms, macS := s.aucSQN(opc, k, Auts, randHex) - if reflect.DeepEqual(macS, Auts[6:]) { - _, err = cryptoRand.Read(RAND) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: deCodeErr.Error(), - } - - logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails - } - - // increment sqn authSubs.SequenceNumber - bigSQN := big.NewInt(0) - sqnStr = hex.EncodeToString(SQNms) - logger.UeauLog.Tracef("SQNstr=[%s]", sqnStr) - bigSQN.SetString(sqnStr, 16) - - bigInc := big.NewInt(ind + 1) - - bigP := big.NewInt(SqnMAx) - bigSQN = bigInc.Add(bigSQN, bigInc) - bigSQN = bigSQN.Mod(bigSQN, bigP) - sqnStr = fmt.Sprintf("%x", bigSQN) - sqnStr = s.strictHex(sqnStr, 12) - } else { - logger.UeauLog.Errorln("Re-Sync MAC failed ", supiOrSuci) - // Check if suci - suciPart := strings.Split(supiOrSuci, "-") - if suciPart[suci.PrefixPlace] == suci.PrefixSUCI && - suciPart[suci.SupiTypePlace] == suci.SupiTypeIMSI && - suciPart[suci.SchemePlace] != suci.NullScheme { - // Get SuciProfile index and write public key - keyIndex, err1 := strconv.Atoi(suciPart[suci.HNPublicKeyIDPlace]) - if err1 != nil { - logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace parse Error") - } else if keyIndex < 1 { - logger.UeauLog.Errorf("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace keyIndex[%d] < 1", - keyIndex) - } else { - logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key ", - udm_context.GetSelf().SuciProfiles[keyIndex-1].PublicKey) - } - } - logger.UeauLog.Errorln("MACS ", macS) - logger.UeauLog.Errorln("Auts[6:] ", Auts[6:]) - logger.UeauLog.Errorln("Sqn ", SQNms) - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "modification is rejected", - } - return nil, problemDetails - } - } - - // increment sqn - bigSQN := big.NewInt(0) - sqn, err = hex.DecodeString(sqnStr) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - bigSQN.SetString(sqnStr, 16) - - bigInc := big.NewInt(1) - bigSQN = bigInc.Add(bigSQN, bigInc) - - SQNheStr := fmt.Sprintf("%x", bigSQN) - SQNheStr = s.strictHex(SQNheStr, 12) - patchItemArray := []models.PatchItem{ - { - Op: models.PatchOperation_REPLACE, - Path: "/sequenceNumber", - Value: SQNheStr, - }, - } - - var rsp *http.Response - - rsp, err = client.AuthenticationDataDocumentApi.ModifyAuthentication( - ctx, supi, patchItemArray) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "modification is rejected ", - Detail: err.Error(), - } - - logger.UeauLog.Errorln("update sqn error:", err) - return nil, problemDetails - } - defer func() { - if rspCloseErr := rsp.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("ModifyAuthentication response body cannot close: %+v", rspCloseErr) - } - }() - - // Run milenage - macA, macS := make([]byte, 8), make([]byte, 8) - CK, IK := make([]byte, 16), make([]byte, 16) - RES := make([]byte, 8) - AK, AKstar := make([]byte, 6), make([]byte, 6) - - // Generate macA, macS - err = milenage.F1(opc, k, RAND, sqn, AMF, macA, macS) - if err != nil { - logger.UeauLog.Errorln("milenage F1 err:", err) - } - - // Generate RES, CK, IK, AK, AKstar - // RES == XRES (expected RES) for server - err = milenage.F2345(opc, k, RAND, RES, CK, IK, AK, AKstar) - if err != nil { - logger.UeauLog.Errorln("milenage F2345 err:", err) - } - logger.UeauLog.Tracef("milenage RES=[%s]", hex.EncodeToString(RES)) - - // Generate AUTN - logger.UeauLog.Tracef("SQN=[%x], AK=[%x]", sqn, AK) - logger.UeauLog.Tracef("AMF=[%x], macA=[%x]", AMF, macA) - SQNxorAK := make([]byte, 6) - for i := 0; i < len(sqn); i++ { - SQNxorAK[i] = sqn[i] ^ AK[i] - } - logger.UeauLog.Tracef("SQN xor AK=[%x]", SQNxorAK) - AUTN := append(append(SQNxorAK, AMF...), macA...) - logger.UeauLog.Tracef("AUTN=[%x]", AUTN) - - var av models.AuthenticationVector - if authSubs.AuthenticationMethod == models.AuthMethod__5_G_AKA { - response.AuthType = models.AuthType__5_G_AKA - - // derive XRES* - key := append(CK, IK...) - FC := ueauth.FC_FOR_RES_STAR_XRES_STAR_DERIVATION - P0 := []byte(authInfoRequest.ServingNetworkName) - P1 := RAND - P2 := RES - - kdfValForXresStar, err := ueauth.GetKDFValue( - key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1), P2, ueauth.KDFLen(P2)) - if err != nil { - logger.UeauLog.Errorf("Get kdfValForXresStar err: %+v", err) - } - xresStar := kdfValForXresStar[len(kdfValForXresStar)/2:] - logger.UeauLog.Tracef("xresStar=[%x]", xresStar) - - // derive Kausf - FC = ueauth.FC_FOR_KAUSF_DERIVATION - P0 = []byte(authInfoRequest.ServingNetworkName) - P1 = SQNxorAK - kdfValForKausf, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) - if err != nil { - logger.UeauLog.Errorf("Get kdfValForKausf err: %+v", err) - } - logger.UeauLog.Tracef("Kausf=[%x]", kdfValForKausf) - - // Fill in rand, xresStar, autn, kausf - av.Rand = hex.EncodeToString(RAND) - av.XresStar = hex.EncodeToString(xresStar) - av.Autn = hex.EncodeToString(AUTN) - av.Kausf = hex.EncodeToString(kdfValForKausf) - av.AvType = models.AvType__5_G_HE_AKA - } else { // EAP-AKA' - response.AuthType = models.AuthType_EAP_AKA_PRIME - - // derive CK' and IK' - key := append(CK, IK...) - FC := ueauth.FC_FOR_CK_PRIME_IK_PRIME_DERIVATION - P0 := []byte(authInfoRequest.ServingNetworkName) - P1 := SQNxorAK - kdfVal, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) - if err != nil { - logger.UeauLog.Errorf("Get kdfVal err: %+v", err) - } - logger.UeauLog.Tracef("kdfVal=[%x] (len=%d)", kdfVal, len(kdfVal)) - - // For TS 35.208 test set 19 & RFC 5448 test vector 1 - // CK': 0093 962d 0dd8 4aa5 684b 045c 9edf fa04 - // IK': ccfc 230c a74f cc96 c0a5 d611 64f5 a76 - - ckPrime := kdfVal[:len(kdfVal)/2] - ikPrime := kdfVal[len(kdfVal)/2:] - logger.UeauLog.Tracef("ckPrime=[%x], kPrime=[%x]", ckPrime, ikPrime) - - // Fill in rand, xres, autn, ckPrime, ikPrime - av.Rand = hex.EncodeToString(RAND) - av.Xres = hex.EncodeToString(RES) - av.Autn = hex.EncodeToString(AUTN) - av.CkPrime = hex.EncodeToString(ckPrime) - av.IkPrime = hex.EncodeToString(ikPrime) - av.AvType = models.AvType_EAP_AKA_PRIME - } - - response.AuthenticationVector = &av - response.Supi = supi - return response, nil -} - -func (s *nudrService) UpdateProcedure( - updateRequest models.PpData, - gpsi string, -) (problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - clientAPI, err := s.createUDMClientToUDR(gpsi) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - res, err := clientAPI.ProvisionedParameterDataDocumentApi.ModifyPpData(ctx, gpsi, nil) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.PpLog.Errorf("ModifyPpData response body cannot close: %+v", rspCloseErr) - } - }() - return nil -} - -func (s *nudrService) GetAmDataProcedure(supi string, plmnID string, supportedFeatures string) ( - response *models.AccessAndMobilitySubscriptionData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. - QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetAMSubsriptionData(&accessAndMobilitySubscriptionDataResp) - return &accessAndMobilitySubscriptionDataResp, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func (s *nudrService) GetIdTranslationResultProcedure(gpsi string) (response *models.IdTranslationResult, - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var idTranslationResult models.IdTranslationResult - var getIdentityDataParamOpts Nudr_DataRepository.GetIdentityDataParamOpts - - clientAPI, err := s.createUDMClientToUDR(gpsi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - idTranslationResultResp, res, err := clientAPI.QueryIdentityDataBySUPIOrGPSIDocumentApi.GetIdentityData( - ctx, gpsi, &getIdentityDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("GetIdentityData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - if idList := idTranslationResultResp; idList.SupiList != nil { - // GetCorrespondingSupi get corresponding Supi(here IMSI) matching the given Gpsi from the queried SUPI list from UDR - idTranslationResult.Supi = udm_context.GetCorrespondingSupi(idList) - idTranslationResult.Gpsi = gpsi - - return &idTranslationResult, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func (s *nudrService) GetSupiProcedure(supi string, plmnID string, dataSetNames []string, supportedFeatures string) ( - response *models.SubscriptionDataSets, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - if len(dataSetNames) < 2 { - problemDetails = &models.ProblemDetails{ - Status: http.StatusBadRequest, - Cause: "BAD_REQUEST", - Detail: "datasetNames must have at least 2 elements", - } - return nil, problemDetails - } - - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var subscriptionDataSets, subsDataSetBody models.SubscriptionDataSets - var ueContextInSmfDataResp models.UeContextInSmfData - pduSessionMap := make(map[string]models.PduSession) - var pgwInfoArray []models.PgwInfo - - var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - var querySmfSelectDataParamOpts Nudr_DataRepository.QuerySmfSelectDataParamOpts - var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts - var querySmDataParamOpts Nudr_DataRepository.QuerySmDataParamOpts - - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - udm_context.GetSelf().CreateSubsDataSetsForUe(supi, subsDataSetBody) - - if s.containDataSetName(dataSetNames, string(models.DataSetName_AM)) { - var body models.AccessAndMobilitySubscriptionData - udm_context.GetSelf().CreateAccessMobilitySubsDataForUe(supi, body) - - amData, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi.QueryAmData( - ctx, supi, plmnID, &queryAmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetAMSubsriptionData(&amData) - subscriptionDataSets.AmData = &amData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - if s.containDataSetName(dataSetNames, string(models.DataSetName_SMF_SEL)) { - var smfSelSubsbody models.SmfSelectionSubscriptionData - udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, smfSelSubsbody) - - smfSelData, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi.QuerySmfSelectData(ctx, - supi, plmnID, &querySmfSelectDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorln(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorln(err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetSmfSelectionSubsData(&smfSelData) - subscriptionDataSets.SmfSelData = &smfSelData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - if s.containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMF)) { - var UeContextInSmfbody models.UeContextInSmfData - var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts - querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, UeContextInSmfbody) - - pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( - ctx, supi, &querySmfRegListParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) - } - }() - - for _, element := range pdusess { - var pduSession models.PduSession - pduSession.Dnn = element.Dnn - pduSession.SmfInstanceId = element.SmfInstanceId - pduSession.PlmnId = element.PlmnId - pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession - } - ueContextInSmfDataResp.PduSessions = pduSessionMap - - for _, element := range pdusess { - var pgwInfo models.PgwInfo - pgwInfo.Dnn = element.Dnn - pgwInfo.PgwFqdn = element.PgwFqdn - pgwInfo.PlmnId = element.PlmnId - pgwInfoArray = append(pgwInfoArray, pgwInfo) - } - ueContextInSmfDataResp.PgwInfo = pgwInfoArray - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.UeCtxtInSmfData = &ueContextInSmfDataResp - subscriptionDataSets.UecSmfData = &ueContextInSmfDataResp - } else { - var problemDetails models.ProblemDetails - problemDetails.Cause = "DATA_NOT_FOUND" - logger.SdmLog.Errorf(problemDetails.Cause) - } - } - - // TODO: UE Context in SMSF Data - // if containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMSF)) { - // } - - // TODO: SMS Subscription Data - // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_SUB)) { - // } - - if s.containDataSetName(dataSetNames, string(models.DataSetName_SM)) { - sessionManagementSubscriptionData, res, err := clientAPI.SessionManagementSubscriptionDataApi. - QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - smData, _, _, _ := udm_context.GetSelf().ManageSmData(sessionManagementSubscriptionData, "", "") - udmUe.SetSMSubsData(smData) - subscriptionDataSets.SmData = sessionManagementSubscriptionData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - if s.containDataSetName(dataSetNames, string(models.DataSetName_TRACE)) { - var TraceDatabody models.TraceData - udm_context.GetSelf().CreateTraceDataforUe(supi, TraceDatabody) - - traceData, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( - ctx, supi, plmnID, &queryTraceDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.TraceData = &traceData - udmUe.TraceDataResponse.TraceData = &traceData - subscriptionDataSets.TraceData = &traceData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - // TODO: SMS Management Subscription Data - // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_MNG)) { - // } - - return &subscriptionDataSets, nil -} - -func (s *nudrService) GetSharedDataProcedure(sharedDataIds []string, supportedFeatures string) ( - response []models.SharedData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := s.createUDMClientToUDR("") - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var getSharedDataParamOpts Nudr_DataRepository.GetSharedDataParamOpts - getSharedDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - sharedDataResp, res, err := clientAPI.RetrievalOfSharedDataApi.GetSharedData(ctx, sharedDataIds, - &getSharedDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("GetShareData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udm_context.GetSelf().SharedSubsDataMap = udm_context.MappingSharedData(sharedDataResp) - sharedData := udm_context.ObtainRequiredSharedData(sharedDataIds, sharedDataResp) - return sharedData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func (s *nudrService) GetSmDataProcedure( - supi string, - plmnID string, - Dnn string, - Snssai string, - supportedFeatures string, -) ( - response interface{}, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - logger.SdmLog.Infof("getSmDataProcedure: SUPI[%s] PLMNID[%s] DNN[%s] SNssai[%s]", supi, plmnID, Dnn, Snssai) - - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var querySmDataParamOpts Nudr_DataRepository.QuerySmDataParamOpts - querySmDataParamOpts.SingleNssai = optional.NewInterface(Snssai) - - sessionManagementSubscriptionDataResp, res, err := clientAPI.SessionManagementSubscriptionDataApi. - QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - smData, snssaikey, AllDnnConfigsbyDnn, AllDnns := udm_context.GetSelf().ManageSmData( - sessionManagementSubscriptionDataResp, Snssai, Dnn) - udmUe.SetSMSubsData(smData) - - rspSMSubDataList := make([]models.SessionManagementSubscriptionData, 0, 4) - - udmUe.SmSubsDataLock.RLock() - for _, eachSMSubData := range udmUe.SessionManagementSubsData { - rspSMSubDataList = append(rspSMSubDataList, eachSMSubData) - } - udmUe.SmSubsDataLock.RUnlock() - - switch { - case Snssai == "" && Dnn == "": - return AllDnns, nil - case Snssai != "" && Dnn == "": - udmUe.SmSubsDataLock.RLock() - defer udmUe.SmSubsDataLock.RUnlock() - return udmUe.SessionManagementSubsData[snssaikey].DnnConfigurations, nil - case Snssai == "" && Dnn != "": - return AllDnnConfigsbyDnn, nil - case Snssai != "" && Dnn != "": - return rspSMSubDataList, nil - default: - udmUe.SmSubsDataLock.RLock() - defer udmUe.SmSubsDataLock.RUnlock() - return udmUe.SessionManagementSubsData, nil - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func (s *nudrService) GetNssaiProcedure(supi string, plmnID string, supportedFeatures string) ( - *models.Nssai, *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - var nssaiResp models.Nssai - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. - QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails := &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) - } - }() - - nssaiResp = *accessAndMobilitySubscriptionDataResp.Nssai - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.Nssai = &nssaiResp - return udmUe.Nssai, nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func (s *nudrService) GetSmfSelectDataProcedure(supi string, plmnID string, supportedFeatures string) ( - response *models.SmfSelectionSubscriptionData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var querySmfSelectDataParamOpts Nudr_DataRepository.QuerySmfSelectDataParamOpts - querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - var body models.SmfSelectionSubscriptionData - - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, body) - - smfSelectionSubscriptionDataResp, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi. - QuerySmfSelectData(ctx, supi, plmnID, &querySmfSelectDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetSmfSelectionSubsData(&smfSelectionSubscriptionDataResp) - return udmUe.SmfSelSubsData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func (s *nudrService) SubscribeProcedure(sdmSubscription *models.SdmSubscription, supi string) ( - header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - sdmSubscriptionResp, res, err := clientAPI.SDMSubscriptionsCollectionApi.CreateSdmSubscriptions( - ctx, supi, *sdmSubscription) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("CreateSdmSubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusCreated { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) - if udmUe == nil { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.CreateSubscriptiontoNotifChange(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) - header.Set("Location", udmUe.GetLocationURI2(udm_context.LocationUriSdmSubscription, supi)) - return header, &sdmSubscriptionResp, nil - } else if res.StatusCode == http.StatusNotFound { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, nil, problemDetails - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotImplemented, - Cause: "UNSUPPORTED_RESOURCE_URI", - } - return nil, nil, problemDetails - } -} - -func (s *nudrService) UnsubscribeProcedure(supi string, subscriptionID string) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - res, err := clientAPI.SDMSubscriptionDocumentApi.RemovesdmSubscriptions(ctx, supi, subscriptionID) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails := &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("RemovesdmSubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusNoContent { - return nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - return problemDetails - } -} - -func (s *nudrService) ModifyProcedure( - sdmSubsModification *models.SdmSubsModification, - supi string, - subscriptionID string, -) ( - response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - sdmSubscription := models.SdmSubscription{} - body := Nudr_DataRepository.UpdatesdmsubscriptionsParamOpts{ - SdmSubscription: optional.NewInterface(sdmSubscription), - } - - res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( - ctx, supi, subscriptionID, &body) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - return &sdmSubscription, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func (s *nudrService) GetTraceDataProcedure(supi string, plmnID string) ( - response *models.TraceData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var body models.TraceData - var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts - - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - udm_context.GetSelf().CreateTraceDataforUe(supi, body) - - traceDataRes, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( - ctx, supi, plmnID, &queryTraceDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.TraceData = &traceDataRes - udmUe.TraceDataResponse.TraceData = &traceDataRes - - return udmUe.TraceDataResponse.TraceData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func (s *nudrService) GetUeContextInSmfDataProcedure(supi string, supportedFeatures string) ( - response *models.UeContextInSmfData, problemDetails *models.ProblemDetails, -) { - var body models.UeContextInSmfData - var ueContextInSmfData models.UeContextInSmfData - var pgwInfoArray []models.PgwInfo - var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts - querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - pduSessionMap := make(map[string]models.PduSession) - udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, body) - - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - - pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( - ctx, supi, &querySmfRegListParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Infoln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Infoln(err) - } else { - logger.SdmLog.Infoln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) - } - }() - - for _, element := range pdusess { - var pduSession models.PduSession - pduSession.Dnn = element.Dnn - pduSession.SmfInstanceId = element.SmfInstanceId - pduSession.PlmnId = element.PlmnId - pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession - } - ueContextInSmfData.PduSessions = pduSessionMap - - for _, element := range pdusess { - var pgwInfo models.PgwInfo - pgwInfo.Dnn = element.Dnn - pgwInfo.PgwFqdn = element.PgwFqdn - pgwInfo.PlmnId = element.PlmnId - pgwInfoArray = append(pgwInfoArray, pgwInfo) - } - ueContextInSmfData.PgwInfo = pgwInfoArray - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.UeCtxtInSmfData = &ueContextInSmfData - return udmUe.UeCtxtInSmfData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -// ue_context_managemanet_service -func (s *nudrService) GetAmf3gppAccessProcedure(ueID string, supportedFeatures string) ( - response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var queryAmfContext3gppParamOpts Nudr_DataRepository.QueryAmfContext3gppParamOpts - queryAmfContext3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - amf3GppAccessRegistration, resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi. - QueryAmfContext3gpp(ctx, ueID, &queryAmfContext3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return &amf3GppAccessRegistration, nil -} - -func (s *nudrService) GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts Nudr_DataRepository. - QueryAmfContextNon3gppParamOpts, ueID string) (response *models.AmfNon3GppAccessRegistration, - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - amfNon3GppAccessRegistration, resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi. - QueryAmfContextNon3gpp(ctx, ueID, &queryAmfContextNon3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return &amfNon3GppAccessRegistration, nil -} - -func (s *nudrService) RegistrationAmf3gppAccessProcedure( - registerRequest models.Amf3GppAccessRegistration, - ueID string, -) ( - header http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - // TODO: EPS interworking with N26 is not supported yet in this stage - var oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration - var ue *udm_context.UdmUeContext - - if udm_context.GetSelf().UdmAmf3gppRegContextExists(ueID) { - ue, _ = udm_context.GetSelf().UdmUeFindBySupi(ueID) - oldAmf3GppAccessRegContext = ue.Amf3GppAccessRegistration - } - - udm_context.GetSelf().CreateAmf3gppRegContext(ueID, registerRequest) - - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var createAmfContext3gppParamOpts Nudr_DataRepository.CreateAmfContext3gppParamOpts - optInterface := optional.NewInterface(registerRequest) - createAmfContext3gppParamOpts.Amf3GppAccessRegistration = optInterface - resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.CreateAmfContext3gpp(ctx, - ueID, &createAmfContext3gppParamOpts) - if err != nil { - logger.UecmLog.Errorln("CreateAmfContext3gpp error : ", err) - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF - // corresponding to the same (e.g. 3GPP) access, if one exists - if oldAmf3GppAccessRegContext != nil { - if !ue.SameAsStoredGUAMI3gpp(*oldAmf3GppAccessRegContext.Guami) { - // Based on TS 23.502 4.2.2.2.2, If the serving NF removal reason indicated by the UDM is Initial Registration, - // the old AMF invokes the Nsmf_PDUSession_ReleaseSMContext (SM Context ID). Thus we give different - // dereg cause based on registration parameter from serving AMF - deregReason := models.DeregistrationReason_UE_REGISTRATION_AREA_CHANGE - if registerRequest.InitialRegistrationInd { - deregReason = models.DeregistrationReason_UE_INITIAL_REGISTRATION - } - deregistData := models.DeregistrationData{ - DeregReason: deregReason, - AccessType: models.AccessType__3_GPP_ACCESS, - } - - go func() { - logger.UecmLog.Infof("Send DeregNotify to old AMF GUAMI=%v", oldAmf3GppAccessRegContext.Guami) - pd := callback.SendOnDeregistrationNotification(ueID, - oldAmf3GppAccessRegContext.DeregCallbackUri, - deregistData) // Deregistration Notify Triggered - if pd != nil { - logger.UecmLog.Errorf("RegistrationAmf3gppAccess: send DeregNotify fail %v", pd) - } - }() - } - return nil, ®isterRequest, nil - } else { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration)) - return header, ®isterRequest, nil - } -} - -func (s *nudrService) RegisterAmfNon3gppAccessProcedure( - registerRequest models.AmfNon3GppAccessRegistration, - ueID string, -) ( - header http.Header, response *models.AmfNon3GppAccessRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - var oldAmfNon3GppAccessRegContext *models.AmfNon3GppAccessRegistration - if udm_context.GetSelf().UdmAmfNon3gppRegContextExists(ueID) { - ue, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - oldAmfNon3GppAccessRegContext = ue.AmfNon3GppAccessRegistration - } - - udm_context.GetSelf().CreateAmfNon3gppRegContext(ueID, registerRequest) - - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var createAmfContextNon3gppParamOpts Nudr_DataRepository.CreateAmfContextNon3gppParamOpts - optInterface := optional.NewInterface(registerRequest) - createAmfContextNon3gppParamOpts.AmfNon3GppAccessRegistration = optInterface - - resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.CreateAmfContextNon3gpp( - ctx, ueID, &createAmfContextNon3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF - // corresponding to the same (e.g. 3GPP) access, if one exists - if oldAmfNon3GppAccessRegContext != nil { - deregistData := models.DeregistrationData{ - DeregReason: models.DeregistrationReason_UE_INITIAL_REGISTRATION, - AccessType: models.AccessType_NON_3_GPP_ACCESS, - } - callback.SendOnDeregistrationNotification(ueID, oldAmfNon3GppAccessRegContext.DeregCallbackUri, - deregistData) // Deregistration Notify Triggered - - return nil, nil, nil - } else { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmfNon3GppAccessRegistration)) - return header, ®isterRequest, nil - } -} - -func (s *nudrService) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessRegistrationModification, ueID string) ( - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - var patchItemReqArray []models.PatchItem - currentContext := udm_context.GetSelf().GetAmf3gppRegContext(ueID) - if currentContext == nil { - logger.UecmLog.Errorln("[UpdateAmf3gppAccess] Empty Amf3gppRegContext") - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "CONTEXT_NOT_FOUND", - } - return problemDetails - } - - if request.Guami != nil { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - if udmUe.SameAsStoredGUAMI3gpp(*request.Guami) { // deregistration - logger.UecmLog.Infoln("UpdateAmf3gppAccess - deregistration") - request.PurgeFlag = true - } else { - logger.UecmLog.Errorln("INVALID_GUAMI") - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "INVALID_GUAMI", - } - return problemDetails - } - - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "guami" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = *request.Guami - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.PurgeFlag { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "purgeFlag" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.PurgeFlag - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.Pei != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "pei" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.Pei - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.ImsVoPs != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "imsVoPs" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.ImsVoPs - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.BackupAmfInfo != nil { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "backupAmfInfo" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.BackupAmfInfo - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.AmfContext3gpp(ctx, ueID, - patchItemReqArray) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return problemDetails - } - - if request.PurgeFlag { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - udmUe.Amf3GppAccessRegistration = nil - } - - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("AmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} - -func (s *nudrService) UpdateAmfNon3gppAccessProcedure( - request models.AmfNon3GppAccessRegistrationModification, - ueID string, -) ( - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - var patchItemReqArray []models.PatchItem - currentContext := udm_context.GetSelf().GetAmfNon3gppRegContext(ueID) - if currentContext == nil { - logger.UecmLog.Errorln("[UpdateAmfNon3gppAccess] Empty AmfNon3gppRegContext") - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "CONTEXT_NOT_FOUND", - } - return problemDetails - } - - if request.Guami != nil { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - if udmUe.SameAsStoredGUAMINon3gpp(*request.Guami) { // deregistration - logger.UecmLog.Infoln("UpdateAmfNon3gppAccess - deregistration") - request.PurgeFlag = true - } else { - logger.UecmLog.Errorln("INVALID_GUAMI") - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "INVALID_GUAMI", - } - } - - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "guami" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = *request.Guami - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.PurgeFlag { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "purgeFlag" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.PurgeFlag - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.Pei != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "pei" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.Pei - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.ImsVoPs != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "imsVoPs" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.ImsVoPs - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.BackupAmfInfo != nil { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "backupAmfInfo" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.BackupAmfInfo - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.AmfContextNon3gpp(ctx, - ueID, patchItemReqArray) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("AmfContextNon3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return problemDetails -} - -func (s *nudrService) DeregistrationSmfRegistrationsProcedure( - ueID string, - pduSessionID string, -) (problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.SMFRegistrationDocumentApi.DeleteSmfContext(ctx, ueID, pduSessionID) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("DeleteSmfContext response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} - -func (s *nudrService) RegistrationSmfRegistrationsProcedure( - request *models.SmfRegistration, - ueID string, - pduSessionID string, -) ( - header http.Header, response *models.SmfRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - contextExisted := false - udm_context.GetSelf().CreateSmfRegContext(ueID, pduSessionID) - if !udm_context.GetSelf().UdmSmfRegContextNotExists(ueID) { - contextExisted = true - } - - pduID64, err := strconv.ParseInt(pduSessionID, 10, 32) - if err != nil { - logger.UecmLog.Errorln(err.Error()) - } - pduID32 := int32(pduID64) - - var createSmfContextNon3gppParamOpts Nudr_DataRepository.CreateSmfContextNon3gppParamOpts - optInterface := optional.NewInterface(*request) - createSmfContextNon3gppParamOpts.SmfRegistration = optInterface - - clientAPI, err := s.createUDMClientToUDR(ueID) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.SMFRegistrationDocumentApi.CreateSmfContextNon3gpp(ctx, ueID, - pduID32, &createSmfContextNon3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("CreateSmfContextNon3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - if contextExisted { - return nil, nil, nil - } else { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriSmfRegistration)) - return header, request, nil - } -} - -// TS 29.503 5.2.2.7.3 -// Modification of a subscription to notifications of shared data change -func (s *nudrService) ModifyForSharedDataProcedure(sdmSubsModification *models.SdmSubsModification, supi string, - subscriptionID string, -) (response *models.SdmSubscription, problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := s.createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var sdmSubscription models.SdmSubscription - sdmSubs := models.SdmSubscription{} - body := Nudr_DataRepository.UpdatesdmsubscriptionsParamOpts{ - SdmSubscription: optional.NewInterface(sdmSubs), - } - - res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( - ctx, supi, subscriptionID, &body) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - return &sdmSubscription, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } -} diff --git a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go b/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go deleted file mode 100644 index 31fed99..0000000 --- a/internal/sbi/processor/access_and_mobility_subscription_data_retrieval.go +++ /dev/null @@ -1,74 +0,0 @@ -package processor - -import ( - "encoding/json" - "net/http" - "net/url" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetAmData - retrieve a UE's Access and Mobility Subscription Data -func (p *Processor) HandleGetAmData(c *gin.Context) { - var query url.Values - query.Set("plmn-id", c.Query("plmn-id")) - query.Set("supported-features", c.Query("plmn-id")) - - // step 1: log - logger.SdmLog.Infof("Handle GetAmData") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - - plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - supportedFeatures := query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := p.consumer.GetAmDataProcedure(supi, plmnID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} - -func (p *Processor) getPlmnIDStruct( - queryParameters url.Values, -) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { - if queryParameters["plmn-id"] != nil { - plmnIDJson := queryParameters["plmn-id"][0] - plmnIDStruct := &models.PlmnId{} - err := json.Unmarshal([]byte(plmnIDJson), plmnIDStruct) - if err != nil { - logger.SdmLog.Warnln("Unmarshal Error in targetPlmnListtruct: ", err) - } - return plmnIDStruct, nil - } else { - problemDetails := &models.ProblemDetails{ - Title: "Invalid Parameter", - Status: http.StatusBadRequest, - Cause: "No get plmn-id", - } - return nil, problemDetails - } -} diff --git a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index 61a4fbd..0000000 --- a/internal/sbi/processor/amf3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,40 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information -func (p *Processor) HandleGetAmf3gppAccess(c *gin.Context) { - // step 1: log - logger.UecmLog.Infof("Handle HandleGetAmf3gppAccessRequest") - - // step 2: retrieve request - ueID := c.Param("ueId") - supportedFeatures := c.Query("supported-features") - - // step 3: handle the message - response, problemDetails := p.consumer.GetAmf3gppAccessProcedure(ueID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index bf04668..0000000 --- a/internal/sbi/processor/amf_non3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,45 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/antihax/optional" - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/Nudr_DataRepository" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetAmfNon3gppAccess - retrieve the AMF registration for non-3GPP access information -func (p *Processor) HandleGetAmfNon3gppAccess(c *gin.Context) { - // step 1: log - logger.UecmLog.Infoln("Handle GetAmfNon3gppAccessRequest") - - // step 2: retrieve request - ueId := c.Param("ueId") - supportedFeatures := c.Query("supported-features") - - var queryAmfContextNon3gppParamOpts Nudr_DataRepository.QueryAmfContextNon3gppParamOpts - queryAmfContextNon3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - // step 3: handle the message - - response, problemDetails := p.consumer.GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts, ueId) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/amf_registration_for3_gpp_access.go b/internal/sbi/processor/amf_registration_for3_gpp_access.go deleted file mode 100644 index 2e65a09..0000000 --- a/internal/sbi/processor/amf_registration_for3_gpp_access.go +++ /dev/null @@ -1,73 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// RegistrationAmf3gppAccess - register as AMF for 3GPP access -func (p *Processor) HandleRegistrationAmf3gppAccess(c *gin.Context) { - var amf3GppAccessRegistration models.Amf3GppAccessRegistration - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amf3GppAccessRegistration, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.UecmLog.Infof("Handle RegistrationAmf3gppAccess") - - // step 2: retrieve request - ueID := c.Param("ueId") - logger.UecmLog.Info("UEID: ", ueID) - - // step 3: handle the message - header, response, problemDetails := p.consumer.RegistrationAmf3gppAccessProcedure(amf3GppAccessRegistration, ueID) - - // step 4: process the return value from step 3 - if response != nil { - if header != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/amf_registration_for_non3_gpp_access.go deleted file mode 100644 index 45dd8c2..0000000 --- a/internal/sbi/processor/amf_registration_for_non3_gpp_access.go +++ /dev/null @@ -1,68 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// Register - register as AMF for non-3GPP access -func (p *Processor) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { - var amfNon3GppAccessRegistration models.AmfNon3GppAccessRegistration - - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amfNon3GppAccessRegistration, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - logger.UecmLog.Infof("Handle RegisterAmfNon3gppAccessRequest") - - // step 2: retrieve request - ueID := c.Param("ueId") - - // step 3: handle the message - header, response, problemDetails := p.consumer.RegisterAmfNon3gppAccessProcedure(amfNon3GppAccessRegistration, ueID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/callback.go b/internal/sbi/processor/callback.go new file mode 100644 index 0000000..b2ab1bb --- /dev/null +++ b/internal/sbi/processor/callback.go @@ -0,0 +1,98 @@ +package processor + +import ( + "net/http" + + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" +) + +func (p *Processor) DataChangeNotificationProcedure( + notifyItems []models.NotifyItem, + supi string, +) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + if err != nil { + return pd + } + + ue, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) + + clientAPI := p.consumer.GetSDMClient("DataChangeNotification") + + var problemDetails *models.ProblemDetails + for _, subscriptionDataSubscription := range ue.UdmSubsToNotify { + onDataChangeNotificationurl := subscriptionDataSubscription.OriginalCallbackReference + dataChangeNotification := models.ModificationNotification{} + dataChangeNotification.NotifyItems = notifyItems + + httpResponse, err := clientAPI.DataChangeNotificationCallbackDocumentApi.OnDataChangeNotification( + ctx, onDataChangeNotificationurl, dataChangeNotification) + if err != nil { + if httpResponse == nil { + logger.HttpLog.Error(err.Error()) + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Detail: err.Error(), + } + } else { + logger.HttpLog.Errorln(err.Error()) + + problemDetails = &models.ProblemDetails{ + Status: int32(httpResponse.StatusCode), + Detail: err.Error(), + } + } + } + defer func() { + if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { + logger.HttpLog.Errorf("OnDataChangeNotification response body cannot close: %+v", rspCloseErr) + } + }() + } + + return problemDetails +} + +func (p *Processor) SendOnDeregistrationNotification(ueId string, onDeregistrationNotificationUrl string, + deregistData models.DeregistrationData, +) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NfType_UDM) + if err != nil { + return pd + } + + clientAPI := p.consumer.GetUECMClient("SendOnDeregistrationNotification") + + httpResponse, err := clientAPI.DeregistrationNotificationCallbackApi.DeregistrationNotify( + ctx, onDeregistrationNotificationUrl, deregistData) + if err != nil { + if httpResponse == nil { + logger.HttpLog.Error(err.Error()) + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "DEREGISTRATION_NOTIFICATION_ERROR", + Detail: err.Error(), + } + + return problemDetails + } else { + logger.HttpLog.Errorln(err.Error()) + problemDetails := &models.ProblemDetails{ + Status: int32(httpResponse.StatusCode), + Cause: "DEREGISTRATION_NOTIFICATION_ERROR", + Detail: err.Error(), + } + + return problemDetails + } + } + defer func() { + if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { + logger.HttpLog.Errorf("DeregistrationNotify response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} diff --git a/internal/sbi/processor/confirm_auth.go b/internal/sbi/processor/confirm_auth.go deleted file mode 100644 index 8edf229..0000000 --- a/internal/sbi/processor/confirm_auth.go +++ /dev/null @@ -1,57 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// ConfirmAuth - Create a new confirmation event -func (p *Processor) HandleConfirmAuth(c *gin.Context) { - var authEvent models.AuthEvent - // 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.UeauLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&authEvent, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UeauLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - supi := c.Params.ByName("supi") - - logger.UeauLog.Infoln("Handle ConfirmAuthDataRequest") - - problemDetails := p.consumer.ConfirmAuthDataProcedure(authEvent, supi) - - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusCreated) - return - } -} diff --git a/internal/sbi/processor/data_change_notification_to_nf.go b/internal/sbi/processor/data_change_notification_to_nf.go deleted file mode 100644 index b3385a0..0000000 --- a/internal/sbi/processor/data_change_notification_to_nf.go +++ /dev/null @@ -1,57 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -func (p *Processor) HandleDataChangeNotificationToNF(c *gin.Context) { - var dataChangeNotify models.DataChangeNotify - // 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.CallbackLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&dataChangeNotify, 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 - } - - supi := c.Params.ByName("supi") - - logger.CallbackLog.Infof("Handle DataChangeNotificationToNF") - - problemDetails := p.consumer.DataChangeNotificationProcedure(dataChangeNotify.NotifyItems, supi) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/ee_subscription.go b/internal/sbi/processor/ee_subscription.go deleted file mode 100644 index 10a7d8e..0000000 --- a/internal/sbi/processor/ee_subscription.go +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Nudm_EE - * - * Nudm Event Exposure Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// HTTPCreateEeSubscription - Subscribe -func (p *Processor) HandleCreateEeSubscription(c *gin.Context) { - var eesubscription models.EeSubscription - - requestBody, err := c.GetRawData() - if err != nil { - logger.EeLog.Errorf("Get Request Body error: %+v", err) - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&eesubscription, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.EeLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // Start - logger.EeLog.Infoln("Handle Create EE Subscription") - - ueIdentity := c.Params.ByName("ueIdentity") - - createdEESubscription, problemDetails := p.consumer.CreateEeSubscriptionProcedure(ueIdentity, eesubscription) - if createdEESubscription != nil { - c.JSON(http.StatusCreated, createdEESubscription) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetails) - return - } -} - -func (p *Processor) HandleDeleteEeSubscription(c *gin.Context) { - ueIdentity := c.Params.ByName("ueIdentity") - subscriptionID := c.Params.ByName("subscriptionId") - - p.consumer.DeleteEeSubscriptionProcedure(ueIdentity, subscriptionID) - // only return 204 no content - c.Status(http.StatusNoContent) -} - -func (p *Processor) HandleUpdateEeSubscription(c *gin.Context) { - var patchList []models.PatchItem - - requestBody, err := c.GetRawData() - if err != nil { - logger.EeLog.Errorf("Get Request Body error: %+v", err) - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&patchList, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.EeLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - ueIdentity := c.Params.ByName("ueIdentity") - subscriptionID := c.Params.ByName("subscriptionId") - - logger.EeLog.Infoln("Handle Update EE subscription") - logger.EeLog.Warnln("Update EE Subscription is not implemented") - - problemDetails := p.consumer.UpdateEeSubscriptionProcedure(ueIdentity, subscriptionID, patchList) - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/enent_exposure.go b/internal/sbi/processor/enent_exposure.go new file mode 100644 index 0000000..9f8e2b1 --- /dev/null +++ b/internal/sbi/processor/enent_exposure.go @@ -0,0 +1,209 @@ +package processor + +import ( + "net/http" + "strconv" + "strings" + + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" +) + +// EE service +func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, + eesubscription models.EeSubscription, +) (*models.CreatedEeSubscription, *models.ProblemDetails) { + udmSelf := udm_context.GetSelf() + logger.EeLog.Debugf("udIdentity: %s", ueIdentity) + switch { + // GPSI (MSISDN identifier) represents a single UE + case strings.HasPrefix(ueIdentity, "msisdn-"): + fallthrough + // GPSI (External identifier) represents a single UE + case strings.HasPrefix(ueIdentity, "extid-"): + if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { + id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() + if err != nil { + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + return nil, problemDetails + } + + subscriptionID := strconv.Itoa(int(id)) + ue.EeSubscriptions[subscriptionID] = &eesubscription + createdEeSubscription := &models.CreatedEeSubscription{ + EeSubscription: &eesubscription, + } + return createdEeSubscription, nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + return nil, problemDetails + } + // external groupID represents a group of UEs + case strings.HasPrefix(ueIdentity, "extgroupid-"): + id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() + if err != nil { + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + return nil, problemDetails + } + subscriptionID := strconv.Itoa(int(id)) + createdEeSubscription := &models.CreatedEeSubscription{ + EeSubscription: &eesubscription, + } + + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if ue.ExternalGroupID == ueIdentity { + ue.EeSubscriptions[subscriptionID] = &eesubscription + } + return true + }) + return createdEeSubscription, nil + // represents any UEs + case ueIdentity == "anyUE": + id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() + if err != nil { + problemDetails := &models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "UNSPECIFIED_NF_FAILURE", + } + return nil, problemDetails + } + subscriptionID := strconv.Itoa(int(id)) + createdEeSubscription := &models.CreatedEeSubscription{ + EeSubscription: &eesubscription, + } + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + ue.EeSubscriptions[subscriptionID] = &eesubscription + return true + }) + return createdEeSubscription, nil + default: + problemDetails := &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "MANDATORY_IE_INCORRECT", + InvalidParams: []models.InvalidParam{ + { + Param: "ueIdentity", + Reason: "incorrect format", + }, + }, + } + return nil, problemDetails + } +} + +// TODO: complete this procedure based on TS 29503 5.5 +func (p *Processor) DeleteEeSubscriptionProcedure(ueIdentity string, subscriptionID string) { + udmSelf := udm_context.GetSelf() + + switch { + case strings.HasPrefix(ueIdentity, "msisdn-"): + fallthrough + case strings.HasPrefix(ueIdentity, "extid-"): + if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { + delete(ue.EeSubscriptions, subscriptionID) + } + case strings.HasPrefix(ueIdentity, "extgroupid-"): + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if ue.ExternalGroupID == ueIdentity { + delete(ue.EeSubscriptions, subscriptionID) + } + return true + }) + case ueIdentity == "anyUE": + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + delete(ue.EeSubscriptions, subscriptionID) + return true + }) + } + if id, err := strconv.ParseInt(subscriptionID, 10, 64); err != nil { + logger.EeLog.Warnf("subscriptionID covert type error: %+v", err) + } else { + udmSelf.EeSubscriptionIDGenerator.FreeID(id) + } +} + +// TODO: complete this procedure based on TS 29503 5.5 +func (p *Processor) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptionID string, + patchList []models.PatchItem, +) *models.ProblemDetails { + udmSelf := udm_context.GetSelf() + + switch { + case strings.HasPrefix(ueIdentity, "msisdn-"): + fallthrough + case strings.HasPrefix(ueIdentity, "extid-"): + if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { + if _, ok := ue.EeSubscriptions[subscriptionID]; ok { + for _, patchItem := range patchList { + logger.EeLog.Debugf("patch item: %+v", patchItem) + // TODO: patch the Eesubscription + } + return nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "SUBSCRIPTION_NOT_FOUND", + } + return problemDetails + } + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "SUBSCRIPTION_NOT_FOUND", + } + return problemDetails + } + case strings.HasPrefix(ueIdentity, "extgroupid-"): + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if ue.ExternalGroupID == ueIdentity { + if _, ok := ue.EeSubscriptions[subscriptionID]; ok { + for _, patchItem := range patchList { + logger.EeLog.Debugf("patch item: %+v", patchItem) + // TODO: patch the Eesubscription + } + } + } + return true + }) + return nil + case ueIdentity == "anyUE": + udmSelf.UdmUePool.Range(func(key, value interface{}) bool { + ue := value.(*udm_context.UdmUeContext) + if _, ok := ue.EeSubscriptions[subscriptionID]; ok { + for _, patchItem := range patchList { + logger.EeLog.Debugf("patch item: %+v", patchItem) + // TODO: patch the Eesubscription + } + } + return true + }) + return nil + default: + problemDetails := &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "MANDATORY_IE_INCORRECT", + InvalidParams: []models.InvalidParam{ + { + Param: "ueIdentity", + Reason: "incorrect format", + }, + }, + } + return problemDetails + } +} diff --git a/internal/sbi/processor/generate_auth_data.go b/internal/sbi/processor/generate_auth_data.go index 8168c4b..87c88fa 100644 --- a/internal/sbi/processor/generate_auth_data.go +++ b/internal/sbi/processor/generate_auth_data.go @@ -1,70 +1,553 @@ package processor import ( + cryptoRand "crypto/rand" + "encoding/hex" + "fmt" + "math/big" + "math/rand" "net/http" + "reflect" + "strconv" + "strings" + "time" - "github.com/gin-gonic/gin" + "github.com/antihax/optional" "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nudr_DataRepository" "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" + "github.com/free5gc/udm/pkg/suci" + "github.com/free5gc/util/milenage" + "github.com/free5gc/util/ueauth" ) -// GenerateAuthData - Generate authentication data for the UE -func (p *Processor) HandleGenerateAuthData(c *gin.Context) { - var authInfoReq models.AuthenticationInfoRequest +const ( + SqnMAx int64 = 0xFFFFFFFFFFFF + ind int64 = 32 + keyStrLen int = 32 + opStrLen int = 32 + opcStrLen int = 32 +) + +const ( + authenticationRejected string = "AUTHENTICATION_REJECTED" + resyncAMF string = "0000" +) + +func (p *Processor) aucSQN(opc, k, auts, rand []byte) ([]byte, []byte) { + AK, SQNms := make([]byte, 6), make([]byte, 6) + macS := make([]byte, 8) + ConcSQNms := auts[:6] + AMF, err := hex.DecodeString(resyncAMF) + if err != nil { + return nil, nil + } + + logger.UeauLog.Tracef("aucSQN: ConcSQNms=[%x]", ConcSQNms) + + err = milenage.F2345(opc, k, rand, nil, nil, nil, nil, AK) + if err != nil { + logger.UeauLog.Errorln("aucSQN milenage F2345 err:", err) + } + + for i := 0; i < 6; i++ { + SQNms[i] = AK[i] ^ ConcSQNms[i] + } + + logger.UeauLog.Tracef("aucSQN: opc=[%x], k=[%x], rand=[%x], AMF=[%x], SQNms=[%x]\n", opc, k, rand, AMF, SQNms) + // The AMF used to calculate MAC-S assumes a dummy value of all zeros + err = milenage.F1(opc, k, rand, SQNms, AMF, nil, macS) + if err != nil { + logger.UeauLog.Errorln("aucSQN milenage F1 err:", err) + } + logger.UeauLog.Tracef("aucSQN: macS=[%x]\n", macS) + return SQNms, macS +} + +func (p *Processor) strictHex(ss string, n int) string { + l := len(ss) + if l < n { + return strings.Repeat("0", n-l) + ss + } else { + return ss[l-n : l] + } +} - // step 1: retrieve http request body - requestBody, err := c.GetRawData() +func (p *Processor) ConfirmAuthDataProcedure( + authEvent models.AuthEvent, + supi string, +) (problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, + return pd + } + var createAuthParam Nudr_DataRepository.CreateAuthenticationStatusParamOpts + optInterface := optional.NewInterface(authEvent) + createAuthParam.AuthEvent = optInterface + + client, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := client.AuthenticationStatusDocumentApi.CreateAuthenticationStatus( + ctx, supi, &createAuthParam) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("ConfirmAuth err:", err.Error()) + return problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UeauLog.Errorf("CreateAuthenticationStatus response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} + +func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.AuthenticationInfoRequest, supiOrSuci string) ( + response *models.AuthenticationInfoResult, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + logger.UeauLog.Traceln("In GenerateAuthDataProcedure") + + response = &models.AuthenticationInfoResult{} + rand.New(rand.NewSource(time.Now().UnixNano())) + supi, err := suci.ToSupi(supiOrSuci, udm_context.GetSelf().SuciProfiles) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, Detail: err.Error(), - Cause: "SYSTEM_FAILURE", } - logger.UeauLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return + + logger.UeauLog.Errorln("suciToSupi error: ", err.Error()) + return nil, problemDetails } - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&authInfoReq, requestBody, "application/json") + logger.UeauLog.Tracef("supi conversion => [%s]", supi) + + client, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + authSubs, res, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(ctx, supi, nil) if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + switch res.StatusCode { + case http.StatusNotFound: + logger.UeauLog.Warnf("Return from UDR QueryAuthSubsData error") + default: + logger.UeauLog.Errorln("Return from UDR QueryAuthSubsData error") } - logger.UeauLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return + return nil, problemDetails } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAuthSubsData response body cannot close: %+v", rspCloseErr) + } + }() + + /* + K, RAND, CK, IK: 128 bits (16 bytes) (hex len = 32) + SQN, AK: 48 bits (6 bytes) (hex len = 12) TS33.102 - 6.3.2 + AMF: 16 bits (2 bytes) (hex len = 4) TS33.102 - Annex H + */ + + hasK, hasOP, hasOPC := false, false, false + var kStr, opStr, opcStr string + var k, op, opc []byte + + if authSubs.PermanentKey != nil { + kStr = authSubs.PermanentKey.PermanentKeyValue + if len(kStr) == keyStrLen { + k, err = hex.DecodeString(kStr) + if err != nil { + logger.UeauLog.Errorln("err:", err) + } else { + hasK = true + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + logger.UeauLog.Errorln("kStr length is ", len(kStr)) + return nil, problemDetails + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } - // step 1: log - logger.UeauLog.Infoln("Handle GenerateAuthDataRequest") + logger.UeauLog.Errorln("Nil PermanentKey") + return nil, problemDetails + } - // step 2: retrieve request - supiOrSuci := c.Param("supiOrSuci") + if authSubs.Milenage != nil { + if authSubs.Milenage.Op != nil && authSubs.Milenage.Op.OpValue != "" { + opStr = authSubs.Milenage.Op.OpValue + if len(opStr) == opStrLen { + op, err = hex.DecodeString(opStr) + if err != nil { + logger.UeauLog.Errorln("err:", err) + } else { + hasOP = true + } + } else { + logger.UeauLog.Errorln("opStr length is ", len(opStr)) + } + } else { + logger.UeauLog.Infoln("Nil Op") + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } - // step 3: handle the message - response, problemDetails := p.consumer.GenerateAuthDataProcedure(authInfoReq, supiOrSuci) + logger.UeauLog.Infoln("Nil Milenage") + return nil, problemDetails + } - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return + if authSubs.Opc != nil && authSubs.Opc.OpcValue != "" { + opcStr = authSubs.Opc.OpcValue + if len(opcStr) == opcStrLen { + opc, err = hex.DecodeString(opcStr) + if err != nil { + logger.UeauLog.Errorln("err:", err) + } else { + hasOPC = true + } + } else { + logger.UeauLog.Errorln("opcStr length is ", len(opcStr)) + } } else { + logger.UeauLog.Infoln("Nil Opc") + } + + if !hasOPC && !hasOP { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + return nil, problemDetails + } + + if !hasOPC { + if hasK && hasOP { + opc, err = milenage.GenerateOPC(k, op) + if err != nil { + logger.UeauLog.Errorln("milenage GenerateOPC err:", err) + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + } + + logger.UeauLog.Errorln("Unable to derive OPC") + return nil, problemDetails + } + } + + sqnStr := p.strictHex(authSubs.SequenceNumber, 12) + logger.UeauLog.Traceln("sqnStr", sqnStr) + sqn, err := hex.DecodeString(sqnStr) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + logger.UeauLog.Tracef("K=[%x], sqn=[%x], OP=[%x], OPC=[%x]", k, sqn, op, opc) + + RAND := make([]byte, 16) + _, err = cryptoRand.Read(RAND) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + amfStr := p.strictHex(authSubs.AuthenticationManagementField, 4) + logger.UeauLog.Traceln("amfStr", amfStr) + AMF, err := hex.DecodeString(amfStr) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + logger.UeauLog.Tracef("RAND=[%x], AMF=[%x]", RAND, AMF) + + // re-synchronization + if authInfoRequest.ResynchronizationInfo != nil { + logger.UeauLog.Infof("Authentication re-synchronization") + + Auts, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Auts) + if deCodeErr != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: deCodeErr.Error(), + } + + logger.UeauLog.Errorln("err:", deCodeErr) + return nil, problemDetails + } + + randHex, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Rand) + if deCodeErr != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: deCodeErr.Error(), + } + + logger.UeauLog.Errorln("err:", deCodeErr) + return nil, problemDetails + } + + SQNms, macS := p.aucSQN(opc, k, Auts, randHex) + if reflect.DeepEqual(macS, Auts[6:]) { + _, err = cryptoRand.Read(RAND) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: deCodeErr.Error(), + } + + logger.UeauLog.Errorln("err:", deCodeErr) + return nil, problemDetails + } + + // increment sqn authSubs.SequenceNumber + bigSQN := big.NewInt(0) + sqnStr = hex.EncodeToString(SQNms) + logger.UeauLog.Tracef("SQNstr=[%s]", sqnStr) + bigSQN.SetString(sqnStr, 16) + + bigInc := big.NewInt(ind + 1) + + bigP := big.NewInt(SqnMAx) + bigSQN = bigInc.Add(bigSQN, bigInc) + bigSQN = bigSQN.Mod(bigSQN, bigP) + sqnStr = fmt.Sprintf("%x", bigSQN) + sqnStr = p.strictHex(sqnStr, 12) + } else { + logger.UeauLog.Errorln("Re-Sync MAC failed ", supiOrSuci) + // Check if suci + suciPart := strings.Split(supiOrSuci, "-") + if suciPart[suci.PrefixPlace] == suci.PrefixSUCI && + suciPart[suci.SupiTypePlace] == suci.SupiTypeIMSI && + suciPart[suci.SchemePlace] != suci.NullScheme { + // Get SuciProfile index and write public key + keyIndex, err1 := strconv.Atoi(suciPart[suci.HNPublicKeyIDPlace]) + if err1 != nil { + logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace parse Error") + } else if keyIndex < 1 { + logger.UeauLog.Errorf("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace keyIndex[%d] < 1", + keyIndex) + } else { + logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key ", + udm_context.GetSelf().SuciProfiles[keyIndex-1].PublicKey) + } + } + logger.UeauLog.Errorln("MACS ", macS) + logger.UeauLog.Errorln("Auts[6:] ", Auts[6:]) + logger.UeauLog.Errorln("Sqn ", SQNms) + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "modification is rejected", + } + return nil, problemDetails + } + } + + // increment sqn + bigSQN := big.NewInt(0) + sqn, err = hex.DecodeString(sqnStr) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: authenticationRejected, + Detail: err.Error(), + } + + logger.UeauLog.Errorln("err:", err) + return nil, problemDetails + } + + bigSQN.SetString(sqnStr, 16) + + bigInc := big.NewInt(1) + bigSQN = bigInc.Add(bigSQN, bigInc) + + SQNheStr := fmt.Sprintf("%x", bigSQN) + SQNheStr = p.strictHex(SQNheStr, 12) + patchItemArray := []models.PatchItem{ + { + Op: models.PatchOperation_REPLACE, + Path: "/sequenceNumber", + Value: SQNheStr, + }, + } + + var rsp *http.Response + + rsp, err = client.AuthenticationDataDocumentApi.ModifyAuthentication( + ctx, supi, patchItemArray) + if err != nil { problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, - Cause: "UNSPECIFIED", + Cause: "modification is rejected ", + Detail: err.Error(), + } + + logger.UeauLog.Errorln("update sqn error:", err) + return nil, problemDetails + } + defer func() { + if rspCloseErr := rsp.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("ModifyAuthentication response body cannot close: %+v", rspCloseErr) + } + }() + + // Run milenage + macA, macS := make([]byte, 8), make([]byte, 8) + CK, IK := make([]byte, 16), make([]byte, 16) + RES := make([]byte, 8) + AK, AKstar := make([]byte, 6), make([]byte, 6) + + // Generate macA, macS + err = milenage.F1(opc, k, RAND, sqn, AMF, macA, macS) + if err != nil { + logger.UeauLog.Errorln("milenage F1 err:", err) + } + + // Generate RES, CK, IK, AK, AKstar + // RES == XRES (expected RES) for server + err = milenage.F2345(opc, k, RAND, RES, CK, IK, AK, AKstar) + if err != nil { + logger.UeauLog.Errorln("milenage F2345 err:", err) + } + logger.UeauLog.Tracef("milenage RES=[%s]", hex.EncodeToString(RES)) + + // Generate AUTN + logger.UeauLog.Tracef("SQN=[%x], AK=[%x]", sqn, AK) + logger.UeauLog.Tracef("AMF=[%x], macA=[%x]", AMF, macA) + SQNxorAK := make([]byte, 6) + for i := 0; i < len(sqn); i++ { + SQNxorAK[i] = sqn[i] ^ AK[i] + } + logger.UeauLog.Tracef("SQN xor AK=[%x]", SQNxorAK) + AUTN := append(append(SQNxorAK, AMF...), macA...) + logger.UeauLog.Tracef("AUTN=[%x]", AUTN) + + var av models.AuthenticationVector + if authSubs.AuthenticationMethod == models.AuthMethod__5_G_AKA { + response.AuthType = models.AuthType__5_G_AKA + + // derive XRES* + key := append(CK, IK...) + FC := ueauth.FC_FOR_RES_STAR_XRES_STAR_DERIVATION + P0 := []byte(authInfoRequest.ServingNetworkName) + P1 := RAND + P2 := RES + + kdfValForXresStar, err := ueauth.GetKDFValue( + key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1), P2, ueauth.KDFLen(P2)) + if err != nil { + logger.UeauLog.Errorf("Get kdfValForXresStar err: %+v", err) + } + xresStar := kdfValForXresStar[len(kdfValForXresStar)/2:] + logger.UeauLog.Tracef("xresStar=[%x]", xresStar) + + // derive Kausf + FC = ueauth.FC_FOR_KAUSF_DERIVATION + P0 = []byte(authInfoRequest.ServingNetworkName) + P1 = SQNxorAK + kdfValForKausf, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) + if err != nil { + logger.UeauLog.Errorf("Get kdfValForKausf err: %+v", err) + } + logger.UeauLog.Tracef("Kausf=[%x]", kdfValForKausf) + + // Fill in rand, xresStar, autn, kausf + av.Rand = hex.EncodeToString(RAND) + av.XresStar = hex.EncodeToString(xresStar) + av.Autn = hex.EncodeToString(AUTN) + av.Kausf = hex.EncodeToString(kdfValForKausf) + av.AvType = models.AvType__5_G_HE_AKA + } else { // EAP-AKA' + response.AuthType = models.AuthType_EAP_AKA_PRIME + + // derive CK' and IK' + key := append(CK, IK...) + FC := ueauth.FC_FOR_CK_PRIME_IK_PRIME_DERIVATION + P0 := []byte(authInfoRequest.ServingNetworkName) + P1 := SQNxorAK + kdfVal, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) + if err != nil { + logger.UeauLog.Errorf("Get kdfVal err: %+v", err) } - c.JSON(http.StatusForbidden, problemDetails) - return + logger.UeauLog.Tracef("kdfVal=[%x] (len=%d)", kdfVal, len(kdfVal)) + + // For TS 35.208 test set 19 & RFC 5448 test vector 1 + // CK': 0093 962d 0dd8 4aa5 684b 045c 9edf fa04 + // IK': ccfc 230c a74f cc96 c0a5 d611 64f5 a76 + + ckPrime := kdfVal[:len(kdfVal)/2] + ikPrime := kdfVal[len(kdfVal)/2:] + logger.UeauLog.Tracef("ckPrime=[%x], kPrime=[%x]", ckPrime, ikPrime) + + // Fill in rand, xres, autn, ckPrime, ikPrime + av.Rand = hex.EncodeToString(RAND) + av.Xres = hex.EncodeToString(RES) + av.Autn = hex.EncodeToString(AUTN) + av.CkPrime = hex.EncodeToString(ckPrime) + av.IkPrime = hex.EncodeToString(ikPrime) + av.AvType = models.AvType_EAP_AKA_PRIME } + + response.AuthenticationVector = &av + response.Supi = supi + return response, nil } diff --git a/internal/sbi/processor/gpsi_to_supi_translation.go b/internal/sbi/processor/gpsi_to_supi_translation.go deleted file mode 100644 index bda7afd..0000000 --- a/internal/sbi/processor/gpsi_to_supi_translation.go +++ /dev/null @@ -1,41 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetIdTranslationResult - retrieve a UE's SUPI -func (p *Processor) HandleGetIdTranslationResult(c *gin.Context) { - // req.Query.Set("SupportedFeatures", c.Query("supported-features")) - - // step 1: log - logger.SdmLog.Infof("Handle GetIdTranslationResultRequest") - - // step 2: retrieve request - gpsi := c.Params.ByName("gpsi") - - // step 3: handle the message - response, problemDetails := p.consumer.GetIdTranslationResultProcedure(gpsi) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/index.go b/internal/sbi/processor/index.go deleted file mode 100644 index dcf7781..0000000 --- a/internal/sbi/processor/index.go +++ /dev/null @@ -1,11 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -func (p *Processor) HandleIndex(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} diff --git a/internal/sbi/processor/parameter_provision.go b/internal/sbi/processor/parameter_provision.go new file mode 100644 index 0000000..f6f9fb1 --- /dev/null +++ b/internal/sbi/processor/parameter_provision.go @@ -0,0 +1,37 @@ +package processor + +import ( + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" +) + +func (p *Processor) UpdateProcedure( + updateRequest models.PpData, + gpsi string, +) (problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR(gpsi) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + res, err := clientAPI.ProvisionedParameterDataDocumentApi.ModifyPpData(ctx, gpsi, nil) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.PpLog.Errorf("ModifyPpData response body cannot close: %+v", rspCloseErr) + } + }() + return nil +} diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go deleted file mode 100644 index 06b07e5..0000000 --- a/internal/sbi/processor/parameter_update_in_the_amf_registration_for3_gpp_access.go +++ /dev/null @@ -1,62 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// UpdateAmf3gppAccess - Update a parameter in the AMF registration for 3GPP access -func (p *Processor) HandleUpdateAmf3gppAccess(c *gin.Context) { - var amf3GppAccessRegistrationModification models.Amf3GppAccessRegistrationModification - - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amf3GppAccessRegistrationModification, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.UecmLog.Infof("Handle UpdateAmf3gppAccessRequest") - - // step 2: retrieve request - ueID := c.Param("ueId") - - // step 3: handle the message - problemDetails := p.consumer.UpdateAmf3gppAccessProcedure(amf3GppAccessRegistrationModification, ueID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go b/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go deleted file mode 100644 index 9fddc79..0000000 --- a/internal/sbi/processor/parameter_update_in_the_amf_registration_for_non3_gpp_access.go +++ /dev/null @@ -1,61 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access -func (p *Processor) HandleUpdateAmfNon3gppAccess(c *gin.Context) { - var amfNon3GppAccessRegistrationModification models.AmfNon3GppAccessRegistrationModification - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amfNon3GppAccessRegistrationModification, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.UecmLog.Infof("Handle UpdateAmfNon3gppAccessRequest") - - // step 2: retrieve request - ueID := c.Param("ueId") - - // step 3: handle the message - problemDetails := p.consumer.UpdateAmfNon3gppAccessProcedure(amfNon3GppAccessRegistrationModification, ueID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go b/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go deleted file mode 100644 index 8689cb6..0000000 --- a/internal/sbi/processor/providing_acknowledgement_of_steering_of_roaming.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// Info - Nudm_Sdm Info service operation -func (p *Processor) HandleInfo(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go b/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go deleted file mode 100644 index 97d9b3a..0000000 --- a/internal/sbi/processor/providing_acknowledgement_of_ue_parameters_update.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// PutUpuAck - Nudm_Sdm Info for UPU service operation -func (p *Processor) HandlePutUpuAck(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/retrieval_of_multiple_data_sets.go b/internal/sbi/processor/retrieval_of_multiple_data_sets.go deleted file mode 100644 index 7497837..0000000 --- a/internal/sbi/processor/retrieval_of_multiple_data_sets.go +++ /dev/null @@ -1,54 +0,0 @@ -package processor - -import ( - "net/http" - "net/url" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetSupi - retrieve multiple data sets -func (p *Processor) HandleGetSupi(c *gin.Context) { - var query url.Values - query.Set("plmn-id", c.Query("plmn-id")) - query.Set("dataset-names", c.Query("dataset-names")) - query.Set("supported-features", c.Query("supported-features")) - - // step 1: log - logger.SdmLog.Infof("Handle GetSupiRequest") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - dataSetNames := strings.Split(query.Get("dataset-names"), ",") - supportedFeatures := query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := p.consumer.GetSupiProcedure(supi, plmnID, dataSetNames, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/retrieval_of_shared_data.go b/internal/sbi/processor/retrieval_of_shared_data.go deleted file mode 100644 index 314b9e8..0000000 --- a/internal/sbi/processor/retrieval_of_shared_data.go +++ /dev/null @@ -1,39 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetSharedData - retrieve shared data -func (p *Processor) HandleGetSharedData(c *gin.Context) { - // step 1: log - logger.SdmLog.Infof("Handle GetSharedData") - - // step 2: retrieve request - sharedDataIds := c.QueryArray("shared-data-ids") - supportedFeatures := c.QueryArray("supported-features") - // step 3: handle the message - response, problemDetails := p.consumer.GetSharedDataProcedure(sharedDataIds, supportedFeatures[0]) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/sdm_route.go b/internal/sbi/processor/sdm_route.go deleted file mode 100644 index 995f830..0000000 --- a/internal/sbi/processor/sdm_route.go +++ /dev/null @@ -1,203 +0,0 @@ -package processor - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" -) - -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 -} - -func (p *Processor) OneLayerPathHandlerFunc(c *gin.Context) { - supi := c.Param("supi") - oneLayerPathRouter := p.getOneLayerRoutes() - for _, route := range oneLayerPathRouter { - if strings.Contains(route.Pattern, supi) && route.Method == c.Request.Method { - route.HandlerFunc(c) - return - } - } - - // special case for :supi - if c.Request.Method == strings.ToUpper("Get") { - p.HandleGetSupi(c) - return - } - - c.String(http.StatusNotFound, "404 page not found") -} - -func (p *Processor) TwoLayerPathHandlerFunc(c *gin.Context) { - supi := c.Param("supi") - op := c.Param("subscriptionId") - - // for "/shared-data-subscriptions/:subscriptionId" - if supi == "shared-data-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { - p.HandleUnsubscribeForSharedData(c) - return - } - - // for "/shared-data-subscriptions/:subscriptionId" - if supi == "shared-data-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { - p.HandleModifyForSharedData(c) - return - } - - // for "/:gpsi/id-translation-result" - if op == "id-translation-result" && strings.ToUpper("Get") == c.Request.Method { - c.Params = append(c.Params, gin.Param{Key: "gpsi", Value: c.Param("supi")}) - p.HandleGetIdTranslationResult(c) - return - } - - twoLayerPathRouter := p.getTwoLayerRoutes() - for _, route := range twoLayerPathRouter { - if strings.Contains(route.Pattern, op) && route.Method == c.Request.Method { - route.HandlerFunc(c) - return - } - } - - c.String(http.StatusNotFound, "404 page not found") -} - -func (p *Processor) ThreeLayerPathHandlerFunc(c *gin.Context) { - op := c.Param("subscriptionId") - - // for "/:supi/sdm-subscriptions/:subscriptionId" - if op == "sdm-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { - var tmpParams gin.Params - tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) - tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) - c.Params = tmpParams - p.HandleUnsubscribe(c) - return - } - - // for "/:supi/am-data/sor-ack" - if op == "am-data" && strings.ToUpper("Put") == c.Request.Method { - p.HandleInfo(c) - return - } - - // for "/:supi/sdm-subscriptions/:subscriptionId" - if op == "sdm-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { - var tmpParams gin.Params - tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) - tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) - c.Params = tmpParams - p.HandleModify(c) - return - } - - c.String(http.StatusNotFound, "404 page not found") -} - -func (p *Processor) getOneLayerRoutes() []Route { - return []Route{ - { - "GetSupi", - strings.ToUpper("Get"), - "/:supi", - p.HandleGetSupi, - }, - - { - "GetSharedData", - strings.ToUpper("Get"), - "/shared-data", - p.HandleGetSharedData, - }, - - { - "SubscribeToSharedData", - strings.ToUpper("Post"), - "/shared-data-subscriptions", - p.HandleSubscribeToSharedData, - }, - } -} - -func (p *Processor) getTwoLayerRoutes() []Route { - return []Route{ - { - "GetAmData", - strings.ToUpper("Get"), - "/:supi/am-data", - p.HandleGetAmData, - }, - - { - "GetSmfSelectData", - strings.ToUpper("Get"), - "/:supi/smf-select-data", - p.HandleGetSmfSelectData, - }, - - { - "GetSmsMngData", - strings.ToUpper("Get"), - "/:supi/sms-mng-data", - p.HandleGetSmsMngData, - }, - - { - "GetSmsData", - strings.ToUpper("Get"), - "/:supi/sms-data", - p.HandleGetSmsData, - }, - - { - "GetSmData", - strings.ToUpper("Get"), - "/:supi/sm-data", - p.HandleGetSmData, - }, - - { - "GetNssai", - strings.ToUpper("Get"), - "/:supi/nssai", - p.HandleGetNssai, - }, - - { - "Subscribe", - strings.ToUpper("Post"), - "/:supi/sdm-subscriptions", - p.HandleSubscribe, - }, - - { - "GetTraceData", - strings.ToUpper("Get"), - "/:supi/trace-data", - p.HandleGetTraceData, - }, - - { - "GetUeContextInSmfData", - strings.ToUpper("Get"), - "/:supi/ue-context-in-smf-data", - p.HandleGetUeContextInSmfData, - }, - - { - "GetUeContextInSmsfData", - strings.ToUpper("Get"), - "/:supi/ue-context-in-smsf-data", - p.HandleGetUeContextInSmsfData, - }, - } -} diff --git a/internal/sbi/processor/session_management_subscription_data_retrieval.go b/internal/sbi/processor/session_management_subscription_data_retrieval.go deleted file mode 100644 index de3a147..0000000 --- a/internal/sbi/processor/session_management_subscription_data_retrieval.go +++ /dev/null @@ -1,55 +0,0 @@ -package processor - -import ( - "net/http" - "net/url" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetSmData - retrieve a UE's Session Management Subscription Data -func (p *Processor) HandleGetSmData(c *gin.Context) { - var query url.Values - query.Set("plmn-id", c.Query("plmn-id")) - query.Set("dnn", c.Query("dnn")) - query.Set("single-nssai", c.Query("single-nssai")) - query.Set("supported-features", c.Query("supported-features")) - - // step 1: log - logger.SdmLog.Infof("Handle GetSmData") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - Dnn := query.Get("dnn") - Snssai := query.Get("single-nssai") - supportedFeatures := query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := p.consumer.GetSmDataProcedure(supi, plmnID, Dnn, Snssai, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go b/internal/sbi/processor/slice_selection_subscription_data_retrieval.go deleted file mode 100644 index 8b66fbe..0000000 --- a/internal/sbi/processor/slice_selection_subscription_data_retrieval.go +++ /dev/null @@ -1,51 +0,0 @@ -package processor - -import ( - "net/http" - "net/url" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetNssai - retrieve a UE's subscribed NSSAI -func (p *Processor) HandleGetNssai(c *gin.Context) { - var query url.Values - query.Set("plmn-id", c.Query("plmn-id")) - query.Set("supported-features", c.Query("supported-features")) - - // step 1: log - logger.SdmLog.Infof("Handle GetNssai") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - supportedFeatures := query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := p.consumer.GetNssaiProcedure(supi, plmnID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/smf_deregistration.go b/internal/sbi/processor/smf_deregistration.go deleted file mode 100644 index c5e6dda..0000000 --- a/internal/sbi/processor/smf_deregistration.go +++ /dev/null @@ -1,31 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/udm/internal/logger" -) - -// DeregistrationSmfRegistrations - delete an SMF registration -func (p *Processor) HandleDeregistrationSmfRegistrations(c *gin.Context) { - // step 1: log - logger.UecmLog.Infof("Handle DeregistrationSmfRegistrations") - - // step 2: retrieve request - ueID := c.Params.ByName("ueId") - pduSessionID := c.Params.ByName("pduSessionId") - - // step 3: handle the message - problemDetails := p.consumer.DeregistrationSmfRegistrationsProcedure(ueID, pduSessionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/smf_registration.go b/internal/sbi/processor/smf_registration.go deleted file mode 100644 index ce8038f..0000000 --- a/internal/sbi/processor/smf_registration.go +++ /dev/null @@ -1,75 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// RegistrationSmfRegistrations - register as SMF -func (p *Processor) HandleRegistrationSmfRegistrations(c *gin.Context) { - var smfRegistration models.SmfRegistration - - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&smfRegistration, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.UecmLog.Infof("Handle RegistrationSmfRegistrations") - - // step 2: retrieve request - ueID := c.Params.ByName("ueId") - pduSessionID := c.Params.ByName("pduSessionId") - - // step 3: handle the message - header, response, problemDetails := p.consumer.RegistrationSmfRegistrationsProcedure( - &smfRegistration, - ueID, - pduSessionID, - ) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - // all nil - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go b/internal/sbi/processor/smf_selection_subscription_data_retrieval.go deleted file mode 100644 index 3b2b16f..0000000 --- a/internal/sbi/processor/smf_selection_subscription_data_retrieval.go +++ /dev/null @@ -1,51 +0,0 @@ -package processor - -import ( - "net/http" - "net/url" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data -func (p *Processor) HandleGetSmfSelectData(c *gin.Context) { - var query url.Values - query.Set("plmn-id", c.Query("plmn-id")) - query.Set("supported-features", c.Query("supported-features")) - - // step 1: log - logger.SdmLog.Infof("Handle GetSmfSelectData") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - plmnIDStruct, problemDetails := p.getPlmnIDStruct(query) - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - supportedFeatures := query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := p.consumer.GetSmfSelectDataProcedure(supi, plmnID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/sms_management_subscription_data_retrieval.go b/internal/sbi/processor/sms_management_subscription_data_retrieval.go deleted file mode 100644 index 771112c..0000000 --- a/internal/sbi/processor/sms_management_subscription_data_retrieval.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsMngData - retrieve a UE's SMS Management Subscription Data -func (p *Processor) HandleGetSmsMngData(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/sms_subscription_data_retrieval.go b/internal/sbi/processor/sms_subscription_data_retrieval.go deleted file mode 100644 index 66c6567..0000000 --- a/internal/sbi/processor/sms_subscription_data_retrieval.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsData - retrieve a UE's SMS Subscription Data -func (p *Processor) HandleGetSmsData(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index 72a6909..0000000 --- a/internal/sbi/processor/smsf3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsf3gppAccess - retrieve the SMSF registration for 3GPP access information -func (p *Processor) HandleGetSmsf3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go b/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go deleted file mode 100644 index a0263e7..0000000 --- a/internal/sbi/processor/smsf_deregistration_for3_gpp_access.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// DeregistrationSmsf3gppAccess - delete the SMSF registration for 3GPP access -func (p *Processor) HandleDeregistrationSmsf3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go b/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go deleted file mode 100644 index 4a12cf3..0000000 --- a/internal/sbi/processor/smsf_deregistration_for_non3_gpp_access.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// DeregistrationSmsfNon3gppAccess - delete SMSF registration for non 3GPP access -func (p *Processor) HandleDeregistrationSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index 492d071..0000000 --- a/internal/sbi/processor/smsf_non3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsfNon3gppAccess - retrieve the SMSF registration for non-3GPP access information -func (p *Processor) HandleGetSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/smsf_registration_for3_gpp_access.go b/internal/sbi/processor/smsf_registration_for3_gpp_access.go deleted file mode 100644 index ab2a13b..0000000 --- a/internal/sbi/processor/smsf_registration_for3_gpp_access.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// UpdateSMSFReg3GPP - register as SMSF for 3GPP access -func (p *Processor) HandleUpdateSMSFReg3GPP(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go b/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go deleted file mode 100644 index 65e2023..0000000 --- a/internal/sbi/processor/smsf_registration_for_non3_gpp_access.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// RegistrationSmsfNon3gppAccess - register as SMSF for non-3GPP access -func (p *Processor) HandleRegistrationSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/subscriber_data_management.go b/internal/sbi/processor/subscriber_data_management.go new file mode 100644 index 0000000..0ca3e37 --- /dev/null +++ b/internal/sbi/processor/subscriber_data_management.go @@ -0,0 +1,1127 @@ +package processor + +import ( + "net/http" + "strconv" + + "github.com/antihax/optional" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nudr_DataRepository" + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" +) + +func (p *Processor) GetAmDataProcedure(supi string, plmnID string, supportedFeatures string) ( + response *models.AccessAndMobilitySubscriptionData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. + QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetAMSubsriptionData(&accessAndMobilitySubscriptionDataResp) + return &accessAndMobilitySubscriptionDataResp, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (p *Processor) GetIdTranslationResultProcedure(gpsi string) (response *models.IdTranslationResult, + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var idTranslationResult models.IdTranslationResult + var getIdentityDataParamOpts Nudr_DataRepository.GetIdentityDataParamOpts + + clientAPI, err := p.consumer.CreateUDMClientToUDR(gpsi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + idTranslationResultResp, res, err := clientAPI.QueryIdentityDataBySUPIOrGPSIDocumentApi.GetIdentityData( + ctx, gpsi, &getIdentityDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("GetIdentityData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + if idList := idTranslationResultResp; idList.SupiList != nil { + // GetCorrespondingSupi get corresponding Supi(here IMSI) matching the given Gpsi from the queried SUPI list from UDR + idTranslationResult.Supi = udm_context.GetCorrespondingSupi(idList) + idTranslationResult.Gpsi = gpsi + + return &idTranslationResult, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames []string, supportedFeatures string) ( + response *models.SubscriptionDataSets, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + if len(dataSetNames) < 2 { + problemDetails = &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "BAD_REQUEST", + Detail: "datasetNames must have at least 2 elements", + } + return nil, problemDetails + } + + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var subscriptionDataSets, subsDataSetBody models.SubscriptionDataSets + var ueContextInSmfDataResp models.UeContextInSmfData + pduSessionMap := make(map[string]models.PduSession) + var pgwInfoArray []models.PgwInfo + + var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + var querySmfSelectDataParamOpts Nudr_DataRepository.QuerySmfSelectDataParamOpts + var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts + var querySmDataParamOpts Nudr_DataRepository.QuerySmDataParamOpts + + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + udm_context.GetSelf().CreateSubsDataSetsForUe(supi, subsDataSetBody) + + if p.containDataSetName(dataSetNames, string(models.DataSetName_AM)) { + var body models.AccessAndMobilitySubscriptionData + udm_context.GetSelf().CreateAccessMobilitySubsDataForUe(supi, body) + + amData, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi.QueryAmData( + ctx, supi, plmnID, &queryAmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetAMSubsriptionData(&amData) + subscriptionDataSets.AmData = &amData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + if p.containDataSetName(dataSetNames, string(models.DataSetName_SMF_SEL)) { + var smfSelSubsbody models.SmfSelectionSubscriptionData + udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, smfSelSubsbody) + + smfSelData, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi.QuerySmfSelectData(ctx, + supi, plmnID, &querySmfSelectDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorln(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorln(err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetSmfSelectionSubsData(&smfSelData) + subscriptionDataSets.SmfSelData = &smfSelData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + if p.containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMF)) { + var UeContextInSmfbody models.UeContextInSmfData + var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts + querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, UeContextInSmfbody) + + pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( + ctx, supi, &querySmfRegListParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) + } + }() + + for _, element := range pdusess { + var pduSession models.PduSession + pduSession.Dnn = element.Dnn + pduSession.SmfInstanceId = element.SmfInstanceId + pduSession.PlmnId = element.PlmnId + pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession + } + ueContextInSmfDataResp.PduSessions = pduSessionMap + + for _, element := range pdusess { + var pgwInfo models.PgwInfo + pgwInfo.Dnn = element.Dnn + pgwInfo.PgwFqdn = element.PgwFqdn + pgwInfo.PlmnId = element.PlmnId + pgwInfoArray = append(pgwInfoArray, pgwInfo) + } + ueContextInSmfDataResp.PgwInfo = pgwInfoArray + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.UeCtxtInSmfData = &ueContextInSmfDataResp + subscriptionDataSets.UecSmfData = &ueContextInSmfDataResp + } else { + var problemDetails models.ProblemDetails + problemDetails.Cause = "DATA_NOT_FOUND" + logger.SdmLog.Errorf(problemDetails.Cause) + } + } + + // TODO: UE Context in SMSF Data + // if containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMSF)) { + // } + + // TODO: SMS Subscription Data + // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_SUB)) { + // } + + if p.containDataSetName(dataSetNames, string(models.DataSetName_SM)) { + sessionManagementSubscriptionData, res, err := clientAPI.SessionManagementSubscriptionDataApi. + QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + smData, _, _, _ := udm_context.GetSelf().ManageSmData(sessionManagementSubscriptionData, "", "") + udmUe.SetSMSubsData(smData) + subscriptionDataSets.SmData = sessionManagementSubscriptionData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + if p.containDataSetName(dataSetNames, string(models.DataSetName_TRACE)) { + var TraceDatabody models.TraceData + udm_context.GetSelf().CreateTraceDataforUe(supi, TraceDatabody) + + traceData, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( + ctx, supi, plmnID, &queryTraceDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Errorf(err.Error()) + } else if err.Error() != res.Status { + logger.SdmLog.Errorf("Response State: %+v", err.Error()) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) + } + }() + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.TraceData = &traceData + udmUe.TraceDataResponse.TraceData = &traceData + subscriptionDataSets.TraceData = &traceData + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } + } + + // TODO: SMS Management Subscription Data + // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_MNG)) { + // } + + return &subscriptionDataSets, nil +} + +func (p *Processor) GetSharedDataProcedure(sharedDataIds []string, supportedFeatures string) ( + response []models.SharedData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR("") + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var getSharedDataParamOpts Nudr_DataRepository.GetSharedDataParamOpts + getSharedDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + sharedDataResp, res, err := clientAPI.RetrievalOfSharedDataApi.GetSharedData(ctx, sharedDataIds, + &getSharedDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("GetShareData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udm_context.GetSelf().SharedSubsDataMap = udm_context.MappingSharedData(sharedDataResp) + sharedData := udm_context.ObtainRequiredSharedData(sharedDataIds, sharedDataResp) + return sharedData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (p *Processor) GetSmDataProcedure( + supi string, + plmnID string, + Dnn string, + Snssai string, + supportedFeatures string, +) ( + response interface{}, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + logger.SdmLog.Infof("getSmDataProcedure: SUPI[%s] PLMNID[%s] DNN[%s] SNssai[%s]", supi, plmnID, Dnn, Snssai) + + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var querySmDataParamOpts Nudr_DataRepository.QuerySmDataParamOpts + querySmDataParamOpts.SingleNssai = optional.NewInterface(Snssai) + + sessionManagementSubscriptionDataResp, res, err := clientAPI.SessionManagementSubscriptionDataApi. + QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + smData, snssaikey, AllDnnConfigsbyDnn, AllDnns := udm_context.GetSelf().ManageSmData( + sessionManagementSubscriptionDataResp, Snssai, Dnn) + udmUe.SetSMSubsData(smData) + + rspSMSubDataList := make([]models.SessionManagementSubscriptionData, 0, 4) + + udmUe.SmSubsDataLock.RLock() + for _, eachSMSubData := range udmUe.SessionManagementSubsData { + rspSMSubDataList = append(rspSMSubDataList, eachSMSubData) + } + udmUe.SmSubsDataLock.RUnlock() + + switch { + case Snssai == "" && Dnn == "": + return AllDnns, nil + case Snssai != "" && Dnn == "": + udmUe.SmSubsDataLock.RLock() + defer udmUe.SmSubsDataLock.RUnlock() + return udmUe.SessionManagementSubsData[snssaikey].DnnConfigurations, nil + case Snssai == "" && Dnn != "": + return AllDnnConfigsbyDnn, nil + case Snssai != "" && Dnn != "": + return rspSMSubDataList, nil + default: + udmUe.SmSubsDataLock.RLock() + defer udmUe.SmSubsDataLock.RUnlock() + return udmUe.SessionManagementSubsData, nil + } + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (p *Processor) GetNssaiProcedure(supi string, plmnID string, supportedFeatures string) ( + *models.Nssai, *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts + queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + var nssaiResp models.Nssai + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. + QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails := &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) + } + }() + + nssaiResp = *accessAndMobilitySubscriptionDataResp.Nssai + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.Nssai = &nssaiResp + return udmUe.Nssai, nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (p *Processor) GetSmfSelectDataProcedure(supi string, plmnID string, supportedFeatures string) ( + response *models.SmfSelectionSubscriptionData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var querySmfSelectDataParamOpts Nudr_DataRepository.QuerySmfSelectDataParamOpts + querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + var body models.SmfSelectionSubscriptionData + + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, body) + + smfSelectionSubscriptionDataResp, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi. + QuerySmfSelectData(ctx, supi, plmnID, &querySmfSelectDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.SetSmfSelectionSubsData(&smfSelectionSubscriptionDataResp) + return udmUe.SmfSelSubsData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (p *Processor) SubscribeToSharedDataProcedure(sdmSubscription *models.SdmSubscription) ( + header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + if err != nil { + return nil, nil, pd + } + + udmClientAPI := p.consumer.GetSDMClient("subscribeToSharedData") + + sdmSubscriptionResp, res, err := udmClientAPI.SubscriptionCreationForSharedDataApi.SubscribeToSharedData( + ctx, *sdmSubscription) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("SubscribeToSharedData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusCreated { + header = make(http.Header) + udm_context.GetSelf().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) + reourceUri := udm_context.GetSelf(). + GetSDMUri() + + "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId + header.Set("Location", reourceUri) + return header, &sdmSubscriptionResp, nil + } else if res.StatusCode == http.StatusNotFound { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + + return nil, nil, problemDetails + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotImplemented, + Cause: "UNSUPPORTED_RESOURCE_URI", + } + + return nil, nil, problemDetails + } +} + +func (p *Processor) SubscribeProcedure(sdmSubscription *models.SdmSubscription, supi string) ( + header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + sdmSubscriptionResp, res, err := clientAPI.SDMSubscriptionsCollectionApi.CreateSdmSubscriptions( + ctx, supi, *sdmSubscription) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("CreateSdmSubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusCreated { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) + if udmUe == nil { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.CreateSubscriptiontoNotifChange(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) + header.Set("Location", udmUe.GetLocationURI2(udm_context.LocationUriSdmSubscription, supi)) + return header, &sdmSubscriptionResp, nil + } else if res.StatusCode == http.StatusNotFound { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, nil, problemDetails + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotImplemented, + Cause: "UNSUPPORTED_RESOURCE_URI", + } + return nil, nil, problemDetails + } +} + +func (p *Processor) UnsubscribeForSharedDataProcedure(subscriptionID string) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + if err != nil { + return pd + } + + udmClientAPI := p.consumer.GetSDMClient("unsubscribeForSharedData") + + res, err := udmClientAPI.SubscriptionDeletionForSharedDataApi.UnsubscribeForSharedData( + ctx, subscriptionID) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails := &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("UnsubscribeForSharedData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusNoContent { + return nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return problemDetails + } +} + +func (p *Processor) UnsubscribeProcedure(supi string, subscriptionID string) *models.ProblemDetails { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + res, err := clientAPI.SDMSubscriptionDocumentApi.RemovesdmSubscriptions(ctx, supi, subscriptionID) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + logger.SdmLog.Warnln(err) + problemDetails := &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("RemovesdmSubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusNoContent { + return nil + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + return problemDetails + } +} + +func (p *Processor) ModifyProcedure( + sdmSubsModification *models.SdmSubsModification, + supi string, + subscriptionID string, +) ( + response *models.SdmSubscription, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + sdmSubscription := models.SdmSubscription{} + body := Nudr_DataRepository.UpdatesdmsubscriptionsParamOpts{ + SdmSubscription: optional.NewInterface(sdmSubscription), + } + + res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( + ctx, supi, subscriptionID, &body) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + return &sdmSubscription, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } +} + +// TS 29.503 5.2.2.7.3 +// Modification of a subscription to notifications of shared data change +func (p *Processor) ModifyForSharedDataProcedure(sdmSubsModification *models.SdmSubsModification, supi string, + subscriptionID string, +) (response *models.SdmSubscription, problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var sdmSubscription models.SdmSubscription + sdmSubs := models.SdmSubscription{} + body := Nudr_DataRepository.UpdatesdmsubscriptionsParamOpts{ + SdmSubscription: optional.NewInterface(sdmSubs), + } + + res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( + ctx, supi, subscriptionID, &body) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + return &sdmSubscription, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (p *Processor) GetTraceDataProcedure(supi string, plmnID string) ( + response *models.TraceData, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var body models.TraceData + var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts + + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + udm_context.GetSelf().CreateTraceDataforUe(supi, body) + + traceDataRes, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( + ctx, supi, plmnID, &queryTraceDataParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Warnln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Warnln(err) + } else { + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) + } + }() + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.TraceData = &traceDataRes + udmUe.TraceDataResponse.TraceData = &traceDataRes + + return udmUe.TraceDataResponse.TraceData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "USER_NOT_FOUND", + } + + return nil, problemDetails + } +} + +func (p *Processor) GetUeContextInSmfDataProcedure(supi string, supportedFeatures string) ( + response *models.UeContextInSmfData, problemDetails *models.ProblemDetails, +) { + var body models.UeContextInSmfData + var ueContextInSmfData models.UeContextInSmfData + var pgwInfoArray []models.PgwInfo + var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts + querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + pduSessionMap := make(map[string]models.PduSession) + udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, body) + + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + + pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( + ctx, supi, &querySmfRegListParamOpts) + if err != nil { + if res == nil { + logger.SdmLog.Infoln(err) + } else if err.Error() != res.Status { + logger.SdmLog.Infoln(err) + } else { + logger.SdmLog.Infoln(err) + problemDetails = &models.ProblemDetails{ + Status: int32(res.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return nil, problemDetails + } + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) + } + }() + + for _, element := range pdusess { + var pduSession models.PduSession + pduSession.Dnn = element.Dnn + pduSession.SmfInstanceId = element.SmfInstanceId + pduSession.PlmnId = element.PlmnId + pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession + } + ueContextInSmfData.PduSessions = pduSessionMap + + for _, element := range pdusess { + var pgwInfo models.PgwInfo + pgwInfo.Dnn = element.Dnn + pgwInfo.PgwFqdn = element.PgwFqdn + pgwInfo.PlmnId = element.PlmnId + pgwInfoArray = append(pgwInfoArray, pgwInfo) + } + ueContextInSmfData.PgwInfo = pgwInfoArray + + if res.StatusCode == http.StatusOK { + udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + if !ok { + udmUe = udm_context.GetSelf().NewUdmUe(supi) + } + udmUe.UeCtxtInSmfData = &ueContextInSmfData + return udmUe.UeCtxtInSmfData, nil + } else { + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "DATA_NOT_FOUND", + } + return nil, problemDetails + } +} + +func (p *Processor) containDataSetName(dataSetNames []string, target string) bool { + for _, dataSetName := range dataSetNames { + if dataSetName == target { + return true + } + } + return false +} diff --git a/internal/sbi/processor/subscription_creation.go b/internal/sbi/processor/subscription_creation.go deleted file mode 100644 index bc40cd9..0000000 --- a/internal/sbi/processor/subscription_creation.go +++ /dev/null @@ -1,69 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// Subscribe - subscribe to notifications -func (p *Processor) HandleSubscribe(c *gin.Context) { - var sdmSubscriptionReq models.SdmSubscription - - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sdmSubscriptionReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.SdmLog.Infof("Handle Subscribe") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - - // step 3: handle the message - header, response, problemDetails := p.consumer.SubscribeProcedure(&sdmSubscriptionReq, supi) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNotFound) - return - } -} diff --git a/internal/sbi/processor/subscription_creation_for_shared_data.go b/internal/sbi/processor/subscription_creation_for_shared_data.go deleted file mode 100644 index 45ac439..0000000 --- a/internal/sbi/processor/subscription_creation_for_shared_data.go +++ /dev/null @@ -1,74 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// SubscribeToSharedData - subscribe to notifications for shared data -func (p *Processor) HandleSubscribeToSharedData(c *gin.Context) { - var sharedDataSubsReq models.SdmSubscription - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sharedDataSubsReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.SdmLog.Infof("Handle SubscribeToSharedData") - - // step 2: retrieve request - - // step 3: handle the message - header, response, problemDetails := p.consumer.SubscribeToSharedDataProcedure(&sharedDataSubsReq) - - // var rsp *httpwrapper.Response - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - // step 5: response - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - return - } -} diff --git a/internal/sbi/processor/subscription_data_update.go b/internal/sbi/processor/subscription_data_update.go deleted file mode 100644 index 47a30da..0000000 --- a/internal/sbi/processor/subscription_data_update.go +++ /dev/null @@ -1,59 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -func (p *Processor) HandleUpdate(c *gin.Context) { - var ppDataReq models.PpData - - // 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.PpLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&ppDataReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.PpLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - gpsi := c.Params.ByName("gpsi") - - logger.PpLog.Infoln("Handle UpdateRequest") - - // step 3: handle the message - problemDetails := p.consumer.UpdateProcedure(ppDataReq, gpsi) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/subscription_deletion.go b/internal/sbi/processor/subscription_deletion.go deleted file mode 100644 index 71553e5..0000000 --- a/internal/sbi/processor/subscription_deletion.go +++ /dev/null @@ -1,30 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/udm/internal/logger" -) - -// Unsubscribe - unsubscribe from notifications -func (p *Processor) HandleUnsubscribe(c *gin.Context) { - logger.SdmLog.Infof("Handle Unsubscribe") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - subscriptionID := c.Params.ByName("subscriptionId") - - // step 3: handle the message - problemDetails := p.consumer.UnsubscribeProcedure(supi, subscriptionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/subscription_deletion_for_shared_data.go b/internal/sbi/processor/subscription_deletion_for_shared_data.go deleted file mode 100644 index 3a6d5ce..0000000 --- a/internal/sbi/processor/subscription_deletion_for_shared_data.go +++ /dev/null @@ -1,28 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/udm/internal/logger" -) - -// UnsubscribeForSharedData - unsubscribe from notifications for shared data -func (p *Processor) HandleUnsubscribeForSharedData(c *gin.Context) { - logger.SdmLog.Infof("Handle UnsubscribeForSharedData") - - // step 2: retrieve request - subscriptionID := c.Params.ByName("subscriptionId") - // step 3: handle the message - problemDetails := p.consumer.UnsubscribeForSharedDataProcedure(subscriptionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } -} diff --git a/internal/sbi/processor/subscription_modification.go b/internal/sbi/processor/subscription_modification.go deleted file mode 100644 index 29eaac7..0000000 --- a/internal/sbi/processor/subscription_modification.go +++ /dev/null @@ -1,129 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// Modify - modify the subscription -func (p *Processor) HandleModify(c *gin.Context) { - var sdmSubsModificationReq models.SdmSubsModification - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sdmSubsModificationReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.SdmLog.Infof("Handle Modify") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - subscriptionID := c.Params.ByName("subscriptionId") - - // step 3: handle the message - response, problemDetails := p.consumer.ModifyProcedure(&sdmSubsModificationReq, supi, subscriptionID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} - -// ModifyForSharedData - modify the subscription -func (p *Processor) HandleModifyForSharedData(c *gin.Context) { - var sharedDataSubscriptions models.SdmSubsModification - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sharedDataSubscriptions, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // step 1: log - logger.SdmLog.Infof("Handle ModifyForSharedData") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - subscriptionID := c.Params.ByName("subscriptionId") - - // step 3: handle the message - response, problemDetails := p.consumer.ModifyForSharedDataProcedure(&sharedDataSubscriptions, supi, subscriptionID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/trace_configuration_data_retrieval.go b/internal/sbi/processor/trace_configuration_data_retrieval.go deleted file mode 100644 index 92672a6..0000000 --- a/internal/sbi/processor/trace_configuration_data_retrieval.go +++ /dev/null @@ -1,40 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetTraceData - retrieve a UE's Trace Configuration Data -func (p *Processor) HandleGetTraceData(c *gin.Context) { - // step 1: log - logger.SdmLog.Infof("Handle GetTraceData") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - plmnID := c.Query("plmn-id") - - // step 3: handle the message - response, problemDetails := p.consumer.GetTraceDataProcedure(supi, plmnID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smf_data_retrieval.go deleted file mode 100644 index 1a6e50f..0000000 --- a/internal/sbi/processor/ue_context_in_smf_data_retrieval.go +++ /dev/null @@ -1,40 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" -) - -// GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data -func (p *Processor) HandleGetUeContextInSmfData(c *gin.Context) { - // step 1: log - logger.SdmLog.Infof("Handle GetUeContextInSmfData") - - // step 2: retrieve request - supi := c.Params.ByName("supi") - supportedFeatures := c.Query("supported-features") - - // step 3: handle the message - response, problemDetails := p.consumer.GetUeContextInSmfDataProcedure(supi, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } -} diff --git a/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go b/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go deleted file mode 100644 index a4ded32..0000000 --- a/internal/sbi/processor/ue_context_in_smsf_data_retrieval.go +++ /dev/null @@ -1,12 +0,0 @@ -package processor - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetUeContextInSmsfData - retrieve a UE's UE Context In SMSF Data -func (p *Processor) HandleGetUeContextInSmsfData(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/processor/ue_context_management.go b/internal/sbi/processor/ue_context_management.go new file mode 100644 index 0000000..29456d6 --- /dev/null +++ b/internal/sbi/processor/ue_context_management.go @@ -0,0 +1,513 @@ +package processor + +import ( + "net/http" + "strconv" + + "github.com/antihax/optional" + + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/Nudr_DataRepository" + "github.com/free5gc/openapi/models" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/internal/logger" + "github.com/free5gc/udm/internal/sbi/producer/callback" +) + +// ue_context_managemanet_service +func (p *Processor) GetAmf3gppAccessProcedure(ueID string, supportedFeatures string) ( + response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + var queryAmfContext3gppParamOpts Nudr_DataRepository.QueryAmfContext3gppParamOpts + queryAmfContext3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) + + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + amf3GppAccessRegistration, resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi. + QueryAmfContext3gpp(ctx, ueID, &queryAmfContext3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return &amf3GppAccessRegistration, nil +} + +func (p *Processor) GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts Nudr_DataRepository. + QueryAmfContextNon3gppParamOpts, ueID string) (response *models.AmfNon3GppAccessRegistration, + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + amfNon3GppAccessRegistration, resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi. + QueryAmfContextNon3gpp(ctx, ueID, &queryAmfContextNon3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return &amfNon3GppAccessRegistration, nil +} + +func (p *Processor) RegistrationAmf3gppAccessProcedure( + registerRequest models.Amf3GppAccessRegistration, + ueID string, +) ( + header http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + // TODO: EPS interworking with N26 is not supported yet in this stage + var oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration + var ue *udm_context.UdmUeContext + + if udm_context.GetSelf().UdmAmf3gppRegContextExists(ueID) { + ue, _ = udm_context.GetSelf().UdmUeFindBySupi(ueID) + oldAmf3GppAccessRegContext = ue.Amf3GppAccessRegistration + } + + udm_context.GetSelf().CreateAmf3gppRegContext(ueID, registerRequest) + + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var createAmfContext3gppParamOpts Nudr_DataRepository.CreateAmfContext3gppParamOpts + optInterface := optional.NewInterface(registerRequest) + createAmfContext3gppParamOpts.Amf3GppAccessRegistration = optInterface + resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.CreateAmfContext3gpp(ctx, + ueID, &createAmfContext3gppParamOpts) + if err != nil { + logger.UecmLog.Errorln("CreateAmfContext3gpp error : ", err) + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF + // corresponding to the same (e.g. 3GPP) access, if one exists + if oldAmf3GppAccessRegContext != nil { + if !ue.SameAsStoredGUAMI3gpp(*oldAmf3GppAccessRegContext.Guami) { + // Based on TS 23.502 4.2.2.2.2, If the serving NF removal reason indicated by the UDM is Initial Registration, + // the old AMF invokes the Nsmf_PDUSession_ReleaseSMContext (SM Context ID). Thus we give different + // dereg cause based on registration parameter from serving AMF + deregReason := models.DeregistrationReason_UE_REGISTRATION_AREA_CHANGE + if registerRequest.InitialRegistrationInd { + deregReason = models.DeregistrationReason_UE_INITIAL_REGISTRATION + } + deregistData := models.DeregistrationData{ + DeregReason: deregReason, + AccessType: models.AccessType__3_GPP_ACCESS, + } + + go func() { + logger.UecmLog.Infof("Send DeregNotify to old AMF GUAMI=%v", oldAmf3GppAccessRegContext.Guami) + pd := callback.SendOnDeregistrationNotification(ueID, + oldAmf3GppAccessRegContext.DeregCallbackUri, + deregistData) // Deregistration Notify Triggered + if pd != nil { + logger.UecmLog.Errorf("RegistrationAmf3gppAccess: send DeregNotify fail %v", pd) + } + }() + } + return nil, ®isterRequest, nil + } else { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration)) + return header, ®isterRequest, nil + } +} + +func (p *Processor) RegisterAmfNon3gppAccessProcedure( + registerRequest models.AmfNon3GppAccessRegistration, + ueID string, +) ( + header http.Header, response *models.AmfNon3GppAccessRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + var oldAmfNon3GppAccessRegContext *models.AmfNon3GppAccessRegistration + if udm_context.GetSelf().UdmAmfNon3gppRegContextExists(ueID) { + ue, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + oldAmfNon3GppAccessRegContext = ue.AmfNon3GppAccessRegistration + } + + udm_context.GetSelf().CreateAmfNon3gppRegContext(ueID, registerRequest) + + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + var createAmfContextNon3gppParamOpts Nudr_DataRepository.CreateAmfContextNon3gppParamOpts + optInterface := optional.NewInterface(registerRequest) + createAmfContextNon3gppParamOpts.AmfNon3GppAccessRegistration = optInterface + + resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.CreateAmfContextNon3gpp( + ctx, ueID, &createAmfContextNon3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF + // corresponding to the same (e.g. 3GPP) access, if one exists + if oldAmfNon3GppAccessRegContext != nil { + deregistData := models.DeregistrationData{ + DeregReason: models.DeregistrationReason_UE_INITIAL_REGISTRATION, + AccessType: models.AccessType_NON_3_GPP_ACCESS, + } + callback.SendOnDeregistrationNotification(ueID, oldAmfNon3GppAccessRegContext.DeregCallbackUri, + deregistData) // Deregistration Notify Triggered + + return nil, nil, nil + } else { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmfNon3GppAccessRegistration)) + return header, ®isterRequest, nil + } +} + +func (p *Processor) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessRegistrationModification, ueID string) ( + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + var patchItemReqArray []models.PatchItem + currentContext := udm_context.GetSelf().GetAmf3gppRegContext(ueID) + if currentContext == nil { + logger.UecmLog.Errorln("[UpdateAmf3gppAccess] Empty Amf3gppRegContext") + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "CONTEXT_NOT_FOUND", + } + return problemDetails + } + + if request.Guami != nil { + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + if udmUe.SameAsStoredGUAMI3gpp(*request.Guami) { // deregistration + logger.UecmLog.Infoln("UpdateAmf3gppAccess - deregistration") + request.PurgeFlag = true + } else { + logger.UecmLog.Errorln("INVALID_GUAMI") + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "INVALID_GUAMI", + } + return problemDetails + } + + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "guami" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = *request.Guami + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.PurgeFlag { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "purgeFlag" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.PurgeFlag + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.Pei != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "pei" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.Pei + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.ImsVoPs != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "imsVoPs" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.ImsVoPs + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.BackupAmfInfo != nil { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "backupAmfInfo" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.BackupAmfInfo + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.AmfContext3gpp(ctx, ueID, + patchItemReqArray) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + + return problemDetails + } + + if request.PurgeFlag { + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + udmUe.Amf3GppAccessRegistration = nil + } + + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("AmfContext3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} + +func (p *Processor) UpdateAmfNon3gppAccessProcedure( + request models.AmfNon3GppAccessRegistrationModification, + ueID string, +) ( + problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + var patchItemReqArray []models.PatchItem + currentContext := udm_context.GetSelf().GetAmfNon3gppRegContext(ueID) + if currentContext == nil { + logger.UecmLog.Errorln("[UpdateAmfNon3gppAccess] Empty AmfNon3gppRegContext") + problemDetails = &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "CONTEXT_NOT_FOUND", + } + return problemDetails + } + + if request.Guami != nil { + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + if udmUe.SameAsStoredGUAMINon3gpp(*request.Guami) { // deregistration + logger.UecmLog.Infoln("UpdateAmfNon3gppAccess - deregistration") + request.PurgeFlag = true + } else { + logger.UecmLog.Errorln("INVALID_GUAMI") + problemDetails = &models.ProblemDetails{ + Status: http.StatusForbidden, + Cause: "INVALID_GUAMI", + } + } + + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "guami" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = *request.Guami + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.PurgeFlag { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "purgeFlag" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.PurgeFlag + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.Pei != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "pei" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.Pei + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.ImsVoPs != "" { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "imsVoPs" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.ImsVoPs + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + if request.BackupAmfInfo != nil { + var patchItemTmp models.PatchItem + patchItemTmp.Path = "/" + "backupAmfInfo" + patchItemTmp.Op = models.PatchOperation_REPLACE + patchItemTmp.Value = request.BackupAmfInfo + patchItemReqArray = append(patchItemReqArray, patchItemTmp) + } + + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.AmfContextNon3gpp(ctx, + ueID, patchItemReqArray) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("AmfContextNon3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + return problemDetails +} + +func (p *Processor) DeregistrationSmfRegistrationsProcedure( + ueID string, + pduSessionID string, +) (problemDetails *models.ProblemDetails) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return pd + } + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.SMFRegistrationDocumentApi.DeleteSmfContext(ctx, ueID, pduSessionID) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("DeleteSmfContext response body cannot close: %+v", rspCloseErr) + } + }() + + return nil +} + +func (p *Processor) RegistrationSmfRegistrationsProcedure( + request *models.SmfRegistration, + ueID string, + pduSessionID string, +) ( + header http.Header, response *models.SmfRegistration, problemDetails *models.ProblemDetails, +) { + ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + if err != nil { + return nil, nil, pd + } + contextExisted := false + udm_context.GetSelf().CreateSmfRegContext(ueID, pduSessionID) + if !udm_context.GetSelf().UdmSmfRegContextNotExists(ueID) { + contextExisted = true + } + + pduID64, err := strconv.ParseInt(pduSessionID, 10, 32) + if err != nil { + logger.UecmLog.Errorln(err.Error()) + } + pduID32 := int32(pduID64) + + var createSmfContextNon3gppParamOpts Nudr_DataRepository.CreateSmfContextNon3gppParamOpts + optInterface := optional.NewInterface(*request) + createSmfContextNon3gppParamOpts.SmfRegistration = optInterface + + clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + if err != nil { + return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + } + + resp, err := clientAPI.SMFRegistrationDocumentApi.CreateSmfContextNon3gpp(ctx, ueID, + pduID32, &createSmfContextNon3gppParamOpts) + if err != nil { + problemDetails = &models.ProblemDetails{ + Status: int32(resp.StatusCode), + Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, + Detail: err.Error(), + } + return nil, nil, problemDetails + } + defer func() { + if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { + logger.UecmLog.Errorf("CreateSmfContextNon3gpp response body cannot close: %+v", rspCloseErr) + } + }() + + if contextExisted { + return nil, nil, nil + } else { + header = make(http.Header) + udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriSmfRegistration)) + return header, request, nil + } +} diff --git a/internal/sbi/processor/ueau_route.go b/internal/sbi/processor/ueau_route.go deleted file mode 100644 index a35d08a..0000000 --- a/internal/sbi/processor/ueau_route.go +++ /dev/null @@ -1,18 +0,0 @@ -package processor - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" -) - -func (p *Processor) GenAuthDataHandlerFunc(c *gin.Context) { - c.Params = append(c.Params, gin.Param{Key: "supiOrSuci", Value: c.Param("supi")}) - if strings.ToUpper("Post") == c.Request.Method { - p.HandleGenerateAuthData(c) - return - } - - c.String(http.StatusNotFound, "404 page not found") -} diff --git a/internal/sbi/server.go b/internal/sbi/server.go index ba5755e..a3f60e6 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -181,7 +181,7 @@ func newRouter(s *Server) *gin.Engine { AddService(udmUEAUGroup, udmUEAURoutes) genAuthDataPath := "/:supi/security-information/generate-auth-data" - udmUEAUGroup.Any(genAuthDataPath, s.Processor().GenAuthDataHandlerFunc) + udmUEAUGroup.Any(genAuthDataPath, s.GenAuthDataHandlerFunc) // UECM udmUECMRoutes := s.getUEContextManagementRoutes() @@ -202,13 +202,13 @@ func newRouter(s *Server) *gin.Engine { AddService(udmSDMGroup, udmSDMRoutes) oneLayerPath := "/:supi" - udmSDMGroup.Any(oneLayerPath, s.Processor().OneLayerPathHandlerFunc) + udmSDMGroup.Any(oneLayerPath, s.OneLayerPathHandlerFunc) twoLayerPath := "/:supi/:subscriptionId" - udmSDMGroup.Any(twoLayerPath, s.Processor().TwoLayerPathHandlerFunc) + udmSDMGroup.Any(twoLayerPath, s.TwoLayerPathHandlerFunc) threeLayerPath := "/:supi/:subscriptionId/:thirdLayer" - udmSDMGroup.Any(threeLayerPath, s.Processor().ThreeLayerPathHandlerFunc) + udmSDMGroup.Any(threeLayerPath, s.ThreeLayerPathHandlerFunc) // PP udmPPRoutes := s.getParameterProvisionRoutes() From 2decf1b48a0b8625b3adf6f564e4d2fbfc039d5d Mon Sep 17 00:00:00 2001 From: ubuntu Date: Thu, 23 May 2024 12:44:45 +0000 Subject: [PATCH 10/23] fix: name error --- internal/sbi/consumer/nrf_service.go | 6 +++--- pkg/service/init.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 79f0117..8a9279e 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -77,9 +77,9 @@ func (s *nnrfService) SendSearchNFInstances( *models.SearchResult, error, ) { // Set client and set url - chfContext := s.consumer.Context() + udmContext := s.consumer.Context() - client := s.getNFDiscClient(chfContext.NrfUri) + client := s.getNFDiscClient(udmContext.NrfUri) ctx, _, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) if err != nil { @@ -150,7 +150,7 @@ func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( for { nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), udmContext.NfId, nfProfile) if err != nil || res == nil { - logger.ConsumerLog.Errorf("CHF register to NRF Error[%v]", err) + logger.ConsumerLog.Errorf("UDM register to NRF Error[%v]", err) time.Sleep(2 * time.Second) continue } diff --git a/pkg/service/init.go b/pkg/service/init.go index 8283b81..8983ca8 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -221,7 +221,7 @@ func (a *UdmApp) Terminate() { } else { logger.MainLog.Infof("Deregister from NRF successfully") } - logger.MainLog.Infof("CHF SBI Server terminated") + logger.MainLog.Infof("UDM SBI Server terminated") } func (a *UdmApp) listenShutdownEvent() { @@ -245,7 +245,7 @@ func (a *UdmApp) CallServerStop() { func (a *UdmApp) WaitRoutineStopped() { a.wg.Wait() - logger.MainLog.Infof("CHF App is terminated") + logger.MainLog.Infof("UDM App is terminated") } func (a *UdmApp) Config() *factory.Config { From f066b7c60bf0f9c1b930d9cf83b42d31d407588b Mon Sep 17 00:00:00 2001 From: ubuntu Date: Sun, 26 May 2024 16:00:59 +0000 Subject: [PATCH 11/23] fix: fix run error, remove unuse line --- cmd/main.go | 5 +-- internal/context/context.go | 1 + internal/sbi/server.go | 16 -------- pkg/service/init.go | 79 +------------------------------------ 4 files changed, 3 insertions(+), 98 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 7873784..e0a4aac 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -17,8 +17,6 @@ import ( "github.com/free5gc/util/version" ) -var UDM *service.UdmApp - func main() { defer func() { if p := recover(); p != nil { @@ -74,10 +72,9 @@ func action(cliCtx *cli.Context) error { if err != nil { return err } - UDM = udm udm.Start() - UDM.WaitRoutineStopped() + udm.WaitRoutineStopped() return nil } diff --git a/internal/context/context.go b/internal/context/context.go index 3450dc3..922efd5 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -34,6 +34,7 @@ const ( func Init() { GetSelf().NfService = make(map[models.ServiceName]models.NfService) GetSelf().EeSubscriptionIDGenerator = idgenerator.NewGenerator(1, math.MaxInt32) + InitUdmContext(GetSelf()) } type NFContext interface { diff --git a/internal/sbi/server.go b/internal/sbi/server.go index a3f60e6..2a7c342 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -54,14 +54,6 @@ func NewServer(udm ServerUdm, tlsKeyLogPath string) (*Server, error) { } s.httpServer.ErrorLog = log.New(logger.SBILog.WriterLevel(logrus.ErrorLevel), "HTTP2: ", 0) - /*server, err := bindRouter(s.Config(), s.router, tlsKeyLogPath) - s.httpServer = server - - if err != nil { - logger.SBILog.Errorf("bind Router Error: %+v", err) - panic("Server initialization failed") - }*/ - return s, err } @@ -76,14 +68,6 @@ func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { wg.Add(1) go s.startServer(wg) - /*go func() { - defer wg.Done() - - err := s.serve() - if err != http.ErrServerClosed { - logger.SBILog.Panicf("HTTP server setup failed: %+v", err) - } - }()*/ return nil } diff --git a/pkg/service/init.go b/pkg/service/init.go index 8983ca8..866156b 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -52,6 +52,7 @@ func NewApp(ctx context.Context, cfg *factory.Config, tlsKeyLogPath string) (*Ud udm.SetLogEnable(cfg.GetLogEnable()) udm.SetLogLevel(cfg.GetLogLevel()) udm.SetReportCaller(cfg.GetLogReportCaller()) + udm_context.Init() processor, err_p := processor.NewProcessor(udm) if err_p != nil { @@ -127,84 +128,6 @@ func (a *UdmApp) Start() { if err := a.sbiServer.Run(context.Background(), &a.wg); err != nil { logger.MainLog.Fatalf("Run SBI server failed: %+v", err) } - /*config := factory.UdmConfig - configuration := config.Configuration - sbi := configuration.Sbi - - logger.InitLog.Infof("UDM Config Info: Version[%s] Description[%s]", config.Info.Version, config.Info.Description) - - logger.InitLog.Infoln("Server started") - - router := logger_util.NewGinWithLogrus(logger.GinLog) - - eventexposure.AddService(router) - httpcallback.AddService(router) - parameterprovision.AddService(router) - subscriberdatamanagement.AddService(router) - ueauthentication.AddService(router) - uecontextmanagement.AddService(router) - - pemPath := factory.UdmDefaultCertPemPath - keyPath := factory.UdmDefaultPrivateKeyPath - if sbi.Tls != nil { - pemPath = sbi.Tls.Pem - keyPath = sbi.Tls.Key - } - - self := a.udmCtx - udm_context.InitUdmContext(self) - - addr := fmt.Sprintf("%s:%d", self.BindingIPv4, self.SBIPort) - - proflie, err := consumer.BuildNFInstance(self) - if err != nil { - logger.InitLog.Errorln(err.Error()) - } else { - var newNrfUri string - var err1 error - newNrfUri, self.NfId, err1 = consumer.SendRegisterNFInstance(self.NrfUri, self.NfId, proflie) - if err1 != nil { - logger.InitLog.Errorln(err1.Error()) - } else { - self.NrfUri = newNrfUri - } - } - - 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) - }() - - 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.UdmConfig.Configuration.Sbi.Scheme - if serverScheme == "http" { - err = server.ListenAndServe() - } else if serverScheme == "https" { - err = server.ListenAndServeTLS(pemPath, keyPath) - } - - if err != nil { - logger.InitLog.Fatalf("HTTP server setup failed: %+v", err) - }*/ } func (a *UdmApp) Terminate() { From e3f5deaee959b663bce7086979e914e76b5b2059 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Mon, 27 May 2024 06:35:50 +0000 Subject: [PATCH 12/23] fix: consumer init error, url.Value init error --- internal/sbi/api_subscriberdatamanagement.go | 10 +++++----- internal/sbi/processor/processor.go | 7 +++++++ internal/sbi/producer/event_exposure.go | 20 -------------------- pkg/service/init.go | 12 ++++++------ 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/internal/sbi/api_subscriberdatamanagement.go b/internal/sbi/api_subscriberdatamanagement.go index 6b4c8da..26392ff 100644 --- a/internal/sbi/api_subscriberdatamanagement.go +++ b/internal/sbi/api_subscriberdatamanagement.go @@ -26,7 +26,7 @@ func (s *Server) getSubscriberDataManagementRoutes() []Route { // GetAmData - retrieve a UE's Access and Mobility Subscription Data func (s *Server) HandleGetAmData(c *gin.Context) { - var query url.Values + query := url.Values{} query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("plmn-id")) @@ -98,7 +98,7 @@ func (s *Server) HandlePutUpuAck(c *gin.Context) { // GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data func (s *Server) HandleGetSmfSelectData(c *gin.Context) { - var query url.Values + query := url.Values{} query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("supported-features")) @@ -148,7 +148,7 @@ func (s *Server) HandleGetSmsData(c *gin.Context) { // GetSupi - retrieve multiple data sets func (s *Server) HandleGetSupi(c *gin.Context) { - var query url.Values + query := url.Values{} query.Set("plmn-id", c.Query("plmn-id")) query.Set("dataset-names", c.Query("dataset-names")) query.Set("supported-features", c.Query("supported-features")) @@ -563,7 +563,7 @@ func (s *Server) HandleGetUeContextInSmsfData(c *gin.Context) { // GetNssai - retrieve a UE's subscribed NSSAI func (s *Server) HandleGetNssai(c *gin.Context) { - var query url.Values + query := url.Values{} query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("supported-features")) @@ -603,7 +603,7 @@ func (s *Server) HandleGetNssai(c *gin.Context) { // GetSmData - retrieve a UE's Session Management Subscription Data func (s *Server) HandleGetSmData(c *gin.Context) { - var query url.Values + query := url.Values{} query.Set("plmn-id", c.Query("plmn-id")) query.Set("dnn", c.Query("dnn")) query.Set("single-nssai", c.Query("single-nssai")) diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go index 2e450ed..0e9cb79 100644 --- a/internal/sbi/processor/processor.go +++ b/internal/sbi/processor/processor.go @@ -7,6 +7,8 @@ import ( type ProcessorUdm interface { app.App + + Consumer() *consumer.Consumer } type Processor struct { @@ -23,6 +25,11 @@ type HandlerResponse struct { func NewProcessor(udm ProcessorUdm) (*Processor, error) { p := &Processor{ ProcessorUdm: udm, + consumer: udm.Consumer(), } return p, nil } + +func (p *Processor) Consumer() *consumer.Consumer { + return p.consumer +} diff --git a/internal/sbi/producer/event_exposure.go b/internal/sbi/producer/event_exposure.go index 4463d05..93a06b0 100644 --- a/internal/sbi/producer/event_exposure.go +++ b/internal/sbi/producer/event_exposure.go @@ -11,26 +11,6 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func HandleCreateEeSubscription(request *httpwrapper.Request) *httpwrapper.Response { - logger.EeLog.Infoln("Handle Create EE Subscription") - - eesubscription := request.Body.(models.EeSubscription) - ueIdentity := request.Params["ueIdentity"] - - createdEESubscription, problemDetails := CreateEeSubscriptionProcedure(ueIdentity, eesubscription) - if createdEESubscription != nil { - return httpwrapper.NewResponse(http.StatusCreated, nil, createdEESubscription) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - return httpwrapper.NewResponse(http.StatusInternalServerError, nil, problemDetails) - } -} - // TODO: complete this procedure based on TS 29503 5.5 func CreateEeSubscriptionProcedure(ueIdentity string, eesubscription models.EeSubscription, diff --git a/pkg/service/init.go b/pkg/service/init.go index 866156b..f2cd7f4 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -54,18 +54,18 @@ func NewApp(ctx context.Context, cfg *factory.Config, tlsKeyLogPath string) (*Ud udm.SetReportCaller(cfg.GetLogReportCaller()) udm_context.Init() - processor, err_p := processor.NewProcessor(udm) - if err_p != nil { - return udm, err_p - } - udm.processor = processor - consumer, err := consumer.NewConsumer(udm) if err != nil { return udm, err } udm.consumer = consumer + processor, err_p := processor.NewProcessor(udm) + if err_p != nil { + return udm, err_p + } + udm.processor = processor + udm.ctx, udm.cancel = context.WithCancel(ctx) udm.udmCtx = udm_context.GetSelf() From bc28dffea300a06dc2b902dc7e15c5556e6a85d0 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 29 May 2024 07:12:25 +0000 Subject: [PATCH 13/23] fix: add mock app interface & fix unit test --- go.mod | 1 + go.sum | 2 + internal/sbi/consumer/nf_management_test.go | 22 +++- internal/sbi/consumer/nrf_service.go | 2 +- pkg/app/mock.go | 129 ++++++++++++++++++++ 5 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 pkg/app/mock.go diff --git a/go.mod b/go.mod index dddb7d5..6897ec0 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.8.4 github.com/urfave/cli v1.22.5 + go.uber.org/mock v0.4.0 golang.org/x/crypto v0.21.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 2184939..8b07968 100644 --- a/go.sum +++ b/go.sum @@ -103,6 +103,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= diff --git a/internal/sbi/consumer/nf_management_test.go b/internal/sbi/consumer/nf_management_test.go index 8667cf7..b185799 100644 --- a/internal/sbi/consumer/nf_management_test.go +++ b/internal/sbi/consumer/nf_management_test.go @@ -1,12 +1,16 @@ package consumer import ( + "context" "testing" "github.com/h2non/gock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "github.com/free5gc/openapi" + udm_context "github.com/free5gc/udm/internal/context" + "github.com/free5gc/udm/pkg/app" ) func TestSendRegisterNFInstance(t *testing.T) { @@ -14,11 +18,25 @@ func TestSendRegisterNFInstance(t *testing.T) { gock.InterceptClient(openapi.GetHttpClient()) defer gock.RestoreClient(openapi.GetHttpClient()) + gock.New("http://127.0.0.10:8000"). Put("/nnrf-nfm/v1/nf-instances/1"). Reply(200). JSON(map[string]string{}) - //_, _, err := SendRegisterNFInstance("http://127.0.0.10:8000", "1", models.NfProfile{}) - require.NoError(t, nil) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockApp := app.NewMockApp(ctrl) + consumer, err := NewConsumer(mockApp) + require.NoError(t, err) + + mockApp.EXPECT().Context().Times(1).Return( + &udm_context.UDMContext{ + NrfUri: "http://127.0.0.10:8000", + NfId: "1", + }, + ) + + _, _, err = consumer.RegisterNFInstance(context.TODO()) + require.NoError(t, err) } diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 8a9279e..57acc7e 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -148,7 +148,7 @@ func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( var nf models.NfProfile var res *http.Response for { - nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), udmContext.NfId, nfProfile) + nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, udmContext.NfId, nfProfile) if err != nil || res == nil { logger.ConsumerLog.Errorf("UDM register to NRF Error[%v]", err) time.Sleep(2 * time.Second) diff --git a/pkg/app/mock.go b/pkg/app/mock.go new file mode 100644 index 0000000..2431e8f --- /dev/null +++ b/pkg/app/mock.go @@ -0,0 +1,129 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: app.go +// +// Generated by this command: +// +// mockgen -source=app.go -destination=mock.go -package=app +// + +// Package app is a generated GoMock package. +package app + +import ( + reflect "reflect" + + context "github.com/free5gc/udm/internal/context" + factory "github.com/free5gc/udm/pkg/factory" + gomock "go.uber.org/mock/gomock" +) + +// MockApp is a mock of App interface. +type MockApp struct { + ctrl *gomock.Controller + recorder *MockAppMockRecorder +} + +// MockAppMockRecorder is the mock recorder for MockApp. +type MockAppMockRecorder struct { + mock *MockApp +} + +// NewMockApp creates a new mock instance. +func NewMockApp(ctrl *gomock.Controller) *MockApp { + mock := &MockApp{ctrl: ctrl} + mock.recorder = &MockAppMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockApp) EXPECT() *MockAppMockRecorder { + return m.recorder +} + +// Config mocks base method. +func (m *MockApp) Config() *factory.Config { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Config") + ret0, _ := ret[0].(*factory.Config) + return ret0 +} + +// Config indicates an expected call of Config. +func (mr *MockAppMockRecorder) Config() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Config", reflect.TypeOf((*MockApp)(nil).Config)) +} + +// Context mocks base method. +func (m *MockApp) Context() *context.UDMContext { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(*context.UDMContext) + return ret0 +} + +// Context indicates an expected call of Context. +func (mr *MockAppMockRecorder) Context() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockApp)(nil).Context)) +} + +// SetLogEnable mocks base method. +func (m *MockApp) SetLogEnable(enable bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetLogEnable", enable) +} + +// SetLogEnable indicates an expected call of SetLogEnable. +func (mr *MockAppMockRecorder) SetLogEnable(enable any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogEnable", reflect.TypeOf((*MockApp)(nil).SetLogEnable), enable) +} + +// SetLogLevel mocks base method. +func (m *MockApp) SetLogLevel(level string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetLogLevel", level) +} + +// SetLogLevel indicates an expected call of SetLogLevel. +func (mr *MockAppMockRecorder) SetLogLevel(level any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogLevel", reflect.TypeOf((*MockApp)(nil).SetLogLevel), level) +} + +// SetReportCaller mocks base method. +func (m *MockApp) SetReportCaller(reportCaller bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetReportCaller", reportCaller) +} + +// SetReportCaller indicates an expected call of SetReportCaller. +func (mr *MockAppMockRecorder) SetReportCaller(reportCaller any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReportCaller", reflect.TypeOf((*MockApp)(nil).SetReportCaller), reportCaller) +} + +// Start mocks base method. +func (m *MockApp) Start() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Start") +} + +// Start indicates an expected call of Start. +func (mr *MockAppMockRecorder) Start() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockApp)(nil).Start)) +} + +// Terminate mocks base method. +func (m *MockApp) Terminate() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Terminate") +} + +// Terminate indicates an expected call of Terminate. +func (mr *MockAppMockRecorder) Terminate() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Terminate", reflect.TypeOf((*MockApp)(nil).Terminate)) +} From 8f668bb5b9c4e6083823f335b1cc5c038bd98eee Mon Sep 17 00:00:00 2001 From: ubuntu Date: Wed, 29 May 2024 07:24:27 +0000 Subject: [PATCH 14/23] delete: remove legacy code --- .../api_create_ee_subscription.go | 75 - .../api_delete_ee_subscription.go | 28 - .../api_update_ee_subscription.go | 76 - internal/sbi/eventexposure/routers.go | 106 -- .../data_change_notification_to_nf.go | 61 - internal/sbi/httpcallback/router.go | 81 - .../api_subscription_data_update.go | 73 - .../api_subscription_data_update_test.go | 76 - internal/sbi/parameterprovision/routers.go | 91 - .../sbi/processor/ue_context_management.go | 5 +- internal/sbi/producer/callback.go | 29 - internal/sbi/producer/callback/callback.go | 97 -- internal/sbi/producer/event_exposure.go | 234 --- internal/sbi/producer/generate_auth_data.go | 591 ------- internal/sbi/producer/parameter_provision.go | 56 - .../producer/subscriber_data_management.go | 1543 ----------------- .../sbi/producer/ue_context_management.go | 742 -------- ...nd_mobility_subscription_data_retrieval.go | 45 - .../api_gpsi_to_supi_translation.go | 44 - ..._acknowledgement_of_steering_of_roaming.go | 21 - ...acknowledgement_of_ue_parameters_update.go | 21 - .../api_retrieval_of_multiple_data_sets.go | 45 - .../api_retrieval_of_shared_data.go | 45 - ..._management_subscription_data_retrieval.go | 47 - ...e_selection_subscription_data_retrieval.go | 45 - ...f_selection_subscription_data_retrieval.go | 44 - ..._management_subscription_data_retrieval.go | 21 - .../api_sms_subscription_data_retrieval.go | 21 - .../api_subscription_creation.go | 76 - ...i_subscription_creation_for_shared_data.go | 73 - .../api_subscription_deletion.go | 47 - ...i_subscription_deletion_for_shared_data.go | 42 - .../api_subscription_modification.go | 123 -- .../api_trace_configuration_data_retrieval.go | 44 - .../api_ue_context_in_smf_data_retrieval.go | 44 - .../api_ue_context_in_smsf_data_retrieval.go | 21 - .../sbi/subscriberdatamanagement/routers.go | 458 ----- .../sbi/ueauthentication/api_confirm_auth.go | 72 - .../api_generate_auth_data.go | 73 - internal/sbi/ueauthentication/routers.go | 123 -- ..._gpp_access_registration_info_retrieval.go | 44 - ..._gpp_access_registration_info_retrieval.go | 44 - .../api_amf_registration_for3_gpp_access.go | 76 - ...pi_amf_registration_for_non3_gpp_access.go | 76 - ...in_the_amf_registration_for3_gpp_access.go | 73 - ...he_amf_registration_for_non3_gpp_access.go | 72 - .../api_smf_deregistration.go | 44 - .../api_smf_registration.go | 76 - ..._gpp_access_registration_info_retrieval.go | 21 - ...api_smsf_deregistration_for3_gpp_access.go | 21 - ...smsf_deregistration_for_non3_gpp_access.go | 21 - ..._gpp_access_registration_info_retrieval.go | 21 - .../api_smsf_registration_for3_gpp_access.go | 21 - ...i_smsf_registration_for_non3_gpp_access.go | 21 - internal/sbi/uecontextmanagement/routers.go | 183 -- 55 files changed, 2 insertions(+), 6371 deletions(-) delete mode 100644 internal/sbi/eventexposure/api_create_ee_subscription.go delete mode 100644 internal/sbi/eventexposure/api_delete_ee_subscription.go delete mode 100644 internal/sbi/eventexposure/api_update_ee_subscription.go delete mode 100644 internal/sbi/eventexposure/routers.go delete mode 100644 internal/sbi/httpcallback/data_change_notification_to_nf.go delete mode 100644 internal/sbi/httpcallback/router.go delete mode 100644 internal/sbi/parameterprovision/api_subscription_data_update.go delete mode 100644 internal/sbi/parameterprovision/api_subscription_data_update_test.go delete mode 100644 internal/sbi/parameterprovision/routers.go delete mode 100644 internal/sbi/producer/callback.go delete mode 100644 internal/sbi/producer/callback/callback.go delete mode 100644 internal/sbi/producer/event_exposure.go delete mode 100644 internal/sbi/producer/generate_auth_data.go delete mode 100644 internal/sbi/producer/parameter_provision.go delete mode 100644 internal/sbi/producer/subscriber_data_management.go delete mode 100644 internal/sbi/producer/ue_context_management.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_access_and_mobility_subscription_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_gpsi_to_supi_translation.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_providing_acknowledgement_of_steering_of_roaming.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_providing_acknowledgement_of_ue_parameters_update.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_retrieval_of_multiple_data_sets.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_retrieval_of_shared_data.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_session_management_subscription_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_slice_selection_subscription_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_smf_selection_subscription_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_sms_management_subscription_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_sms_subscription_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_subscription_creation.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_subscription_creation_for_shared_data.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_subscription_deletion.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_subscription_deletion_for_shared_data.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_subscription_modification.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_trace_configuration_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_ue_context_in_smf_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/api_ue_context_in_smsf_data_retrieval.go delete mode 100644 internal/sbi/subscriberdatamanagement/routers.go delete mode 100644 internal/sbi/ueauthentication/api_confirm_auth.go delete mode 100644 internal/sbi/ueauthentication/api_generate_auth_data.go delete mode 100644 internal/sbi/ueauthentication/routers.go delete mode 100644 internal/sbi/uecontextmanagement/api_amf3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/uecontextmanagement/api_amf_non3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/uecontextmanagement/api_amf_registration_for3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/api_amf_registration_for_non3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/api_parameter_update_in_the_amf_registration_for3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/api_parameter_update_in_the_amf_registration_for_non3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/api_smf_deregistration.go delete mode 100644 internal/sbi/uecontextmanagement/api_smf_registration.go delete mode 100644 internal/sbi/uecontextmanagement/api_smsf3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/uecontextmanagement/api_smsf_deregistration_for3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/api_smsf_deregistration_for_non3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/api_smsf_non3_gpp_access_registration_info_retrieval.go delete mode 100644 internal/sbi/uecontextmanagement/api_smsf_registration_for3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/api_smsf_registration_for_non3_gpp_access.go delete mode 100644 internal/sbi/uecontextmanagement/routers.go diff --git a/internal/sbi/eventexposure/api_create_ee_subscription.go b/internal/sbi/eventexposure/api_create_ee_subscription.go deleted file mode 100644 index 2e11a38..0000000 --- a/internal/sbi/eventexposure/api_create_ee_subscription.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Nudm_EE - * - * Nudm Event Exposure Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package eventexposure - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" -) - -// HTTPCreateEeSubscription - Subscribe -func HTTPCreateEeSubscription(c *gin.Context) { - var eesubscription models.EeSubscription - - requestBody, err := c.GetRawData() - if err != nil { - logger.EeLog.Errorf("Get Request Body error: %+v", err) - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // err = openapi.Deserialize(&eeSubscription, requestBody, "application/json") - err = openapi.Deserialize(nil, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.EeLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - // Start - logger.EeLog.Infoln("Handle Create EE Subscription") - - ueIdentity := c.Params.ByName("ueIdentity") - - createdEESubscription, problemDetails := producer.CreateEeSubscriptionProcedure(ueIdentity, eesubscription) - - if createdEESubscription != nil { - c.JSON(http.StatusCreated, createdEESubscription) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetails) - return - } -} diff --git a/internal/sbi/eventexposure/api_delete_ee_subscription.go b/internal/sbi/eventexposure/api_delete_ee_subscription.go deleted file mode 100644 index 8b7343e..0000000 --- a/internal/sbi/eventexposure/api_delete_ee_subscription.go +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Nudm_EE - * - * Nudm Event Exposure Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package eventexposure - -import ( - "github.com/gin-gonic/gin" - - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// DeleteEeSubscription - Unsubscribe -func HTTPDeleteEeSubscription(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["ueIdentity"] = c.Params.ByName("ueIdentity") - req.Params["subscriptionID"] = c.Params.ByName("subscriptionId") - - rsp := producer.HandleDeleteEeSubscription(req) - // only return 204 no content - c.Status(rsp.Status) -} diff --git a/internal/sbi/eventexposure/api_update_ee_subscription.go b/internal/sbi/eventexposure/api_update_ee_subscription.go deleted file mode 100644 index f310ce2..0000000 --- a/internal/sbi/eventexposure/api_update_ee_subscription.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Nudm_EE - * - * Nudm Event Exposure Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package eventexposure - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// UpdateEeSubscription - Patch -func HTTPUpdateEeSubscription(c *gin.Context) { - var patchList []models.PatchItem - - requestBody, err := c.GetRawData() - if err != nil { - logger.EeLog.Errorf("Get Request Body error: %+v", err) - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&patchList, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.EeLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, patchList) - req.Params["ueIdentity"] = c.Params.ByName("ueIdentity") - req.Params["subscriptionID"] = c.Params.ByName("subscriptionId") - - rsp := producer.HandleUpdateEeSubscription(req) - - if rsp.Status == http.StatusNoContent { - c.Status(rsp.Status) - } else { - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.EeLog.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/eventexposure/routers.go b/internal/sbi/eventexposure/routers.go deleted file mode 100644 index a6f7400..0000000 --- a/internal/sbi/eventexposure/routers.go +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Nudm_EE - * - * Nudm Event Exposure Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package eventexposure - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/util" - "github.com/free5gc/udm/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.UdmEeResUriPrefix) - - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_EE) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, udm_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, - }, - - { - "HTTPCreateEeSubscription", - strings.ToUpper("Post"), - "/:ueIdentity/ee-subscriptions", - HTTPCreateEeSubscription, - }, - - { - "HTTPDeleteEeSubscription", - strings.ToUpper("Delete"), - "/:ueIdentity/ee-subscriptions/:subscriptionId", - HTTPDeleteEeSubscription, - }, - - { - "HTTPUpdateEeSubscription", - strings.ToUpper("Patch"), - "/:ueIdentity/ee-subscriptions/:subscriptionId", - HTTPUpdateEeSubscription, - }, -} diff --git a/internal/sbi/httpcallback/data_change_notification_to_nf.go b/internal/sbi/httpcallback/data_change_notification_to_nf.go deleted file mode 100644 index dfc6be4..0000000 --- a/internal/sbi/httpcallback/data_change_notification_to_nf.go +++ /dev/null @@ -1,61 +0,0 @@ -package httpcallback - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -func HTTPDataChangeNotificationToNF(c *gin.Context) { - var dataChangeNotify models.DataChangeNotify - // 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.CallbackLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&dataChangeNotify, 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, dataChangeNotify) - req.Params["supi"] = c.Params.ByName("supi") - - rsp := producer.HandleDataChangeNotificationToNFRequest(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) - } -} diff --git a/internal/sbi/httpcallback/router.go b/internal/sbi/httpcallback/router.go deleted file mode 100644 index 2d926b6..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/sirupsen/logrus" - - "github.com/free5gc/udm/internal/logger" - logger_util "github.com/free5gc/util/logger" -) - -var HttpLog *logrus.Entry - -func init() { - HttpLog = logger.HttpLog -} - -// 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("") - - 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 "PATCH": - group.PATCH(route.Pattern, route.HandlerFunc) - case "DELETE": - group.DELETE(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, - }, - - { - "DataChangeNotificationToNF", - strings.ToUpper("Post"), - "/sdm-subscriptions", - HTTPDataChangeNotificationToNF, - }, -} diff --git a/internal/sbi/parameterprovision/api_subscription_data_update.go b/internal/sbi/parameterprovision/api_subscription_data_update.go deleted file mode 100644 index aec820c..0000000 --- a/internal/sbi/parameterprovision/api_subscription_data_update.go +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Nudm_PP - * - * Nudm Parameter Provision Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package parameterprovision - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// Update - provision parameters -func HTTPUpdate(c *gin.Context) { - var ppDataReq models.PpData - - // 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.PpLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&ppDataReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.PpLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, ppDataReq) - req.Params["gspi"] = c.Params.ByName("gpsi") - - rsp := producer.HandleUpdateRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.PpLog.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/parameterprovision/api_subscription_data_update_test.go b/internal/sbi/parameterprovision/api_subscription_data_update_test.go deleted file mode 100644 index abb4fb6..0000000 --- a/internal/sbi/parameterprovision/api_subscription_data_update_test.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Nudm_PP - * - * Nudm Parameter Provision Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package parameterprovision_test - -import ( - "testing" -) - -// Update - provision parameters -func TestUpdate(t *testing.T) { - /*go handler.Handle() - go func() { // udm server - router := gin.Default() - Nudm_PP_Server.AddService(router) - - udmLogPath := path_util.Free5gcPath("free5gc/udmsslkey.log") - udmPemPath := path_util.Free5gcPath("free5gc/support/TLS/udm.pem") - udmKeyPath := path_util.Free5gcPath("free5gc/support/TLS/udm.key") - server, err := http2_util.NewServer(":29503", udmLogPath, router) - if err == nil && server != nil { - logger.InitLog.Infoln(server.ListenAndServeTLS(udmPemPath, udmKeyPath)) - assert.True(t, err == nil) - } - }() - - go func() { // fake udr server - router := gin.Default() - - router.PATCH("/nudr-dr/v1/:gpsi/pp-data", func(c *gin.Context) { - gpsi := c.Param("gpsi") - fmt.Println("==========CreateEeSubscription - Subscribe==========") - fmt.Println("ueIdentity: ", gpsi) - var testppData models.PpData - if err := c.ShouldBindJSON(&testppData); err != nil { - fmt.Println("fake udm server error: ", err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{}) - return - } - fmt.Println("patchItems: ", testppData) - c.JSON(http.StatusCreated, gin.H{}) - }) - - udrLogPath := path_util.Free5gcPath("free5gc/udrsslkey.log") - udrPemPath := path_util.Free5gcPath("free5gc/support/TLS/udr.pem") - udrKeyPath := path_util.Free5gcPath("free5gc/support/TLS/udr.key") - - server, err := http2_util.NewServer(":29504", udrLogPath, router) - if err == nil && server != nil { - logger.InitLog.Infoln(server.ListenAndServeTLS(udrPemPath, udrKeyPath)) - assert.True(t, err == nil) - } - }() - - udm_context.Init() - cfg := Nudm_PP_Client.NewConfiguration() - cfg.SetBasePath("https://localhost:29503") - clientAPI := Nudm_PP_Client.NewAPIClient(cfg) - - var ppData models.PpData - ppData.SupportedFeatures = "Test001" - gpsi := "SDM1234" - resp, err := clientAPI.SubscriptionDataUpdateApi.Update(context.Background(), gpsi, ppData) - if err != nil { - fmt.Println(err.Error()) - } else { - fmt.Println("resp: ", resp) - } - */ -} diff --git a/internal/sbi/parameterprovision/routers.go b/internal/sbi/parameterprovision/routers.go deleted file mode 100644 index 1066db4..0000000 --- a/internal/sbi/parameterprovision/routers.go +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Nudm_PP - * - * Nudm Parameter Provision Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package parameterprovision - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/util" - "github.com/free5gc/udm/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.UdmPpResUriPrefix) - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_PP) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, udm_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, - }, - - { - "Update", - strings.ToUpper("Patch"), - "/:gpsi/pp-data", - HTTPUpdate, - }, -} diff --git a/internal/sbi/processor/ue_context_management.go b/internal/sbi/processor/ue_context_management.go index 29456d6..2d4b087 100644 --- a/internal/sbi/processor/ue_context_management.go +++ b/internal/sbi/processor/ue_context_management.go @@ -11,7 +11,6 @@ import ( "github.com/free5gc/openapi/models" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer/callback" ) // ue_context_managemanet_service @@ -145,7 +144,7 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure( go func() { logger.UecmLog.Infof("Send DeregNotify to old AMF GUAMI=%v", oldAmf3GppAccessRegContext.Guami) - pd := callback.SendOnDeregistrationNotification(ueID, + pd := p.SendOnDeregistrationNotification(ueID, oldAmf3GppAccessRegContext.DeregCallbackUri, deregistData) // Deregistration Notify Triggered if pd != nil { @@ -212,7 +211,7 @@ func (p *Processor) RegisterAmfNon3gppAccessProcedure( DeregReason: models.DeregistrationReason_UE_INITIAL_REGISTRATION, AccessType: models.AccessType_NON_3_GPP_ACCESS, } - callback.SendOnDeregistrationNotification(ueID, oldAmfNon3GppAccessRegContext.DeregCallbackUri, + p.SendOnDeregistrationNotification(ueID, oldAmfNon3GppAccessRegContext.DeregCallbackUri, deregistData) // Deregistration Notify Triggered return nil, nil, nil diff --git a/internal/sbi/producer/callback.go b/internal/sbi/producer/callback.go deleted file mode 100644 index c4c84ca..0000000 --- a/internal/sbi/producer/callback.go +++ /dev/null @@ -1,29 +0,0 @@ -package producer - -import ( - "net/http" - - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer/callback" - "github.com/free5gc/util/httpwrapper" -) - -// HandleDataChangeNotificationToNFRequest ... Send Data Change Notification -func HandleDataChangeNotificationToNFRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.CallbackLog.Infof("Handle DataChangeNotificationToNF") - - // step 2: retrieve request - dataChangeNotify := request.Body.(models.DataChangeNotify) - supi := request.Params["supi"] - - problemDetails := callback.DataChangeNotificationProcedure(dataChangeNotify.NotifyItems, supi) - - // step 4: process the return value from step 3 - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} diff --git a/internal/sbi/producer/callback/callback.go b/internal/sbi/producer/callback/callback.go deleted file mode 100644 index cf22d03..0000000 --- a/internal/sbi/producer/callback/callback.go +++ /dev/null @@ -1,97 +0,0 @@ -package callback - -import ( - "net/http" - - "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" - "github.com/free5gc/openapi/Nudm_UEContextManagement" - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" -) - -func DataChangeNotificationProcedure(notifyItems []models.NotifyItem, supi string) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) - if err != nil { - return pd - } - - ue, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) - configuration := Nudm_SubscriberDataManagement.NewConfiguration() - clientAPI := Nudm_SubscriberDataManagement.NewAPIClient(configuration) - - var problemDetails *models.ProblemDetails - for _, subscriptionDataSubscription := range ue.UdmSubsToNotify { - onDataChangeNotificationurl := subscriptionDataSubscription.OriginalCallbackReference - dataChangeNotification := models.ModificationNotification{} - dataChangeNotification.NotifyItems = notifyItems - - httpResponse, err := clientAPI.DataChangeNotificationCallbackDocumentApi.OnDataChangeNotification( - ctx, onDataChangeNotificationurl, dataChangeNotification) - if err != nil { - if httpResponse == nil { - logger.HttpLog.Error(err.Error()) - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Detail: err.Error(), - } - } else { - logger.HttpLog.Errorln(err.Error()) - - problemDetails = &models.ProblemDetails{ - Status: int32(httpResponse.StatusCode), - Detail: err.Error(), - } - } - } - defer func() { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.HttpLog.Errorf("OnDataChangeNotification response body cannot close: %+v", rspCloseErr) - } - }() - } - - return problemDetails -} - -func SendOnDeregistrationNotification(ueId string, onDeregistrationNotificationUrl string, - deregistData models.DeregistrationData, -) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NfType_UDM) - if err != nil { - return pd - } - configuration := Nudm_UEContextManagement.NewConfiguration() - clientAPI := Nudm_UEContextManagement.NewAPIClient(configuration) - - httpResponse, err := clientAPI.DeregistrationNotificationCallbackApi.DeregistrationNotify( - ctx, onDeregistrationNotificationUrl, deregistData) - if err != nil { - if httpResponse == nil { - logger.HttpLog.Error(err.Error()) - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "DEREGISTRATION_NOTIFICATION_ERROR", - Detail: err.Error(), - } - - return problemDetails - } else { - logger.HttpLog.Errorln(err.Error()) - problemDetails := &models.ProblemDetails{ - Status: int32(httpResponse.StatusCode), - Cause: "DEREGISTRATION_NOTIFICATION_ERROR", - Detail: err.Error(), - } - - return problemDetails - } - } - defer func() { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.HttpLog.Errorf("DeregistrationNotify response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} diff --git a/internal/sbi/producer/event_exposure.go b/internal/sbi/producer/event_exposure.go deleted file mode 100644 index 93a06b0..0000000 --- a/internal/sbi/producer/event_exposure.go +++ /dev/null @@ -1,234 +0,0 @@ -package producer - -import ( - "net/http" - "strconv" - "strings" - - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/util/httpwrapper" -) - -// TODO: complete this procedure based on TS 29503 5.5 -func CreateEeSubscriptionProcedure(ueIdentity string, - eesubscription models.EeSubscription, -) (*models.CreatedEeSubscription, *models.ProblemDetails) { - udmSelf := udm_context.GetSelf() - logger.EeLog.Debugf("udIdentity: %s", ueIdentity) - switch { - // GPSI (MSISDN identifier) represents a single UE - case strings.HasPrefix(ueIdentity, "msisdn-"): - fallthrough - // GPSI (External identifier) represents a single UE - case strings.HasPrefix(ueIdentity, "extid-"): - if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { - id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() - if err != nil { - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - return nil, problemDetails - } - - subscriptionID := strconv.Itoa(int(id)) - ue.EeSubscriptions[subscriptionID] = &eesubscription - createdEeSubscription := &models.CreatedEeSubscription{ - EeSubscription: &eesubscription, - } - return createdEeSubscription, nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - return nil, problemDetails - } - // external groupID represents a group of UEs - case strings.HasPrefix(ueIdentity, "extgroupid-"): - id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() - if err != nil { - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - return nil, problemDetails - } - subscriptionID := strconv.Itoa(int(id)) - createdEeSubscription := &models.CreatedEeSubscription{ - EeSubscription: &eesubscription, - } - - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if ue.ExternalGroupID == ueIdentity { - ue.EeSubscriptions[subscriptionID] = &eesubscription - } - return true - }) - return createdEeSubscription, nil - // represents any UEs - case ueIdentity == "anyUE": - id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() - if err != nil { - problemDetails := &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - return nil, problemDetails - } - subscriptionID := strconv.Itoa(int(id)) - createdEeSubscription := &models.CreatedEeSubscription{ - EeSubscription: &eesubscription, - } - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - ue.EeSubscriptions[subscriptionID] = &eesubscription - return true - }) - return createdEeSubscription, nil - default: - problemDetails := &models.ProblemDetails{ - Status: http.StatusBadRequest, - Cause: "MANDATORY_IE_INCORRECT", - InvalidParams: []models.InvalidParam{ - { - Param: "ueIdentity", - Reason: "incorrect format", - }, - }, - } - return nil, problemDetails - } -} - -func HandleDeleteEeSubscription(request *httpwrapper.Request) *httpwrapper.Response { - ueIdentity := request.Params["ueIdentity"] - subscriptionID := request.Params["subscriptionID"] - - DeleteEeSubscriptionProcedure(ueIdentity, subscriptionID) - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) -} - -// TODO: complete this procedure based on TS 29503 5.5 -func DeleteEeSubscriptionProcedure(ueIdentity string, subscriptionID string) { - udmSelf := udm_context.GetSelf() - - switch { - case strings.HasPrefix(ueIdentity, "msisdn-"): - fallthrough - case strings.HasPrefix(ueIdentity, "extid-"): - if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { - delete(ue.EeSubscriptions, subscriptionID) - } - case strings.HasPrefix(ueIdentity, "extgroupid-"): - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if ue.ExternalGroupID == ueIdentity { - delete(ue.EeSubscriptions, subscriptionID) - } - return true - }) - case ueIdentity == "anyUE": - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - delete(ue.EeSubscriptions, subscriptionID) - return true - }) - } - if id, err := strconv.ParseInt(subscriptionID, 10, 64); err != nil { - logger.EeLog.Warnf("subscriptionID covert type error: %+v", err) - } else { - udmSelf.EeSubscriptionIDGenerator.FreeID(id) - } -} - -func HandleUpdateEeSubscription(request *httpwrapper.Request) *httpwrapper.Response { - logger.EeLog.Infoln("Handle Update EE subscription") - logger.EeLog.Warnln("Update EE Subscription is not implemented") - - patchList := request.Body.([]models.PatchItem) - ueIdentity := request.Params["ueIdentity"] - subscriptionID := request.Params["subscriptionID"] - - problemDetails := UpdateEeSubscriptionProcedure(ueIdentity, subscriptionID, patchList) - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} - -// TODO: complete this procedure based on TS 29503 5.5 -func UpdateEeSubscriptionProcedure(ueIdentity string, subscriptionID string, - patchList []models.PatchItem, -) *models.ProblemDetails { - udmSelf := udm_context.GetSelf() - - switch { - case strings.HasPrefix(ueIdentity, "msisdn-"): - fallthrough - case strings.HasPrefix(ueIdentity, "extid-"): - if ue, ok := udmSelf.UdmUeFindByGpsi(ueIdentity); ok { - if _, ok := ue.EeSubscriptions[subscriptionID]; ok { - for _, patchItem := range patchList { - logger.EeLog.Debugf("patch item: %+v", patchItem) - // TODO: patch the Eesubscription - } - return nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "SUBSCRIPTION_NOT_FOUND", - } - return problemDetails - } - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "SUBSCRIPTION_NOT_FOUND", - } - return problemDetails - } - case strings.HasPrefix(ueIdentity, "extgroupid-"): - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if ue.ExternalGroupID == ueIdentity { - if _, ok := ue.EeSubscriptions[subscriptionID]; ok { - for _, patchItem := range patchList { - logger.EeLog.Debugf("patch item: %+v", patchItem) - // TODO: patch the Eesubscription - } - } - } - return true - }) - return nil - case ueIdentity == "anyUE": - udmSelf.UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if _, ok := ue.EeSubscriptions[subscriptionID]; ok { - for _, patchItem := range patchList { - logger.EeLog.Debugf("patch item: %+v", patchItem) - // TODO: patch the Eesubscription - } - } - return true - }) - return nil - default: - problemDetails := &models.ProblemDetails{ - Status: http.StatusBadRequest, - Cause: "MANDATORY_IE_INCORRECT", - InvalidParams: []models.InvalidParam{ - { - Param: "ueIdentity", - Reason: "incorrect format", - }, - }, - } - return problemDetails - } -} diff --git a/internal/sbi/producer/generate_auth_data.go b/internal/sbi/producer/generate_auth_data.go deleted file mode 100644 index a09c0ae..0000000 --- a/internal/sbi/producer/generate_auth_data.go +++ /dev/null @@ -1,591 +0,0 @@ -package producer - -import ( - cryptoRand "crypto/rand" - "encoding/hex" - "fmt" - "math/big" - "math/rand" - "net/http" - "reflect" - "strconv" - "strings" - "time" - - "github.com/antihax/optional" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nudr_DataRepository" - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/pkg/suci" - "github.com/free5gc/util/httpwrapper" - "github.com/free5gc/util/milenage" - "github.com/free5gc/util/ueauth" -) - -const ( - SqnMAx int64 = 0xFFFFFFFFFFFF - ind int64 = 32 - keyStrLen int = 32 - opStrLen int = 32 - opcStrLen int = 32 -) - -const ( - authenticationRejected string = "AUTHENTICATION_REJECTED" - resyncAMF string = "0000" -) - -func aucSQN(opc, k, auts, rand []byte) ([]byte, []byte) { - AK, SQNms := make([]byte, 6), make([]byte, 6) - macS := make([]byte, 8) - ConcSQNms := auts[:6] - AMF, err := hex.DecodeString(resyncAMF) - if err != nil { - return nil, nil - } - - logger.UeauLog.Tracef("aucSQN: ConcSQNms=[%x]", ConcSQNms) - - err = milenage.F2345(opc, k, rand, nil, nil, nil, nil, AK) - if err != nil { - logger.UeauLog.Errorln("aucSQN milenage F2345 err:", err) - } - - for i := 0; i < 6; i++ { - SQNms[i] = AK[i] ^ ConcSQNms[i] - } - - logger.UeauLog.Tracef("aucSQN: opc=[%x], k=[%x], rand=[%x], AMF=[%x], SQNms=[%x]\n", opc, k, rand, AMF, SQNms) - // The AMF used to calculate MAC-S assumes a dummy value of all zeros - err = milenage.F1(opc, k, rand, SQNms, AMF, nil, macS) - if err != nil { - logger.UeauLog.Errorln("aucSQN milenage F1 err:", err) - } - logger.UeauLog.Tracef("aucSQN: macS=[%x]\n", macS) - return SQNms, macS -} - -func strictHex(s string, n int) string { - l := len(s) - if l < n { - return strings.Repeat("0", n-l) + s - } else { - return s[l-n : l] - } -} - -func HandleGenerateAuthDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UeauLog.Infoln("Handle GenerateAuthDataRequest") - - // step 2: retrieve request - authInfoRequest := request.Body.(models.AuthenticationInfoRequest) - supiOrSuci := request.Params["supiOrSuci"] - - // step 3: handle the message - response, problemDetails := GenerateAuthDataProcedure(authInfoRequest, supiOrSuci) - - // 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 HandleConfirmAuthDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - logger.UeauLog.Infoln("Handle ConfirmAuthDataRequest") - - authEvent := request.Body.(models.AuthEvent) - supi := request.Params["supi"] - - problemDetails := ConfirmAuthDataProcedure(authEvent, supi) - - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusCreated, nil, nil) - } -} - -func ConfirmAuthDataProcedure(authEvent models.AuthEvent, supi string) (problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - var createAuthParam Nudr_DataRepository.CreateAuthenticationStatusParamOpts - optInterface := optional.NewInterface(authEvent) - createAuthParam.AuthEvent = optInterface - - client, err := createUDMClientToUDR(supi) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := client.AuthenticationStatusDocumentApi.CreateAuthenticationStatus( - ctx, supi, &createAuthParam) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("ConfirmAuth err:", err.Error()) - return problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UeauLog.Errorf("CreateAuthenticationStatus response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} - -func GenerateAuthDataProcedure(authInfoRequest models.AuthenticationInfoRequest, supiOrSuci string) ( - response *models.AuthenticationInfoResult, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - logger.UeauLog.Traceln("In GenerateAuthDataProcedure") - - response = &models.AuthenticationInfoResult{} - rand.New(rand.NewSource(time.Now().UnixNano())) - supi, err := suci.ToSupi(supiOrSuci, udm_context.GetSelf().SuciProfiles) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("suciToSupi error: ", err.Error()) - return nil, problemDetails - } - - logger.UeauLog.Tracef("supi conversion => [%s]", supi) - - client, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - authSubs, res, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(ctx, supi, nil) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - switch res.StatusCode { - case http.StatusNotFound: - logger.UeauLog.Warnf("Return from UDR QueryAuthSubsData error") - default: - logger.UeauLog.Errorln("Return from UDR QueryAuthSubsData error") - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAuthSubsData response body cannot close: %+v", rspCloseErr) - } - }() - - /* - K, RAND, CK, IK: 128 bits (16 bytes) (hex len = 32) - SQN, AK: 48 bits (6 bytes) (hex len = 12) TS33.102 - 6.3.2 - AMF: 16 bits (2 bytes) (hex len = 4) TS33.102 - Annex H - */ - - hasK, hasOP, hasOPC := false, false, false - var kStr, opStr, opcStr string - var k, op, opc []byte - - if authSubs.PermanentKey != nil { - kStr = authSubs.PermanentKey.PermanentKeyValue - if len(kStr) == keyStrLen { - k, err = hex.DecodeString(kStr) - if err != nil { - logger.UeauLog.Errorln("err:", err) - } else { - hasK = true - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Errorln("kStr length is ", len(kStr)) - return nil, problemDetails - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Errorln("Nil PermanentKey") - return nil, problemDetails - } - - if authSubs.Milenage != nil { - if authSubs.Milenage.Op != nil && authSubs.Milenage.Op.OpValue != "" { - opStr = authSubs.Milenage.Op.OpValue - if len(opStr) == opStrLen { - op, err = hex.DecodeString(opStr) - if err != nil { - logger.UeauLog.Errorln("err:", err) - } else { - hasOP = true - } - } else { - logger.UeauLog.Errorln("opStr length is ", len(opStr)) - } - } else { - logger.UeauLog.Infoln("Nil Op") - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Infoln("Nil Milenage") - return nil, problemDetails - } - - if authSubs.Opc != nil && authSubs.Opc.OpcValue != "" { - opcStr = authSubs.Opc.OpcValue - if len(opcStr) == opcStrLen { - opc, err = hex.DecodeString(opcStr) - if err != nil { - logger.UeauLog.Errorln("err:", err) - } else { - hasOPC = true - } - } else { - logger.UeauLog.Errorln("opcStr length is ", len(opcStr)) - } - } else { - logger.UeauLog.Infoln("Nil Opc") - } - - if !hasOPC && !hasOP { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - return nil, problemDetails - } - - if !hasOPC { - if hasK && hasOP { - opc, err = milenage.GenerateOPC(k, op) - if err != nil { - logger.UeauLog.Errorln("milenage GenerateOPC err:", err) - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - } - - logger.UeauLog.Errorln("Unable to derive OPC") - return nil, problemDetails - } - } - - sqnStr := strictHex(authSubs.SequenceNumber, 12) - logger.UeauLog.Traceln("sqnStr", sqnStr) - sqn, err := hex.DecodeString(sqnStr) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - logger.UeauLog.Tracef("K=[%x], sqn=[%x], OP=[%x], OPC=[%x]", k, sqn, op, opc) - - RAND := make([]byte, 16) - _, err = cryptoRand.Read(RAND) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - amfStr := strictHex(authSubs.AuthenticationManagementField, 4) - logger.UeauLog.Traceln("amfStr", amfStr) - AMF, err := hex.DecodeString(amfStr) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - logger.UeauLog.Tracef("RAND=[%x], AMF=[%x]", RAND, AMF) - - // re-synchronization - if authInfoRequest.ResynchronizationInfo != nil { - logger.UeauLog.Infof("Authentication re-synchronization") - - Auts, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Auts) - if deCodeErr != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: deCodeErr.Error(), - } - - logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails - } - - randHex, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Rand) - if deCodeErr != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: deCodeErr.Error(), - } - - logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails - } - - SQNms, macS := aucSQN(opc, k, Auts, randHex) - if reflect.DeepEqual(macS, Auts[6:]) { - _, err = cryptoRand.Read(RAND) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: deCodeErr.Error(), - } - - logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails - } - - // increment sqn authSubs.SequenceNumber - bigSQN := big.NewInt(0) - sqnStr = hex.EncodeToString(SQNms) - logger.UeauLog.Tracef("SQNstr=[%s]", sqnStr) - bigSQN.SetString(sqnStr, 16) - - bigInc := big.NewInt(ind + 1) - - bigP := big.NewInt(SqnMAx) - bigSQN = bigInc.Add(bigSQN, bigInc) - bigSQN = bigSQN.Mod(bigSQN, bigP) - sqnStr = fmt.Sprintf("%x", bigSQN) - sqnStr = strictHex(sqnStr, 12) - } else { - logger.UeauLog.Errorln("Re-Sync MAC failed ", supiOrSuci) - // Check if suci - suciPart := strings.Split(supiOrSuci, "-") - if suciPart[suci.PrefixPlace] == suci.PrefixSUCI && - suciPart[suci.SupiTypePlace] == suci.SupiTypeIMSI && - suciPart[suci.SchemePlace] != suci.NullScheme { - // Get SuciProfile index and write public key - keyIndex, err1 := strconv.Atoi(suciPart[suci.HNPublicKeyIDPlace]) - if err1 != nil { - logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace parse Error") - } else if keyIndex < 1 { - logger.UeauLog.Errorf("Re-Sync Failed UDM Public Key HNPublicKeyIDPlace keyIndex[%d] < 1", - keyIndex) - } else { - logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key ", - udm_context.GetSelf().SuciProfiles[keyIndex-1].PublicKey) - } - } - logger.UeauLog.Errorln("MACS ", macS) - logger.UeauLog.Errorln("Auts[6:] ", Auts[6:]) - logger.UeauLog.Errorln("Sqn ", SQNms) - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "modification is rejected", - } - return nil, problemDetails - } - } - - // increment sqn - bigSQN := big.NewInt(0) - sqn, err = hex.DecodeString(sqnStr) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: authenticationRejected, - Detail: err.Error(), - } - - logger.UeauLog.Errorln("err:", err) - return nil, problemDetails - } - - bigSQN.SetString(sqnStr, 16) - - bigInc := big.NewInt(1) - bigSQN = bigInc.Add(bigSQN, bigInc) - - SQNheStr := fmt.Sprintf("%x", bigSQN) - SQNheStr = strictHex(SQNheStr, 12) - patchItemArray := []models.PatchItem{ - { - Op: models.PatchOperation_REPLACE, - Path: "/sequenceNumber", - Value: SQNheStr, - }, - } - - var rsp *http.Response - - rsp, err = client.AuthenticationDataDocumentApi.ModifyAuthentication( - ctx, supi, patchItemArray) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "modification is rejected ", - Detail: err.Error(), - } - - logger.UeauLog.Errorln("update sqn error:", err) - return nil, problemDetails - } - defer func() { - if rspCloseErr := rsp.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("ModifyAuthentication response body cannot close: %+v", rspCloseErr) - } - }() - - // Run milenage - macA, macS := make([]byte, 8), make([]byte, 8) - CK, IK := make([]byte, 16), make([]byte, 16) - RES := make([]byte, 8) - AK, AKstar := make([]byte, 6), make([]byte, 6) - - // Generate macA, macS - err = milenage.F1(opc, k, RAND, sqn, AMF, macA, macS) - if err != nil { - logger.UeauLog.Errorln("milenage F1 err:", err) - } - - // Generate RES, CK, IK, AK, AKstar - // RES == XRES (expected RES) for server - err = milenage.F2345(opc, k, RAND, RES, CK, IK, AK, AKstar) - if err != nil { - logger.UeauLog.Errorln("milenage F2345 err:", err) - } - logger.UeauLog.Tracef("milenage RES=[%s]", hex.EncodeToString(RES)) - - // Generate AUTN - logger.UeauLog.Tracef("SQN=[%x], AK=[%x]", sqn, AK) - logger.UeauLog.Tracef("AMF=[%x], macA=[%x]", AMF, macA) - SQNxorAK := make([]byte, 6) - for i := 0; i < len(sqn); i++ { - SQNxorAK[i] = sqn[i] ^ AK[i] - } - logger.UeauLog.Tracef("SQN xor AK=[%x]", SQNxorAK) - AUTN := append(append(SQNxorAK, AMF...), macA...) - logger.UeauLog.Tracef("AUTN=[%x]", AUTN) - - var av models.AuthenticationVector - if authSubs.AuthenticationMethod == models.AuthMethod__5_G_AKA { - response.AuthType = models.AuthType__5_G_AKA - - // derive XRES* - key := append(CK, IK...) - FC := ueauth.FC_FOR_RES_STAR_XRES_STAR_DERIVATION - P0 := []byte(authInfoRequest.ServingNetworkName) - P1 := RAND - P2 := RES - - kdfValForXresStar, err := ueauth.GetKDFValue( - key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1), P2, ueauth.KDFLen(P2)) - if err != nil { - logger.UeauLog.Errorf("Get kdfValForXresStar err: %+v", err) - } - xresStar := kdfValForXresStar[len(kdfValForXresStar)/2:] - logger.UeauLog.Tracef("xresStar=[%x]", xresStar) - - // derive Kausf - FC = ueauth.FC_FOR_KAUSF_DERIVATION - P0 = []byte(authInfoRequest.ServingNetworkName) - P1 = SQNxorAK - kdfValForKausf, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) - if err != nil { - logger.UeauLog.Errorf("Get kdfValForKausf err: %+v", err) - } - logger.UeauLog.Tracef("Kausf=[%x]", kdfValForKausf) - - // Fill in rand, xresStar, autn, kausf - av.Rand = hex.EncodeToString(RAND) - av.XresStar = hex.EncodeToString(xresStar) - av.Autn = hex.EncodeToString(AUTN) - av.Kausf = hex.EncodeToString(kdfValForKausf) - av.AvType = models.AvType__5_G_HE_AKA - } else { // EAP-AKA' - response.AuthType = models.AuthType_EAP_AKA_PRIME - - // derive CK' and IK' - key := append(CK, IK...) - FC := ueauth.FC_FOR_CK_PRIME_IK_PRIME_DERIVATION - P0 := []byte(authInfoRequest.ServingNetworkName) - P1 := SQNxorAK - kdfVal, err := ueauth.GetKDFValue(key, FC, P0, ueauth.KDFLen(P0), P1, ueauth.KDFLen(P1)) - if err != nil { - logger.UeauLog.Errorf("Get kdfVal err: %+v", err) - } - logger.UeauLog.Tracef("kdfVal=[%x] (len=%d)", kdfVal, len(kdfVal)) - - // For TS 35.208 test set 19 & RFC 5448 test vector 1 - // CK': 0093 962d 0dd8 4aa5 684b 045c 9edf fa04 - // IK': ccfc 230c a74f cc96 c0a5 d611 64f5 a76 - - ckPrime := kdfVal[:len(kdfVal)/2] - ikPrime := kdfVal[len(kdfVal)/2:] - logger.UeauLog.Tracef("ckPrime=[%x], kPrime=[%x]", ckPrime, ikPrime) - - // Fill in rand, xres, autn, ckPrime, ikPrime - av.Rand = hex.EncodeToString(RAND) - av.Xres = hex.EncodeToString(RES) - av.Autn = hex.EncodeToString(AUTN) - av.CkPrime = hex.EncodeToString(ckPrime) - av.IkPrime = hex.EncodeToString(ikPrime) - av.AvType = models.AvType_EAP_AKA_PRIME - } - - response.AuthenticationVector = &av - response.Supi = supi - return response, nil -} diff --git a/internal/sbi/producer/parameter_provision.go b/internal/sbi/producer/parameter_provision.go deleted file mode 100644 index d3dfae1..0000000 --- a/internal/sbi/producer/parameter_provision.go +++ /dev/null @@ -1,56 +0,0 @@ -package producer - -import ( - "net/http" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/util/httpwrapper" -) - -func HandleUpdateRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.PpLog.Infoln("Handle UpdateRequest") - - // step 2: retrieve request - updateRequest := request.Body.(models.PpData) - gpsi := request.Params["gpsi"] - - // step 3: handle the message - problemDetails := UpdateProcedure(updateRequest, gpsi) - - // step 4: process the return value from step 3 - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} - -func UpdateProcedure(updateRequest models.PpData, gpsi string) (problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - clientAPI, err := createUDMClientToUDR(gpsi) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - res, err := clientAPI.ProvisionedParameterDataDocumentApi.ModifyPpData(ctx, gpsi, nil) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.PpLog.Errorf("ModifyPpData response body cannot close: %+v", rspCloseErr) - } - }() - return nil -} diff --git a/internal/sbi/producer/subscriber_data_management.go b/internal/sbi/producer/subscriber_data_management.go deleted file mode 100644 index cf36bcd..0000000 --- a/internal/sbi/producer/subscriber_data_management.go +++ /dev/null @@ -1,1543 +0,0 @@ -package producer - -import ( - "encoding/json" - "net/http" - "net/url" - "strconv" - "strings" - - "github.com/antihax/optional" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" - Nudr "github.com/free5gc/openapi/Nudr_DataRepository" - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/util/httpwrapper" -) - -func HandleGetAmDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetAmData") - - // step 2: retrieve request - supi := request.Params["supi"] - plmnIDStruct, problemDetails := getPlmnIDStruct(request.Query) - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - supportedFeatures := request.Query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := getAmDataProcedure(supi, plmnID, supportedFeatures) - - // 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) -} - -// TS 29.503 5.2.2.2.3 -// Access and Mobility Subscription Data Retrieval -func getAmDataProcedure(supi string, plmnID string, supportedFeatures string) ( - response *models.AccessAndMobilitySubscriptionData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var queryAmDataParamOpts Nudr.QueryAmDataParamOpts - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. - QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetAMSubsriptionData(&accessAndMobilitySubscriptionDataResp) - return &accessAndMobilitySubscriptionDataResp, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func HandleGetIdTranslationResultRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetIdTranslationResultRequest") - - // step 2: retrieve request - gpsi := request.Params["gpsi"] - - // step 3: handle the message - response, problemDetails := getIdTranslationResultProcedure(gpsi) - - // 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) -} - -// TS 29.503 5.2.2.2.10 -// Identifier Translation -func getIdTranslationResultProcedure(gpsi string) (response *models.IdTranslationResult, - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var idTranslationResult models.IdTranslationResult - var getIdentityDataParamOpts Nudr.GetIdentityDataParamOpts - - clientAPI, err := createUDMClientToUDR(gpsi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - idTranslationResultResp, res, err := clientAPI.QueryIdentityDataBySUPIOrGPSIDocumentApi.GetIdentityData( - ctx, gpsi, &getIdentityDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("GetIdentityData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - if idList := idTranslationResultResp; idList.SupiList != nil { - // GetCorrespondingSupi get corresponding Supi(here IMSI) matching the given Gpsi from the queried SUPI list from UDR - idTranslationResult.Supi = udm_context.GetCorrespondingSupi(idList) - idTranslationResult.Gpsi = gpsi - - return &idTranslationResult, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func HandleGetSupiRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetSupiRequest") - - // step 2: retrieve request - supi := request.Params["supi"] - plmnIDStruct, problemDetails := getPlmnIDStruct(request.Query) - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - dataSetNames := strings.Split(request.Query.Get("dataset-names"), ",") - supportedFeatures := request.Query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := getSupiProcedure(supi, plmnID, dataSetNames, supportedFeatures) - - // 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) -} - -// TS 29.503 5.2.2.2.9 -// Retrieval Of Multiple Data Set -func getSupiProcedure(supi string, plmnID string, dataSetNames []string, supportedFeatures string) ( - response *models.SubscriptionDataSets, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - if len(dataSetNames) < 2 { - problemDetails = &models.ProblemDetails{ - Status: http.StatusBadRequest, - Cause: "BAD_REQUEST", - Detail: "datasetNames must have at least 2 elements", - } - return nil, problemDetails - } - - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var subscriptionDataSets, subsDataSetBody models.SubscriptionDataSets - var ueContextInSmfDataResp models.UeContextInSmfData - pduSessionMap := make(map[string]models.PduSession) - var pgwInfoArray []models.PgwInfo - - var queryAmDataParamOpts Nudr.QueryAmDataParamOpts - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - var querySmfSelectDataParamOpts Nudr.QuerySmfSelectDataParamOpts - var queryTraceDataParamOpts Nudr.QueryTraceDataParamOpts - var querySmDataParamOpts Nudr.QuerySmDataParamOpts - - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - udm_context.GetSelf().CreateSubsDataSetsForUe(supi, subsDataSetBody) - - if containDataSetName(dataSetNames, string(models.DataSetName_AM)) { - var body models.AccessAndMobilitySubscriptionData - udm_context.GetSelf().CreateAccessMobilitySubsDataForUe(supi, body) - - amData, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi.QueryAmData( - ctx, supi, plmnID, &queryAmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetAMSubsriptionData(&amData) - subscriptionDataSets.AmData = &amData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - if containDataSetName(dataSetNames, string(models.DataSetName_SMF_SEL)) { - var smfSelSubsbody models.SmfSelectionSubscriptionData - udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, smfSelSubsbody) - - smfSelData, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi.QuerySmfSelectData(ctx, - supi, plmnID, &querySmfSelectDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorln(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorln(err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetSmfSelectionSubsData(&smfSelData) - subscriptionDataSets.SmfSelData = &smfSelData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - if containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMF)) { - var UeContextInSmfbody models.UeContextInSmfData - var querySmfRegListParamOpts Nudr.QuerySmfRegListParamOpts - querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, UeContextInSmfbody) - - pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( - ctx, supi, &querySmfRegListParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) - } - }() - - for _, element := range pdusess { - var pduSession models.PduSession - pduSession.Dnn = element.Dnn - pduSession.SmfInstanceId = element.SmfInstanceId - pduSession.PlmnId = element.PlmnId - pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession - } - ueContextInSmfDataResp.PduSessions = pduSessionMap - - for _, element := range pdusess { - var pgwInfo models.PgwInfo - pgwInfo.Dnn = element.Dnn - pgwInfo.PgwFqdn = element.PgwFqdn - pgwInfo.PlmnId = element.PlmnId - pgwInfoArray = append(pgwInfoArray, pgwInfo) - } - ueContextInSmfDataResp.PgwInfo = pgwInfoArray - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.UeCtxtInSmfData = &ueContextInSmfDataResp - subscriptionDataSets.UecSmfData = &ueContextInSmfDataResp - } else { - var problemDetails models.ProblemDetails - problemDetails.Cause = "DATA_NOT_FOUND" - logger.SdmLog.Errorf(problemDetails.Cause) - } - } - - // TODO: UE Context in SMSF Data - // if containDataSetName(dataSetNames, string(models.DataSetName_UEC_SMSF)) { - // } - - // TODO: SMS Subscription Data - // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_SUB)) { - // } - - if containDataSetName(dataSetNames, string(models.DataSetName_SM)) { - sessionManagementSubscriptionData, res, err := clientAPI.SessionManagementSubscriptionDataApi. - QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - smData, _, _, _ := udm_context.GetSelf().ManageSmData(sessionManagementSubscriptionData, "", "") - udmUe.SetSMSubsData(smData) - subscriptionDataSets.SmData = sessionManagementSubscriptionData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - if containDataSetName(dataSetNames, string(models.DataSetName_TRACE)) { - var TraceDatabody models.TraceData - udm_context.GetSelf().CreateTraceDataforUe(supi, TraceDatabody) - - traceData, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( - ctx, supi, plmnID, &queryTraceDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Errorf(err.Error()) - } else if err.Error() != res.Status { - logger.SdmLog.Errorf("Response State: %+v", err.Error()) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) - } - }() - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.TraceData = &traceData - udmUe.TraceDataResponse.TraceData = &traceData - subscriptionDataSets.TraceData = &traceData - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } - } - - // TODO: SMS Management Subscription Data - // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_MNG)) { - // } - - return &subscriptionDataSets, nil -} - -func HandleGetSharedDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetSharedData") - - // step 2: retrieve request - sharedDataIds := request.Query["sharedDataIds"] - supportedFeatures := request.Query.Get("supported-features") - // step 3: handle the message - response, problemDetails := getSharedDataProcedure(sharedDataIds, supportedFeatures) - - // 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) -} - -// TS 29.503 5.2.2.2.11 -// Shared Subscription Data Retrieval -func getSharedDataProcedure(sharedDataIds []string, supportedFeatures string) ( - response []models.SharedData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := createUDMClientToUDR("") - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var getSharedDataParamOpts Nudr.GetSharedDataParamOpts - getSharedDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - sharedDataResp, res, err := clientAPI.RetrievalOfSharedDataApi.GetSharedData(ctx, sharedDataIds, - &getSharedDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("GetShareData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udm_context.GetSelf().SharedSubsDataMap = udm_context.MappingSharedData(sharedDataResp) - sharedData := udm_context.ObtainRequiredSharedData(sharedDataIds, sharedDataResp) - return sharedData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func HandleGetSmDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetSmData") - - // step 2: retrieve request - supi := request.Params["supi"] - plmnIDStruct, problemDetails := getPlmnIDStruct(request.Query) - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - Dnn := request.Query.Get("dnn") - Snssai := request.Query.Get("single-nssai") - supportedFeatures := request.Query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := getSmDataProcedure(supi, plmnID, Dnn, Snssai, supportedFeatures) - - // 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) -} - -// TS 29.503 5.2.2.2.5 -// Session Management Subscription Data Retrieval -func getSmDataProcedure(supi string, plmnID string, Dnn string, Snssai string, supportedFeatures string) ( - response interface{}, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - logger.SdmLog.Infof("getSmDataProcedure: SUPI[%s] PLMNID[%s] DNN[%s] SNssai[%s]", supi, plmnID, Dnn, Snssai) - - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var querySmDataParamOpts Nudr.QuerySmDataParamOpts - querySmDataParamOpts.SingleNssai = optional.NewInterface(Snssai) - - sessionManagementSubscriptionDataResp, res, err := clientAPI.SessionManagementSubscriptionDataApi. - QuerySmData(ctx, supi, plmnID, &querySmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - smData, snssaikey, AllDnnConfigsbyDnn, AllDnns := udm_context.GetSelf().ManageSmData( - sessionManagementSubscriptionDataResp, Snssai, Dnn) - udmUe.SetSMSubsData(smData) - - rspSMSubDataList := make([]models.SessionManagementSubscriptionData, 0, 4) - - udmUe.SmSubsDataLock.RLock() - for _, eachSMSubData := range udmUe.SessionManagementSubsData { - rspSMSubDataList = append(rspSMSubDataList, eachSMSubData) - } - udmUe.SmSubsDataLock.RUnlock() - - switch { - case Snssai == "" && Dnn == "": - return AllDnns, nil - case Snssai != "" && Dnn == "": - udmUe.SmSubsDataLock.RLock() - defer udmUe.SmSubsDataLock.RUnlock() - return udmUe.SessionManagementSubsData[snssaikey].DnnConfigurations, nil - case Snssai == "" && Dnn != "": - return AllDnnConfigsbyDnn, nil - case Snssai != "" && Dnn != "": - return rspSMSubDataList, nil - default: - udmUe.SmSubsDataLock.RLock() - defer udmUe.SmSubsDataLock.RUnlock() - return udmUe.SessionManagementSubsData, nil - } - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func HandleGetNssaiRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetNssai") - - // step 2: retrieve request - supi := request.Params["supi"] - plmnIDStruct, problemDetails := getPlmnIDStruct(request.Query) - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - supportedFeatures := request.Query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := getNssaiProcedure(supi, plmnID, supportedFeatures) - - // 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) -} - -// TS 29.503 5.2.2.2.2 -// Slice Selection Subscription Data Retrieval -func getNssaiProcedure(supi string, plmnID string, supportedFeatures string) ( - *models.Nssai, *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var queryAmDataParamOpts Nudr.QueryAmDataParamOpts - queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - var nssaiResp models.Nssai - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. - QueryAmData(ctx, supi, plmnID, &queryAmDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails := &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmData response body cannot close: %+v", rspCloseErr) - } - }() - - nssaiResp = *accessAndMobilitySubscriptionDataResp.Nssai - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.Nssai = &nssaiResp - return udmUe.Nssai, nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func HandleGetSmfSelectDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetSmfSelectData") - - // step 2: retrieve request - supi := request.Params["supi"] - plmnIDStruct, problemDetails := getPlmnIDStruct(request.Query) - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc - supportedFeatures := request.Query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := getSmfSelectDataProcedure(supi, plmnID, supportedFeatures) - - // 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) -} - -// TS 29.503 5.2.2.2.4 -// SMF Selection Subscription Data Retrieval -func getSmfSelectDataProcedure(supi string, plmnID string, supportedFeatures string) ( - response *models.SmfSelectionSubscriptionData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var querySmfSelectDataParamOpts Nudr.QuerySmfSelectDataParamOpts - querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - var body models.SmfSelectionSubscriptionData - - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, body) - - smfSelectionSubscriptionDataResp, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi. - QuerySmfSelectData(ctx, supi, plmnID, &querySmfSelectDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfSelectData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.SetSmfSelectionSubsData(&smfSelectionSubscriptionDataResp) - return udmUe.SmfSelSubsData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func HandleSubscribeToSharedDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle SubscribeToSharedData") - - // step 2: retrieve request - sdmSubscription := request.Body.(models.SdmSubscription) - - // step 3: handle the message - header, response, problemDetails := subscribeToSharedDataProcedure(&sdmSubscription) - - // 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) - } -} - -// TS 29.503 5.2.2.3.3 -// Subscription to notifications of shared data change -func subscribeToSharedDataProcedure(sdmSubscription *models.SdmSubscription) ( - header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) - if err != nil { - return nil, nil, pd - } - cfg := Nudm_SubscriberDataManagement.NewConfiguration() - udmClientAPI := Nudm_SubscriberDataManagement.NewAPIClient(cfg) - - sdmSubscriptionResp, res, err := udmClientAPI.SubscriptionCreationForSharedDataApi.SubscribeToSharedData( - ctx, *sdmSubscription) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("SubscribeToSharedData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusCreated { - header = make(http.Header) - udm_context.GetSelf().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) - reourceUri := udm_context.GetSelf().GetSDMUri() + "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId - header.Set("Location", reourceUri) - return header, &sdmSubscriptionResp, nil - } else if res.StatusCode == http.StatusNotFound { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - - return nil, nil, problemDetails - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotImplemented, - Cause: "UNSUPPORTED_RESOURCE_URI", - } - - return nil, nil, problemDetails - } -} - -func HandleSubscribeRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle Subscribe") - - // step 2: retrieve request - sdmSubscription := request.Body.(models.SdmSubscription) - supi := request.Params["supi"] - - // step 3: handle the message - header, response, problemDetails := subscribeProcedure(&sdmSubscription, 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.StatusCreated, header, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNotFound, nil, nil) - } -} - -// TS 29.503 5.2.2.3.2 -// Subscription to notifications of data change -func subscribeProcedure(sdmSubscription *models.SdmSubscription, supi string) ( - header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - sdmSubscriptionResp, res, err := clientAPI.SDMSubscriptionsCollectionApi.CreateSdmSubscriptions( - ctx, supi, *sdmSubscription) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("CreateSdmSubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusCreated { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) - if udmUe == nil { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.CreateSubscriptiontoNotifChange(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) - header.Set("Location", udmUe.GetLocationURI2(udm_context.LocationUriSdmSubscription, supi)) - return header, &sdmSubscriptionResp, nil - } else if res.StatusCode == http.StatusNotFound { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, nil, problemDetails - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotImplemented, - Cause: "UNSUPPORTED_RESOURCE_URI", - } - return nil, nil, problemDetails - } -} - -func HandleUnsubscribeForSharedDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - logger.SdmLog.Infof("Handle UnsubscribeForSharedData") - - // step 2: retrieve request - subscriptionID := request.Params["subscriptionId"] - // step 3: handle the message - problemDetails := unsubscribeForSharedDataProcedure(subscriptionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) -} - -// TS 29.503 5.2.2.4.3 -// Unsubscribe to notifications of data change -func unsubscribeForSharedDataProcedure(subscriptionID string) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) - if err != nil { - return pd - } - cfg := Nudm_SubscriberDataManagement.NewConfiguration() - udmClientAPI := Nudm_SubscriberDataManagement.NewAPIClient(cfg) - - res, err := udmClientAPI.SubscriptionDeletionForSharedDataApi.UnsubscribeForSharedData( - ctx, subscriptionID) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails := &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("UnsubscribeForSharedData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusNoContent { - return nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return problemDetails - } -} - -func HandleUnsubscribeRequest(request *httpwrapper.Request) *httpwrapper.Response { - logger.SdmLog.Infof("Handle Unsubscribe") - - // step 2: retrieve request - supi := request.Params["supi"] - subscriptionID := request.Params["subscriptionId"] - - // step 3: handle the message - problemDetails := unsubscribeProcedure(supi, subscriptionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) -} - -// TS 29.503 5.2.2.4.2 -// Unsubscribe to notifications of data change -func unsubscribeProcedure(supi string, subscriptionID string) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - res, err := clientAPI.SDMSubscriptionDocumentApi.RemovesdmSubscriptions(ctx, supi, subscriptionID) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - logger.SdmLog.Warnln(err) - problemDetails := &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("RemovesdmSubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusNoContent { - return nil - } else { - problemDetails := &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - return problemDetails - } -} - -func HandleModifyRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle Modify") - - // step 2: retrieve request - sdmSubsModification := request.Body.(models.SdmSubsModification) - supi := request.Params["supi"] - subscriptionID := request.Params["subscriptionId"] - - // step 3: handle the message - response, problemDetails := modifyProcedure(&sdmSubsModification, supi, subscriptionID) - - // 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) -} - -// TS 29.503 5.2.2.7.2 -// Modification of a subscription to notifications of data change -func modifyProcedure(sdmSubsModification *models.SdmSubsModification, supi string, subscriptionID string) ( - response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - sdmSubscription := models.SdmSubscription{} - body := Nudr.UpdatesdmsubscriptionsParamOpts{ - SdmSubscription: optional.NewInterface(sdmSubscription), - } - - res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( - ctx, supi, subscriptionID, &body) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - return &sdmSubscription, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func HandleModifyForSharedDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle ModifyForSharedData") - - // step 2: retrieve request - sdmSubsModification := request.Body.(models.SdmSubsModification) - supi := request.Params["supi"] - subscriptionID := request.Params["subscriptionId"] - - // step 3: handle the message - response, problemDetails := modifyForSharedDataProcedure(&sdmSubsModification, supi, subscriptionID) - - // 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) -} - -// TS 29.503 5.2.2.7.3 -// Modification of a subscription to notifications of shared data change -func modifyForSharedDataProcedure(sdmSubsModification *models.SdmSubsModification, supi string, - subscriptionID string, -) (response *models.SdmSubscription, problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var sdmSubscription models.SdmSubscription - sdmSubs := models.SdmSubscription{} - body := Nudr.UpdatesdmsubscriptionsParamOpts{ - SdmSubscription: optional.NewInterface(sdmSubs), - } - - res, err := clientAPI.SDMSubscriptionDocumentApi.Updatesdmsubscriptions( - ctx, supi, subscriptionID, &body) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("Updatesdmsubscriptions response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - return &sdmSubscription, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func HandleGetTraceDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetTraceData") - - // step 2: retrieve request - supi := request.Params["supi"] - plmnID := request.Query.Get("plmn-id") - - // step 3: handle the message - response, problemDetails := getTraceDataProcedure(supi, plmnID) - - // 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 getTraceDataProcedure(supi string, plmnID string) ( - response *models.TraceData, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var body models.TraceData - var queryTraceDataParamOpts Nudr.QueryTraceDataParamOpts - - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - udm_context.GetSelf().CreateTraceDataforUe(supi, body) - - traceDataRes, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( - ctx, supi, plmnID, &queryTraceDataParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Warnln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Warnln(err) - } else { - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryTraceData response body cannot close: %+v", rspCloseErr) - } - }() - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.TraceData = &traceDataRes - udmUe.TraceDataResponse.TraceData = &traceDataRes - - return udmUe.TraceDataResponse.TraceData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "USER_NOT_FOUND", - } - - return nil, problemDetails - } -} - -func HandleGetUeContextInSmfDataRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.SdmLog.Infof("Handle GetUeContextInSmfData") - - // step 2: retrieve request - supi := request.Params["supi"] - supportedFeatures := request.Query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := getUeContextInSmfDataProcedure(supi, supportedFeatures) - - // 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 getUeContextInSmfDataProcedure(supi string, supportedFeatures string) ( - response *models.UeContextInSmfData, problemDetails *models.ProblemDetails, -) { - var body models.UeContextInSmfData - var ueContextInSmfData models.UeContextInSmfData - var pgwInfoArray []models.PgwInfo - var querySmfRegListParamOpts Nudr.QuerySmfRegListParamOpts - querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - clientAPI, err := createUDMClientToUDR(supi) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - pduSessionMap := make(map[string]models.PduSession) - udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, body) - - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - - pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( - ctx, supi, &querySmfRegListParamOpts) - if err != nil { - if res == nil { - logger.SdmLog.Infoln(err) - } else if err.Error() != res.Status { - logger.SdmLog.Infoln(err) - } else { - logger.SdmLog.Infoln(err) - problemDetails = &models.ProblemDetails{ - Status: int32(res.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return nil, problemDetails - } - } - defer func() { - if rspCloseErr := res.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QuerySmfRegList response body cannot close: %+v", rspCloseErr) - } - }() - - for _, element := range pdusess { - var pduSession models.PduSession - pduSession.Dnn = element.Dnn - pduSession.SmfInstanceId = element.SmfInstanceId - pduSession.PlmnId = element.PlmnId - pduSessionMap[strconv.Itoa(int(element.PduSessionId))] = pduSession - } - ueContextInSmfData.PduSessions = pduSessionMap - - for _, element := range pdusess { - var pgwInfo models.PgwInfo - pgwInfo.Dnn = element.Dnn - pgwInfo.PgwFqdn = element.PgwFqdn - pgwInfo.PlmnId = element.PlmnId - pgwInfoArray = append(pgwInfoArray, pgwInfo) - } - ueContextInSmfData.PgwInfo = pgwInfoArray - - if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) - if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) - } - udmUe.UeCtxtInSmfData = &ueContextInSmfData - return udmUe.UeCtxtInSmfData, nil - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "DATA_NOT_FOUND", - } - return nil, problemDetails - } -} - -func getPlmnIDStruct(queryParameters url.Values) (plmnIDStruct *models.PlmnId, problemDetails *models.ProblemDetails) { - if queryParameters["plmn-id"] != nil { - plmnIDJson := queryParameters["plmn-id"][0] - plmnIDStruct := &models.PlmnId{} - err := json.Unmarshal([]byte(plmnIDJson), plmnIDStruct) - if err != nil { - logger.SdmLog.Warnln("Unmarshal Error in targetPlmnListtruct: ", err) - } - return plmnIDStruct, nil - } else { - problemDetails := &models.ProblemDetails{ - Title: "Invalid Parameter", - Status: http.StatusBadRequest, - Cause: "No get plmn-id", - } - return nil, problemDetails - } -} - -func containDataSetName(dataSetNames []string, target string) bool { - for _, dataSetName := range dataSetNames { - if dataSetName == target { - return true - } - } - return false -} diff --git a/internal/sbi/producer/ue_context_management.go b/internal/sbi/producer/ue_context_management.go deleted file mode 100644 index f1f9b0c..0000000 --- a/internal/sbi/producer/ue_context_management.go +++ /dev/null @@ -1,742 +0,0 @@ -package producer - -import ( - "fmt" - "net/http" - "strconv" - "strings" - - "github.com/antihax/optional" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nudr_DataRepository" - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/consumer" - "github.com/free5gc/udm/internal/sbi/producer/callback" - "github.com/free5gc/util/httpwrapper" -) - -func createUDMClientToUDR(id string) (*Nudr_DataRepository.APIClient, error) { - uri := getUdrURI(id) - if uri == "" { - logger.ProcLog.Errorf("ID[%s] does not match any UDR", id) - return nil, fmt.Errorf("No UDR URI found") - } - cfg := Nudr_DataRepository.NewConfiguration() - cfg.SetBasePath(uri) - clientAPI := Nudr_DataRepository.NewAPIClient(cfg) - return clientAPI, nil -} - -func getUdrURI(id string) string { - if strings.Contains(id, "imsi") || strings.Contains(id, "nai") { // supi - ue, ok := udm_context.GetSelf().UdmUeFindBySupi(id) - if ok { - if ue.UdrUri == "" { - ue.UdrUri = consumer.SendNFIntancesUDR(id, consumer.NFDiscoveryToUDRParamSupi) - } - return ue.UdrUri - } else { - ue = udm_context.GetSelf().NewUdmUe(id) - ue.UdrUri = consumer.SendNFIntancesUDR(id, consumer.NFDiscoveryToUDRParamSupi) - return ue.UdrUri - } - } else if strings.Contains(id, "pei") { - var udrURI string - udm_context.GetSelf().UdmUePool.Range(func(key, value interface{}) bool { - ue := value.(*udm_context.UdmUeContext) - if ue.Amf3GppAccessRegistration != nil && ue.Amf3GppAccessRegistration.Pei == id { - if ue.UdrUri == "" { - ue.UdrUri = consumer.SendNFIntancesUDR(ue.Supi, consumer.NFDiscoveryToUDRParamSupi) - } - udrURI = ue.UdrUri - return false - } else if ue.AmfNon3GppAccessRegistration != nil && ue.AmfNon3GppAccessRegistration.Pei == id { - if ue.UdrUri == "" { - ue.UdrUri = consumer.SendNFIntancesUDR(ue.Supi, consumer.NFDiscoveryToUDRParamSupi) - } - udrURI = ue.UdrUri - return false - } - return true - }) - return udrURI - } else if strings.Contains(id, "extgroupid") { - // extra group id - return consumer.SendNFIntancesUDR(id, consumer.NFDiscoveryToUDRParamExtGroupId) - } else if strings.Contains(id, "msisdn") || strings.Contains(id, "extid") { - // gpsi - return consumer.SendNFIntancesUDR(id, consumer.NFDiscoveryToUDRParamGpsi) - } - return consumer.SendNFIntancesUDR("", consumer.NFDiscoveryToUDRParamNone) -} - -func HandleGetAmf3gppAccessRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infof("Handle HandleGetAmf3gppAccessRequest") - - // step 2: retrieve request - ueID := request.Params["ueId"] - supportedFeatures := request.Query.Get("supported-features") - - // step 3: handle the message - response, problemDetails := GetAmf3gppAccessProcedure(ueID, supportedFeatures) - - // 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 GetAmf3gppAccessProcedure(ueID string, supportedFeatures string) ( - response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - var queryAmfContext3gppParamOpts Nudr_DataRepository.QueryAmfContext3gppParamOpts - queryAmfContext3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - amf3GppAccessRegistration, resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi. - QueryAmfContext3gpp(ctx, ueID, &queryAmfContext3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return &amf3GppAccessRegistration, nil -} - -func HandleGetAmfNon3gppAccessRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infoln("Handle GetAmfNon3gppAccessRequest") - - // step 2: retrieve request - ueId := request.Params["ueId"] - supportedFeatures := request.Query.Get("supported-features") - - var queryAmfContextNon3gppParamOpts Nudr_DataRepository.QueryAmfContextNon3gppParamOpts - queryAmfContextNon3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - // step 3: handle the message - response, problemDetails := GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts, ueId) - - // 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 GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts Nudr_DataRepository. - QueryAmfContextNon3gppParamOpts, ueID string) (response *models.AmfNon3GppAccessRegistration, - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, pd - } - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - amfNon3GppAccessRegistration, resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi. - QueryAmfContextNon3gpp(ctx, ueID, &queryAmfContextNon3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.SdmLog.Errorf("QueryAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return &amfNon3GppAccessRegistration, nil -} - -func HandleRegistrationAmf3gppAccessRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infof("Handle RegistrationAmf3gppAccess") - - // step 2: retrieve request - registerRequest := request.Body.(models.Amf3GppAccessRegistration) - ueID := request.Params["ueId"] - logger.UecmLog.Info("UEID: ", ueID) - - // step 3: handle the message - header, response, problemDetails := RegistrationAmf3gppAccessProcedure(registerRequest, ueID) - - // step 4: process the return value from step 3 - if response != nil { - if header != nil { - // status code is based on SPEC, and option headers - return httpwrapper.NewResponse(http.StatusCreated, header, response) - } - return httpwrapper.NewResponse(http.StatusOK, nil, response) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} - -// TS 29.503 5.3.2.2.2 -func RegistrationAmf3gppAccessProcedure(registerRequest models.Amf3GppAccessRegistration, ueID string) ( - header http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - // TODO: EPS interworking with N26 is not supported yet in this stage - var oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration - var ue *udm_context.UdmUeContext - - if udm_context.GetSelf().UdmAmf3gppRegContextExists(ueID) { - ue, _ = udm_context.GetSelf().UdmUeFindBySupi(ueID) - oldAmf3GppAccessRegContext = ue.Amf3GppAccessRegistration - } - - udm_context.GetSelf().CreateAmf3gppRegContext(ueID, registerRequest) - - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var createAmfContext3gppParamOpts Nudr_DataRepository.CreateAmfContext3gppParamOpts - optInterface := optional.NewInterface(registerRequest) - createAmfContext3gppParamOpts.Amf3GppAccessRegistration = optInterface - resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.CreateAmfContext3gpp(ctx, - ueID, &createAmfContext3gppParamOpts) - if err != nil { - logger.UecmLog.Errorln("CreateAmfContext3gpp error : ", err) - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF - // corresponding to the same (e.g. 3GPP) access, if one exists - if oldAmf3GppAccessRegContext != nil { - if !ue.SameAsStoredGUAMI3gpp(*oldAmf3GppAccessRegContext.Guami) { - // Based on TS 23.502 4.2.2.2.2, If the serving NF removal reason indicated by the UDM is Initial Registration, - // the old AMF invokes the Nsmf_PDUSession_ReleaseSMContext (SM Context ID). Thus we give different - // dereg cause based on registration parameter from serving AMF - deregReason := models.DeregistrationReason_UE_REGISTRATION_AREA_CHANGE - if registerRequest.InitialRegistrationInd { - deregReason = models.DeregistrationReason_UE_INITIAL_REGISTRATION - } - deregistData := models.DeregistrationData{ - DeregReason: deregReason, - AccessType: models.AccessType__3_GPP_ACCESS, - } - - go func() { - logger.UecmLog.Infof("Send DeregNotify to old AMF GUAMI=%v", oldAmf3GppAccessRegContext.Guami) - pd := callback.SendOnDeregistrationNotification(ueID, - oldAmf3GppAccessRegContext.DeregCallbackUri, - deregistData) // Deregistration Notify Triggered - if pd != nil { - logger.UecmLog.Errorf("RegistrationAmf3gppAccess: send DeregNotify fail %v", pd) - } - }() - } - return nil, ®isterRequest, nil - } else { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration)) - return header, ®isterRequest, nil - } -} - -// TS 29.503 5.3.2.2.3 -func HandleRegisterAmfNon3gppAccessRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infof("Handle RegisterAmfNon3gppAccessRequest") - - // step 2: retrieve request - registerRequest := request.Body.(models.AmfNon3GppAccessRegistration) - ueID := request.Params["ueId"] - - // step 3: handle the message - header, response, problemDetails := RegisterAmfNon3gppAccessProcedure(registerRequest, ueID) - - // 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.StatusNoContent, nil, nil) - } -} - -func RegisterAmfNon3gppAccessProcedure(registerRequest models.AmfNon3GppAccessRegistration, ueID string) ( - header http.Header, response *models.AmfNon3GppAccessRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - var oldAmfNon3GppAccessRegContext *models.AmfNon3GppAccessRegistration - if udm_context.GetSelf().UdmAmfNon3gppRegContextExists(ueID) { - ue, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - oldAmfNon3GppAccessRegContext = ue.AmfNon3GppAccessRegistration - } - - udm_context.GetSelf().CreateAmfNon3gppRegContext(ueID, registerRequest) - - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - var createAmfContextNon3gppParamOpts Nudr_DataRepository.CreateAmfContextNon3gppParamOpts - optInterface := optional.NewInterface(registerRequest) - createAmfContextNon3gppParamOpts.AmfNon3GppAccessRegistration = optInterface - - resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.CreateAmfContextNon3gpp( - ctx, ueID, &createAmfContextNon3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF - // corresponding to the same (e.g. 3GPP) access, if one exists - if oldAmfNon3GppAccessRegContext != nil { - deregistData := models.DeregistrationData{ - DeregReason: models.DeregistrationReason_UE_INITIAL_REGISTRATION, - AccessType: models.AccessType_NON_3_GPP_ACCESS, - } - callback.SendOnDeregistrationNotification(ueID, oldAmfNon3GppAccessRegContext.DeregCallbackUri, - deregistData) // Deregistration Notify Triggered - - return nil, nil, nil - } else { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmfNon3GppAccessRegistration)) - return header, ®isterRequest, nil - } -} - -// TODO: ueID may be SUPI or GPSI, but this function did not handle this condition -func HandleUpdateAmf3gppAccessRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infof("Handle UpdateAmf3gppAccessRequest") - - // step 2: retrieve request - amf3GppAccessRegistrationModification := request.Body.(models.Amf3GppAccessRegistrationModification) - ueID := request.Params["ueId"] - - // step 3: handle the message - problemDetails := UpdateAmf3gppAccessProcedure(amf3GppAccessRegistrationModification, ueID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} - -func UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessRegistrationModification, ueID string) ( - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - var patchItemReqArray []models.PatchItem - currentContext := udm_context.GetSelf().GetAmf3gppRegContext(ueID) - if currentContext == nil { - logger.UecmLog.Errorln("[UpdateAmf3gppAccess] Empty Amf3gppRegContext") - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "CONTEXT_NOT_FOUND", - } - return problemDetails - } - - if request.Guami != nil { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - if udmUe.SameAsStoredGUAMI3gpp(*request.Guami) { // deregistration - logger.UecmLog.Infoln("UpdateAmf3gppAccess - deregistration") - request.PurgeFlag = true - } else { - logger.UecmLog.Errorln("INVALID_GUAMI") - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "INVALID_GUAMI", - } - return problemDetails - } - - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "guami" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = *request.Guami - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.PurgeFlag { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "purgeFlag" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.PurgeFlag - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.Pei != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "pei" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.Pei - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.ImsVoPs != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "imsVoPs" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.ImsVoPs - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.BackupAmfInfo != nil { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "backupAmfInfo" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.BackupAmfInfo - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.AmfContext3gpp(ctx, ueID, - patchItemReqArray) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - - return problemDetails - } - - if request.PurgeFlag { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - udmUe.Amf3GppAccessRegistration = nil - } - - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("AmfContext3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} - -// TODO: ueID may be SUPI or GPSI, but this function did not handle this condition -func HandleUpdateAmfNon3gppAccessRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infof("Handle UpdateAmfNon3gppAccessRequest") - - // step 2: retrieve request - requestMSG := request.Body.(models.AmfNon3GppAccessRegistrationModification) - ueID := request.Params["ueId"] - - // step 3: handle the message - problemDetails := UpdateAmfNon3gppAccessProcedure(requestMSG, ueID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} - -func UpdateAmfNon3gppAccessProcedure(request models.AmfNon3GppAccessRegistrationModification, ueID string) ( - problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - var patchItemReqArray []models.PatchItem - currentContext := udm_context.GetSelf().GetAmfNon3gppRegContext(ueID) - if currentContext == nil { - logger.UecmLog.Errorln("[UpdateAmfNon3gppAccess] Empty AmfNon3gppRegContext") - problemDetails = &models.ProblemDetails{ - Status: http.StatusNotFound, - Cause: "CONTEXT_NOT_FOUND", - } - return problemDetails - } - - if request.Guami != nil { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - if udmUe.SameAsStoredGUAMINon3gpp(*request.Guami) { // deregistration - logger.UecmLog.Infoln("UpdateAmfNon3gppAccess - deregistration") - request.PurgeFlag = true - } else { - logger.UecmLog.Errorln("INVALID_GUAMI") - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "INVALID_GUAMI", - } - } - - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "guami" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = *request.Guami - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.PurgeFlag { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "purgeFlag" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.PurgeFlag - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.Pei != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "pei" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.Pei - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.ImsVoPs != "" { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "imsVoPs" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.ImsVoPs - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - if request.BackupAmfInfo != nil { - var patchItemTmp models.PatchItem - patchItemTmp.Path = "/" + "backupAmfInfo" - patchItemTmp.Op = models.PatchOperation_REPLACE - patchItemTmp.Value = request.BackupAmfInfo - patchItemReqArray = append(patchItemReqArray, patchItemTmp) - } - - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.AmfContextNon3gpp(ctx, - ueID, patchItemReqArray) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("AmfContextNon3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - return problemDetails -} - -func HandleDeregistrationSmfRegistrations(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infof("Handle DeregistrationSmfRegistrations") - - // step 2: retrieve request - ueID := request.Params["ueId"] - pduSessionID := request.Params["pduSessionId"] - - // step 3: handle the message - problemDetails := DeregistrationSmfRegistrationsProcedure(ueID, pduSessionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } else { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} - -func DeregistrationSmfRegistrationsProcedure(ueID string, pduSessionID string) (problemDetails *models.ProblemDetails) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return pd - } - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.SMFRegistrationDocumentApi.DeleteSmfContext(ctx, ueID, pduSessionID) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("DeleteSmfContext response body cannot close: %+v", rspCloseErr) - } - }() - - return nil -} - -// SmfRegistrations -func HandleRegistrationSmfRegistrationsRequest(request *httpwrapper.Request) *httpwrapper.Response { - // step 1: log - logger.UecmLog.Infof("Handle RegistrationSmfRegistrations") - - // step 2: retrieve request - registerRequest := request.Body.(models.SmfRegistration) - ueID := request.Params["ueId"] - pduSessionID := request.Params["pduSessionId"] - - // step 3: handle the message - header, response, problemDetails := RegistrationSmfRegistrationsProcedure(®isterRequest, ueID, pduSessionID) - - // 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 { - // all nil - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } -} - -// SmfRegistrationsProcedure -func RegistrationSmfRegistrationsProcedure(request *models.SmfRegistration, ueID string, pduSessionID string) ( - header http.Header, response *models.SmfRegistration, problemDetails *models.ProblemDetails, -) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) - if err != nil { - return nil, nil, pd - } - contextExisted := false - udm_context.GetSelf().CreateSmfRegContext(ueID, pduSessionID) - if !udm_context.GetSelf().UdmSmfRegContextNotExists(ueID) { - contextExisted = true - } - - pduID64, err := strconv.ParseInt(pduSessionID, 10, 32) - if err != nil { - logger.UecmLog.Errorln(err.Error()) - } - pduID32 := int32(pduID64) - - var createSmfContextNon3gppParamOpts Nudr_DataRepository.CreateSmfContextNon3gppParamOpts - optInterface := optional.NewInterface(*request) - createSmfContextNon3gppParamOpts.SmfRegistration = optInterface - - clientAPI, err := createUDMClientToUDR(ueID) - if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) - } - - resp, err := clientAPI.SMFRegistrationDocumentApi.CreateSmfContextNon3gpp(ctx, ueID, - pduID32, &createSmfContextNon3gppParamOpts) - if err != nil { - problemDetails = &models.ProblemDetails{ - Status: int32(resp.StatusCode), - Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, - Detail: err.Error(), - } - return nil, nil, problemDetails - } - defer func() { - if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { - logger.UecmLog.Errorf("CreateSmfContextNon3gpp response body cannot close: %+v", rspCloseErr) - } - }() - - if contextExisted { - return nil, nil, nil - } else { - header = make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriSmfRegistration)) - return header, request, nil - } -} diff --git a/internal/sbi/subscriberdatamanagement/api_access_and_mobility_subscription_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_access_and_mobility_subscription_data_retrieval.go deleted file mode 100644 index d1150f3..0000000 --- a/internal/sbi/subscriberdatamanagement/api_access_and_mobility_subscription_data_retrieval.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetAmData - retrieve a UE's Access and Mobility Subscription Data -func HTTPGetAmData(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - req.Query.Set("plmn-id", c.Query("plmn-id")) - req.Query.Set("supported-features", c.Query("plmn-id")) - - rsp := producer.HandleGetAmDataRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_gpsi_to_supi_translation.go b/internal/sbi/subscriberdatamanagement/api_gpsi_to_supi_translation.go deleted file mode 100644 index 2627f48..0000000 --- a/internal/sbi/subscriberdatamanagement/api_gpsi_to_supi_translation.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetIdTranslationResult - retrieve a UE's SUPI -func HTTPGetIdTranslationResult(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["gpsi"] = c.Params.ByName("gpsi") - req.Query.Set("SupportedFeatures", c.Query("supported-features")) - - rsp := producer.HandleGetIdTranslationResultRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_providing_acknowledgement_of_steering_of_roaming.go b/internal/sbi/subscriberdatamanagement/api_providing_acknowledgement_of_steering_of_roaming.go deleted file mode 100644 index b85f54e..0000000 --- a/internal/sbi/subscriberdatamanagement/api_providing_acknowledgement_of_steering_of_roaming.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// Info - Nudm_Sdm Info service operation -func HTTPInfo(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/subscriberdatamanagement/api_providing_acknowledgement_of_ue_parameters_update.go b/internal/sbi/subscriberdatamanagement/api_providing_acknowledgement_of_ue_parameters_update.go deleted file mode 100644 index ac34c44..0000000 --- a/internal/sbi/subscriberdatamanagement/api_providing_acknowledgement_of_ue_parameters_update.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// PutUpuAck - Nudm_Sdm Info for UPU service operation -func HTTPPutUpuAck(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/subscriberdatamanagement/api_retrieval_of_multiple_data_sets.go b/internal/sbi/subscriberdatamanagement/api_retrieval_of_multiple_data_sets.go deleted file mode 100644 index ae5fb82..0000000 --- a/internal/sbi/subscriberdatamanagement/api_retrieval_of_multiple_data_sets.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetSupi - retrieve multiple data sets -func HTTPGetSupi(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - req.Query.Set("plmn-id", c.Query("plmn-id")) - req.Query.Set("dataset-names", c.Query("dataset-names")) - req.Query.Set("supported-features", c.Query("supported-features")) - - rsp := producer.HandleGetSupiRequest(req) - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_retrieval_of_shared_data.go b/internal/sbi/subscriberdatamanagement/api_retrieval_of_shared_data.go deleted file mode 100644 index 2a97023..0000000 --- a/internal/sbi/subscriberdatamanagement/api_retrieval_of_shared_data.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetSharedData - retrieve shared data -func HTTPGetSharedData(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Query["sharedDataIds"] = c.QueryArray("shared-data-ids") - req.Query["supported-features"] = c.QueryArray("supported-features") - - rsp := producer.HandleGetSharedDataRequest(req) - - // step 5: response - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_session_management_subscription_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_session_management_subscription_data_retrieval.go deleted file mode 100644 index d8c2cb3..0000000 --- a/internal/sbi/subscriberdatamanagement/api_session_management_subscription_data_retrieval.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetSmData - retrieve a UE's Session Management Subscription Data -func HTTPGetSmData(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Param("supi") - req.Query.Set("plmn-id", c.Query("plmn-id")) - req.Query.Set("dnn", c.Query("dnn")) - req.Query.Set("single-nssai", c.Query("single-nssai")) - req.Query.Set("supported-features", c.Query("supported-features")) - - rsp := producer.HandleGetSmDataRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_slice_selection_subscription_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_slice_selection_subscription_data_retrieval.go deleted file mode 100644 index 61cb6c7..0000000 --- a/internal/sbi/subscriberdatamanagement/api_slice_selection_subscription_data_retrieval.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetNssai - retrieve a UE's subscribed NSSAI -func HTTPGetNssai(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - req.Query.Set("plmn-id", c.Query("plmn-id")) - req.Query.Set("supported-features", c.Query("supported-features")) - - rsp := producer.HandleGetNssaiRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_smf_selection_subscription_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_smf_selection_subscription_data_retrieval.go deleted file mode 100644 index 6d1a289..0000000 --- a/internal/sbi/subscriberdatamanagement/api_smf_selection_subscription_data_retrieval.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data -func HTTPGetSmfSelectData(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - req.Query.Set("plmn-id", c.Query("plmn-id")) - req.Query.Set("supported-features", c.Query("supported-features")) - - rsp := producer.HandleGetSmfSelectDataRequest(req) - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_sms_management_subscription_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_sms_management_subscription_data_retrieval.go deleted file mode 100644 index cf4cc6d..0000000 --- a/internal/sbi/subscriberdatamanagement/api_sms_management_subscription_data_retrieval.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsMngData - retrieve a UE's SMS Management Subscription Data -func HTTPGetSmsMngData(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/subscriberdatamanagement/api_sms_subscription_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_sms_subscription_data_retrieval.go deleted file mode 100644 index ec535c3..0000000 --- a/internal/sbi/subscriberdatamanagement/api_sms_subscription_data_retrieval.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsData - retrieve a UE's SMS Subscription Data -func HTTPGetSmsData(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/subscriberdatamanagement/api_subscription_creation.go b/internal/sbi/subscriberdatamanagement/api_subscription_creation.go deleted file mode 100644 index 51adf05..0000000 --- a/internal/sbi/subscriberdatamanagement/api_subscription_creation.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// Subscribe - subscribe to notifications -func HTTPSubscribe(c *gin.Context) { - var sdmSubscriptionReq models.SdmSubscription - - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sdmSubscriptionReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, sdmSubscriptionReq) - req.Params["supi"] = c.Params.ByName("supi") - - rsp := producer.HandleSubscribeRequest(req) - - 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.SdmLog.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/subscriberdatamanagement/api_subscription_creation_for_shared_data.go b/internal/sbi/subscriberdatamanagement/api_subscription_creation_for_shared_data.go deleted file mode 100644 index a6c8744..0000000 --- a/internal/sbi/subscriberdatamanagement/api_subscription_creation_for_shared_data.go +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// SubscribeToSharedData - subscribe to notifications for shared data -func HTTPSubscribeToSharedData(c *gin.Context) { - var sharedDataSubsReq models.SdmSubscription - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sharedDataSubsReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, sharedDataSubsReq) - rsp := producer.HandleSubscribeToSharedDataRequest(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.SdmLog.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/subscriberdatamanagement/api_subscription_deletion.go b/internal/sbi/subscriberdatamanagement/api_subscription_deletion.go deleted file mode 100644 index c7870d9..0000000 --- a/internal/sbi/subscriberdatamanagement/api_subscription_deletion.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// Unsubscribe - unsubscribe from notifications -func HTTPUnsubscribe(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - req.Params["subscriptionId"] = c.Params.ByName("subscriptionId") - - rsp := producer.HandleUnsubscribeRequest(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.SdmLog.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/subscriberdatamanagement/api_subscription_deletion_for_shared_data.go b/internal/sbi/subscriberdatamanagement/api_subscription_deletion_for_shared_data.go deleted file mode 100644 index 306d347..0000000 --- a/internal/sbi/subscriberdatamanagement/api_subscription_deletion_for_shared_data.go +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// UnsubscribeForSharedData - unsubscribe from notifications for shared data -func HTTPUnsubscribeForSharedData(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["subscriptionId"] = c.Params.ByName("subscriptionId") - - rsp := producer.HandleUnsubscribeForSharedDataRequest(req) - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_subscription_modification.go b/internal/sbi/subscriberdatamanagement/api_subscription_modification.go deleted file mode 100644 index b0f543e..0000000 --- a/internal/sbi/subscriberdatamanagement/api_subscription_modification.go +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// Modify - modify the subscription -func HTTPModify(c *gin.Context) { - var sdmSubsModificationReq models.SdmSubsModification - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sdmSubsModificationReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, sdmSubsModificationReq) - req.Params["supi"] = c.Params.ByName("supi") - req.Params["subscriptionId"] = c.Params.ByName("subscriptionId") - - rsp := producer.HandleModifyRequest(req) - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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) - } -} - -// ModifyForSharedData - modify the subscription -func HTTPModifyForSharedData(c *gin.Context) { - var sharedDataSubscriptions models.SdmSubsModification - // 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.SdmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&sharedDataSubscriptions, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.SdmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, sharedDataSubscriptions) - req.Params["supi"] = c.Params.ByName("supi") - req.Params["subscriptionId"] = c.Params.ByName("subscriptionId") - - rsp := producer.HandleModifyForSharedDataRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_trace_configuration_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_trace_configuration_data_retrieval.go deleted file mode 100644 index 6ae6aff..0000000 --- a/internal/sbi/subscriberdatamanagement/api_trace_configuration_data_retrieval.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetTraceData - retrieve a UE's Trace Configuration Data -func HTTPGetTraceData(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - req.Query.Set("plmn-id", c.Query("plmn-id")) - - rsp := producer.HandleGetTraceDataRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_ue_context_in_smf_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_ue_context_in_smf_data_retrieval.go deleted file mode 100644 index 2486cc7..0000000 --- a/internal/sbi/subscriberdatamanagement/api_ue_context_in_smf_data_retrieval.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data -func HTTPGetUeContextInSmfData(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["supi"] = c.Params.ByName("supi") - req.Query.Set("supported-features", c.Query("supported-features")) - - rsp := producer.HandleGetUeContextInSmfDataRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.SdmLog.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/subscriberdatamanagement/api_ue_context_in_smsf_data_retrieval.go b/internal/sbi/subscriberdatamanagement/api_ue_context_in_smsf_data_retrieval.go deleted file mode 100644 index 804d0d2..0000000 --- a/internal/sbi/subscriberdatamanagement/api_ue_context_in_smsf_data_retrieval.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 2.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetUeContextInSmsfData - retrieve a UE's UE Context In SMSF Data -func HTTPGetUeContextInSmsfData(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/subscriberdatamanagement/routers.go b/internal/sbi/subscriberdatamanagement/routers.go deleted file mode 100644 index 82469d1..0000000 --- a/internal/sbi/subscriberdatamanagement/routers.go +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Nudm_SDM - * - * Nudm Subscriber Data Management Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package subscriberdatamanagement - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/util" - "github.com/free5gc/udm/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 oneLayerPathHandlerFunc(c *gin.Context) { - supi := c.Param("supi") - for _, route := range oneLayerPathRouter { - if strings.Contains(route.Pattern, supi) && route.Method == c.Request.Method { - route.HandlerFunc(c) - return - } - } - - // special case for :supi - if c.Request.Method == strings.ToUpper("Get") { - HTTPGetSupi(c) - return - } - - c.String(http.StatusNotFound, "404 page not found") -} - -func twoLayerPathHandlerFunc(c *gin.Context) { - supi := c.Param("supi") - op := c.Param("subscriptionId") - - // for "/shared-data-subscriptions/:subscriptionId" - if supi == "shared-data-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { - HTTPUnsubscribeForSharedData(c) - return - } - - // for "/shared-data-subscriptions/:subscriptionId" - if supi == "shared-data-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { - HTTPModifyForSharedData(c) - return - } - - // for "/:gpsi/id-translation-result" - if op == "id-translation-result" && strings.ToUpper("Get") == c.Request.Method { - c.Params = append(c.Params, gin.Param{Key: "gpsi", Value: c.Param("supi")}) - HTTPGetIdTranslationResult(c) - return - } - - for _, route := range twoLayerPathRouter { - if strings.Contains(route.Pattern, op) && route.Method == c.Request.Method { - route.HandlerFunc(c) - return - } - } - - c.String(http.StatusNotFound, "404 page not found") -} - -func threeLayerPathHandlerFunc(c *gin.Context) { - op := c.Param("subscriptionId") - - // for "/:supi/sdm-subscriptions/:subscriptionId" - if op == "sdm-subscriptions" && strings.ToUpper("Delete") == c.Request.Method { - var tmpParams gin.Params - tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) - tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) - c.Params = tmpParams - HTTPUnsubscribe(c) - return - } - - // for "/:supi/am-data/sor-ack" - if op == "am-data" && strings.ToUpper("Put") == c.Request.Method { - HTTPInfo(c) - return - } - - // for "/:supi/sdm-subscriptions/:subscriptionId" - if op == "sdm-subscriptions" && strings.ToUpper("Patch") == c.Request.Method { - var tmpParams gin.Params - tmpParams = append(tmpParams, gin.Param{Key: "supi", Value: c.Param("supi")}) - tmpParams = append(tmpParams, gin.Param{Key: "subscriptionId", Value: c.Param("thirdLayer")}) - c.Params = tmpParams - HTTPModify(c) - return - } - - c.String(http.StatusNotFound, "404 page not found") -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.UdmSdmResUriPrefix) - - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_SDM) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, udm_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) - } - } - - oneLayerPath := "/:supi" - group.Any(oneLayerPath, oneLayerPathHandlerFunc) - - twoLayerPath := "/:supi/:subscriptionId" - group.Any(twoLayerPath, twoLayerPathHandlerFunc) - - threeLayerPath := "/:supi/:subscriptionId/:thirdLayer" - group.Any(threeLayerPath, threeLayerPathHandlerFunc) - - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "/", - Index, - }, -} - -/* -var specialRouter = Routes{ - { - "GetIdTranslationResult", - strings.ToUpper("Get"), - "/:gpsi/id-translation-result", - HTTPGetIdTranslationResult, - }, - - { - "UnsubscribeForSharedData", - strings.ToUpper("Delete"), - "/shared-data-subscriptions/:subscriptionId", - HTTPUnsubscribeForSharedData, - }, - - { - "ModifyForSharedData", - strings.ToUpper("Patch"), - "/shared-data-subscriptions/:subscriptionId", - HTTPModifyForSharedData, - }, -} -*/ - -var oneLayerPathRouter = Routes{ - { - "GetSupi", - strings.ToUpper("Get"), - "/:supi", - HTTPGetSupi, - }, - - { - "GetSharedData", - strings.ToUpper("Get"), - "/shared-data", - HTTPGetSharedData, - }, - - { - "SubscribeToSharedData", - strings.ToUpper("Post"), - "/shared-data-subscriptions", - HTTPSubscribeToSharedData, - }, -} - -var twoLayerPathRouter = Routes{ - { - "GetAmData", - strings.ToUpper("Get"), - "/:supi/am-data", - HTTPGetAmData, - }, - - { - "GetSmfSelectData", - strings.ToUpper("Get"), - "/:supi/smf-select-data", - HTTPGetSmfSelectData, - }, - - { - "GetSmsMngData", - strings.ToUpper("Get"), - "/:supi/sms-mng-data", - HTTPGetSmsMngData, - }, - - { - "GetSmsData", - strings.ToUpper("Get"), - "/:supi/sms-data", - HTTPGetSmsData, - }, - - { - "GetSmData", - strings.ToUpper("Get"), - "/:supi/sm-data", - HTTPGetSmData, - }, - - { - "GetNssai", - strings.ToUpper("Get"), - "/:supi/nssai", - HTTPGetNssai, - }, - - { - "Subscribe", - strings.ToUpper("Post"), - "/:supi/sdm-subscriptions", - HTTPSubscribe, - }, - - { - "GetTraceData", - strings.ToUpper("Get"), - "/:supi/trace-data", - HTTPGetTraceData, - }, - - { - "GetUeContextInSmfData", - strings.ToUpper("Get"), - "/:supi/ue-context-in-smf-data", - HTTPGetUeContextInSmfData, - }, - - { - "GetUeContextInSmsfData", - strings.ToUpper("Get"), - "/:supi/ue-context-in-smsf-data", - HTTPGetUeContextInSmsfData, - }, -} - -/* -var threeLayerPathRouter = Routes{ - { - "Unsubscribe", - strings.ToUpper("Delete"), - "/:supi/sdm-subscriptions/:subscriptionId", - HTTPUnsubscribe, - }, - - { - "Info", - strings.ToUpper("Put"), - "/:supi/am-data/sor-ack", - HTTPInfo, - }, - - { - "PutUpuAck", - strings.ToUpper("Put"), - "/:supi/am-data/upu-ack", - HTTPPutUpuAck, - }, - - { - "Modify", - strings.ToUpper("Patch"), - "/:supi/sdm-subscriptions/:subscriptionId", - HTTPModify, - }, -} - -var routesBackup = Routes{ - { - "Index", - "GET", - "/", - Index, - }, - - { - "GetAmData", - strings.ToUpper("Get"), - "/:supi/am-data", - HTTPGetAmData, - }, - - { - "Info", - strings.ToUpper("Put"), - "/:supi/am-data/sor-ack", - HTTPInfo, - }, - - { - "GetSupi", - strings.ToUpper("Get"), - "/:supi", - HTTPGetSupi, - }, - - { - "GetSharedData", - strings.ToUpper("Get"), - "/shared-data", - HTTPGetSharedData, - }, - - { - "GetSmfSelectData", - strings.ToUpper("Get"), - "/:supi/smf-select-data", - HTTPGetSmfSelectData, - }, - - { - "GetSmsMngData", - strings.ToUpper("Get"), - "/:supi/sms-mng-data", - HTTPGetSmsMngData, - }, - - { - "GetSmsData", - strings.ToUpper("Get"), - "/:supi/sms-data", - HTTPGetSmsData, - }, - - { - "GetSmData", - strings.ToUpper("Get"), - "/:supi/sm-data", - HTTPGetSmData, - }, - - { - "GetNssai", - strings.ToUpper("Get"), - "/:supi/nssai", - HTTPGetNssai, - }, - - { - "Subscribe", - strings.ToUpper("Post"), - "/:supi/sdm-subscriptions", - HTTPSubscribe, - }, - - { - "SubscribeToSharedData", - strings.ToUpper("Post"), - "/shared-data-subscriptions", - HTTPSubscribeToSharedData, - }, - - { - "Unsubscribe", - strings.ToUpper("Delete"), - "/:supi/sdm-subscriptions/:subscriptionId", - HTTPUnsubscribe, - }, - - { - "UnsubscribeForSharedData", - strings.ToUpper("Delete"), - "/shared-data-subscriptions/:subscriptionId", - HTTPUnsubscribeForSharedData, - }, - - { - "GetTraceData", - strings.ToUpper("Get"), - "/:supi/trace-data", - HTTPGetTraceData, - }, - - { - "GetUeContextInSmfData", - strings.ToUpper("Get"), - "/:supi/ue-context-in-smf-data", - HTTPGetUeContextInSmfData, - }, - - { - "GetUeContextInSmsfData", - strings.ToUpper("Get"), - "/:supi/ue-context-in-smsf-data", - HTTPGetUeContextInSmsfData, - }, - - { - "GetIdTranslationResult", - strings.ToUpper("Get"), - "/:gpsi/id-translation-result", - HTTPGetIdTranslationResult, - }, -} -*/ diff --git a/internal/sbi/ueauthentication/api_confirm_auth.go b/internal/sbi/ueauthentication/api_confirm_auth.go deleted file mode 100644 index 6e6e79d..0000000 --- a/internal/sbi/ueauthentication/api_confirm_auth.go +++ /dev/null @@ -1,72 +0,0 @@ -/* - * NudmUEAU - * - * UDM UE Authentication Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package ueauthentication - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// ConfirmAuth - Create a new confirmation event -func HTTPConfirmAuth(c *gin.Context) { - var authEvent models.AuthEvent - // 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.UeauLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&authEvent, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UeauLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, authEvent) - req.Params["supi"] = c.Params.ByName("supi") - - rsp := producer.HandleConfirmAuthDataRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.UeauLog.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/ueauthentication/api_generate_auth_data.go b/internal/sbi/ueauthentication/api_generate_auth_data.go deleted file mode 100644 index a4e0680..0000000 --- a/internal/sbi/ueauthentication/api_generate_auth_data.go +++ /dev/null @@ -1,73 +0,0 @@ -/* - * NudmUEAU - * - * UDM UE Authentication Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package ueauthentication - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GenerateAuthData - Generate authentication data for the UE -func HttpGenerateAuthData(c *gin.Context) { - var authInfoReq models.AuthenticationInfoRequest - - // 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.UeauLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&authInfoReq, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UeauLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, authInfoReq) - req.Params["supiOrSuci"] = c.Param("supiOrSuci") - - rsp := producer.HandleGenerateAuthDataRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.UeauLog.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/ueauthentication/routers.go b/internal/sbi/ueauthentication/routers.go deleted file mode 100644 index 2ca5def..0000000 --- a/internal/sbi/ueauthentication/routers.go +++ /dev/null @@ -1,123 +0,0 @@ -/* - * NudmUEAU - * - * UDM UE Authentication Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package ueauthentication - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" - - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/util" - "github.com/free5gc/udm/pkg/factory" - logger_util "github.com/free5gc/util/logger" -) - -var HttpLog *logrus.Entry - -func init() { - HttpLog = logger.HttpLog -} - -// 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 genAuthDataHandlerFunc(c *gin.Context) { - c.Params = append(c.Params, gin.Param{Key: "supiOrSuci", Value: c.Param("supi")}) - if strings.ToUpper("Post") == c.Request.Method { - HttpGenerateAuthData(c) - return - } - - c.String(http.StatusNotFound, "404 page not found") -} - -func AddService(engine *gin.Engine) *gin.RouterGroup { - group := engine.Group(factory.UdmUeauResUriPrefix) - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_UEAU) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, udm_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) - } - } - - genAuthDataPath := "/:supi/security-information/generate-auth-data" - group.Any(genAuthDataPath, genAuthDataHandlerFunc) - - return group -} - -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - -var routes = Routes{ - { - "Index", - "GET", - "/", - Index, - }, - - { - "ConfirmAuth", - strings.ToUpper("Post"), - "/:supi/auth-events", - HTTPConfirmAuth, - }, -} - -/* -var specialRoutes = Routes{ - { - "GenerateAuthData", - strings.ToUpper("Post"), - "/:supiOrSuci/security-information/generate-auth-data", - HttpGenerateAuthData, - }, -} -*/ diff --git a/internal/sbi/uecontextmanagement/api_amf3_gpp_access_registration_info_retrieval.go b/internal/sbi/uecontextmanagement/api_amf3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index 4a0acd5..0000000 --- a/internal/sbi/uecontextmanagement/api_amf3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information -func HTTPGetAmf3gppAccess(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["ueId"] = c.Param("ueId") - req.Query.Add("supported-features", c.Query("supported-features")) - - rsp := producer.HandleGetAmf3gppAccessRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.UecmLog.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/uecontextmanagement/api_amf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/uecontextmanagement/api_amf_non3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index b33fb42..0000000 --- a/internal/sbi/uecontextmanagement/api_amf_non3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// GetAmfNon3gppAccess - retrieve the AMF registration for non-3GPP access information -func HTTPGetAmfNon3gppAccess(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["ueId"] = c.Param("ueId") - req.Query.Add("supported-features", c.Query("supported-features")) - - rsp := producer.HandleGetAmfNon3gppAccessRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.UecmLog.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/uecontextmanagement/api_amf_registration_for3_gpp_access.go b/internal/sbi/uecontextmanagement/api_amf_registration_for3_gpp_access.go deleted file mode 100644 index 7e39c21..0000000 --- a/internal/sbi/uecontextmanagement/api_amf_registration_for3_gpp_access.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// RegistrationAmf3gppAccess - register as AMF for 3GPP access -func HTTPRegistrationAmf3gppAccess(c *gin.Context) { - var amf3GppAccessRegistration models.Amf3GppAccessRegistration - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amf3GppAccessRegistration, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, amf3GppAccessRegistration) - req.Params["ueId"] = c.Param("ueId") - - rsp := producer.HandleRegistrationAmf3gppAccessRequest(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.UecmLog.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/uecontextmanagement/api_amf_registration_for_non3_gpp_access.go b/internal/sbi/uecontextmanagement/api_amf_registration_for_non3_gpp_access.go deleted file mode 100644 index 6190365..0000000 --- a/internal/sbi/uecontextmanagement/api_amf_registration_for_non3_gpp_access.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// Register - register as AMF for non-3GPP access -func HTTPRegistrationAmfNon3gppAccess(c *gin.Context) { - var amfNon3GppAccessRegistration models.AmfNon3GppAccessRegistration - - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amfNon3GppAccessRegistration, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, amfNon3GppAccessRegistration) - req.Params["ueId"] = c.Param("ueId") - - rsp := producer.HandleRegisterAmfNon3gppAccessRequest(req) - - 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.UecmLog.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/uecontextmanagement/api_parameter_update_in_the_amf_registration_for3_gpp_access.go b/internal/sbi/uecontextmanagement/api_parameter_update_in_the_amf_registration_for3_gpp_access.go deleted file mode 100644 index 3646f85..0000000 --- a/internal/sbi/uecontextmanagement/api_parameter_update_in_the_amf_registration_for3_gpp_access.go +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// UpdateAmf3gppAccess - Update a parameter in the AMF registration for 3GPP access -func HTTPUpdateAmf3gppAccess(c *gin.Context) { - var amf3GppAccessRegistrationModification models.Amf3GppAccessRegistrationModification - - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amf3GppAccessRegistrationModification, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, amf3GppAccessRegistrationModification) - req.Params["ueId"] = c.Param("ueId") - - rsp := producer.HandleUpdateAmf3gppAccessRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.UecmLog.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/uecontextmanagement/api_parameter_update_in_the_amf_registration_for_non3_gpp_access.go b/internal/sbi/uecontextmanagement/api_parameter_update_in_the_amf_registration_for_non3_gpp_access.go deleted file mode 100644 index 775071e..0000000 --- a/internal/sbi/uecontextmanagement/api_parameter_update_in_the_amf_registration_for_non3_gpp_access.go +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access -func HTTPUpdateAmfNon3gppAccess(c *gin.Context) { - var amfNon3GppAccessRegistrationModification models.AmfNon3GppAccessRegistrationModification - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&amfNon3GppAccessRegistrationModification, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - - req := httpwrapper.NewRequest(c.Request, amfNon3GppAccessRegistrationModification) - req.Params["ueId"] = c.Param("ueId") - - rsp := producer.HandleUpdateAmfNon3gppAccessRequest(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.UecmLog.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/uecontextmanagement/api_smf_deregistration.go b/internal/sbi/uecontextmanagement/api_smf_deregistration.go deleted file mode 100644 index bdbc0a0..0000000 --- a/internal/sbi/uecontextmanagement/api_smf_deregistration.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// DeregistrationSmfRegistrations - delete an SMF registration -func HTTPDeregistrationSmfRegistrations(c *gin.Context) { - req := httpwrapper.NewRequest(c.Request, nil) - req.Params["ueId"] = c.Params.ByName("ueId") - req.Params["pduSessionId"] = c.Params.ByName("pduSessionId") - - rsp := producer.HandleDeregistrationSmfRegistrations(req) - - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.UecmLog.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/uecontextmanagement/api_smf_registration.go b/internal/sbi/uecontextmanagement/api_smf_registration.go deleted file mode 100644 index 03b2f13..0000000 --- a/internal/sbi/uecontextmanagement/api_smf_registration.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/sbi/producer" - "github.com/free5gc/util/httpwrapper" -) - -// RegistrationSmfRegistrations - register as SMF -func HTTPRegistrationSmfRegistrations(c *gin.Context) { - var smfRegistration models.SmfRegistration - - // 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.UecmLog.Errorf("Get Request Body error: %+v", err) - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - // step 2: convert requestBody to openapi models - err = openapi.Deserialize(&smfRegistration, requestBody, "application/json") - if err != nil { - problemDetail := "[Request Body] " + err.Error() - rsp := models.ProblemDetails{ - Title: "Malformed request syntax", - Status: http.StatusBadRequest, - Detail: problemDetail, - } - logger.UecmLog.Errorln(problemDetail) - c.JSON(http.StatusBadRequest, rsp) - return - } - req := httpwrapper.NewRequest(c.Request, smfRegistration) - req.Params["ueId"] = c.Params.ByName("ueId") - req.Params["pduSessionId"] = c.Params.ByName("pduSessionId") - - rsp := producer.HandleRegistrationSmfRegistrationsRequest(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.UecmLog.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/uecontextmanagement/api_smsf3_gpp_access_registration_info_retrieval.go b/internal/sbi/uecontextmanagement/api_smsf3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index 98e7dda..0000000 --- a/internal/sbi/uecontextmanagement/api_smsf3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsf3gppAccess - retrieve the SMSF registration for 3GPP access information -func HTTPGetSmsf3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/uecontextmanagement/api_smsf_deregistration_for3_gpp_access.go b/internal/sbi/uecontextmanagement/api_smsf_deregistration_for3_gpp_access.go deleted file mode 100644 index 3634298..0000000 --- a/internal/sbi/uecontextmanagement/api_smsf_deregistration_for3_gpp_access.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// DeregistrationSmsf3gppAccess - delete the SMSF registration for 3GPP access -func HTTPDeregistrationSmsf3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/uecontextmanagement/api_smsf_deregistration_for_non3_gpp_access.go b/internal/sbi/uecontextmanagement/api_smsf_deregistration_for_non3_gpp_access.go deleted file mode 100644 index 7411f58..0000000 --- a/internal/sbi/uecontextmanagement/api_smsf_deregistration_for_non3_gpp_access.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// DeregistrationSmsfNon3gppAccess - delete SMSF registration for non 3GPP access -func HTTPDeregistrationSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/uecontextmanagement/api_smsf_non3_gpp_access_registration_info_retrieval.go b/internal/sbi/uecontextmanagement/api_smsf_non3_gpp_access_registration_info_retrieval.go deleted file mode 100644 index 75b32fe..0000000 --- a/internal/sbi/uecontextmanagement/api_smsf_non3_gpp_access_registration_info_retrieval.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// GetSmsfNon3gppAccess - retrieve the SMSF registration for non-3GPP access information -func HTTPGetSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/uecontextmanagement/api_smsf_registration_for3_gpp_access.go b/internal/sbi/uecontextmanagement/api_smsf_registration_for3_gpp_access.go deleted file mode 100644 index 8474685..0000000 --- a/internal/sbi/uecontextmanagement/api_smsf_registration_for3_gpp_access.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// UpdateSMSFReg3GPP - register as SMSF for 3GPP access -func HTTPUpdateSMSFReg3GPP(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/uecontextmanagement/api_smsf_registration_for_non3_gpp_access.go b/internal/sbi/uecontextmanagement/api_smsf_registration_for_non3_gpp_access.go deleted file mode 100644 index 1d32047..0000000 --- a/internal/sbi/uecontextmanagement/api_smsf_registration_for_non3_gpp_access.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.1 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -// RegistrationSmsfNon3gppAccess - register as SMSF for non-3GPP access -func HTTPRegistrationSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} diff --git a/internal/sbi/uecontextmanagement/routers.go b/internal/sbi/uecontextmanagement/routers.go deleted file mode 100644 index ab67e22..0000000 --- a/internal/sbi/uecontextmanagement/routers.go +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Nudm_UECM - * - * Nudm Context Management Service - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package uecontextmanagement - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - - "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" - "github.com/free5gc/udm/internal/logger" - "github.com/free5gc/udm/internal/util" - "github.com/free5gc/udm/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.UdmUecmResUriPrefix) - routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_UECM) - group.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, udm_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, - }, - - { - "GetAmf3gppAccess", - strings.ToUpper("Get"), - "/:ueId/registrations/amf-3gpp-access", - HTTPGetAmf3gppAccess, - }, - - { - "GetAmfNon3gppAccess", - strings.ToUpper("Get"), - "/:ueId/registrations/amf-non-3gpp-access", - HTTPGetAmfNon3gppAccess, - }, - - { - "RegistrationAmf3gppAccess", - strings.ToUpper("Put"), - "/:ueId/registrations/amf-3gpp-access", - HTTPRegistrationAmf3gppAccess, - }, - - { - "Register", - strings.ToUpper("Put"), - "/:ueId/registrations/amf-non-3gpp-access", - HTTPRegistrationAmfNon3gppAccess, - }, - - { - "UpdateAmf3gppAccess", - strings.ToUpper("Patch"), - "/:ueId/registrations/amf-3gpp-access", - HTTPUpdateAmf3gppAccess, - }, - - { - "UpdateAmfNon3gppAccess", - strings.ToUpper("Patch"), - "/:ueId/registrations/amf-non-3gpp-access", - HTTPUpdateAmfNon3gppAccess, - }, - - { - "DeregistrationSmfRegistrations", - strings.ToUpper("Delete"), - "/:ueId/registrations/smf-registrations/:pduSessionId", - HTTPDeregistrationSmfRegistrations, - }, - - { - "RegistrationSmfRegistrations", - strings.ToUpper("Put"), - "/:ueId/registrations/smf-registrations/:pduSessionId", - HTTPRegistrationSmfRegistrations, - }, - - { - "GetSmsf3gppAccess", - strings.ToUpper("Get"), - "/:ueId/registrations/smsf-3gpp-access", - HTTPGetSmsf3gppAccess, - }, - - { - "DeregistrationSmsf3gppAccess", - strings.ToUpper("Delete"), - "/:ueId/registrations/smsf-3gpp-access", - HTTPDeregistrationSmsf3gppAccess, - }, - - { - "DeregistrationSmsfNon3gppAccess", - strings.ToUpper("Delete"), - "/:ueId/registrations/smsf-non-3gpp-access", - HTTPDeregistrationSmsfNon3gppAccess, - }, - - { - "GetSmsfNon3gppAccess", - strings.ToUpper("Get"), - "/:ueId/registrations/smsf-non-3gpp-access", - HTTPGetSmsfNon3gppAccess, - }, - - { - "UpdateSMSFReg3GPP", - strings.ToUpper("Put"), - "/:ueId/registrations/smsf-3gpp-access", - HTTPUpdateSMSFReg3GPP, - }, - - { - "RegistrationSmsfNon3gppAccess", - strings.ToUpper("Put"), - "/:ueId/registrations/smsf-non-3gpp-access", - HTTPRegistrationSmsfNon3gppAccess, - }, -} From 76c53ec5d5d71b00d4e7ace80e826ff05b884780 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Tue, 4 Jun 2024 07:32:42 +0000 Subject: [PATCH 15/23] fix: fix with PR comment --- internal/sbi/processor/processor.go | 6 ----- internal/sbi/router.go | 34 ----------------------------- pkg/service/init.go | 8 ------- 3 files changed, 48 deletions(-) diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go index 0e9cb79..b2e7aa4 100644 --- a/internal/sbi/processor/processor.go +++ b/internal/sbi/processor/processor.go @@ -16,12 +16,6 @@ type Processor struct { consumer *consumer.Consumer } -type HandlerResponse struct { - Status int - Headers map[string][]string - Body interface{} -} - func NewProcessor(udm ProcessorUdm) (*Processor, error) { p := &Processor{ ProcessorUdm: udm, diff --git a/internal/sbi/router.go b/internal/sbi/router.go index 4be6bdf..0e6288c 100644 --- a/internal/sbi/router.go +++ b/internal/sbi/router.go @@ -36,37 +36,3 @@ func AddService(group *gin.RouterGroup, routes []Route) { } } } - -func AddSDMService(group *gin.RouterGroup, routes []Route) { - 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) - } - } -} - -func AddUEAUService(group *gin.RouterGroup, routes []Route) { - 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) - } - } -} diff --git a/pkg/service/init.go b/pkg/service/init.go index f2cd7f4..3120809 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -18,8 +18,6 @@ import ( "github.com/free5gc/udm/pkg/factory" ) -var UDM *UdmApp - var _ app.App = &UdmApp{} type UdmApp struct { @@ -40,10 +38,6 @@ type UdmApp struct { processor *processor.Processor } -func GetApp() *UdmApp { - return UDM -} - func NewApp(ctx context.Context, cfg *factory.Config, tlsKeyLogPath string) (*UdmApp, error) { udm := &UdmApp{ cfg: cfg, @@ -73,8 +67,6 @@ func NewApp(ctx context.Context, cfg *factory.Config, tlsKeyLogPath string) (*Ud return nil, err } - UDM = udm - return udm, nil } From 6cf39c6da472c493812512c485d9ccf0387ea5ef Mon Sep 17 00:00:00 2001 From: ubuntu Date: Fri, 21 Jun 2024 10:56:57 +0000 Subject: [PATCH 16/23] fix: fix PR comment & terminate problem --- cmd/main.go | 1 - internal/sbi/consumer/nrf_service.go | 2 +- internal/sbi/consumer/udm_service.go | 2 +- internal/sbi/consumer/udr_service.go | 2 +- pkg/service/init.go | 44 ++++++++++++++-------------- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index e0a4aac..734725e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -74,7 +74,6 @@ func action(cliCtx *cli.Context) error { } udm.Start() - udm.WaitRoutineStopped() return nil } diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 57acc7e..3f5ec28 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -35,7 +35,7 @@ func (s *nnrfService) getNFManagementClient(uri string) *Nnrf_NFManagement.APICl s.nfMngmntMu.RLock() client, ok := s.nfMngmntClients[uri] if ok { - defer s.nfMngmntMu.RUnlock() + s.nfMngmntMu.RUnlock() return client } diff --git a/internal/sbi/consumer/udm_service.go b/internal/sbi/consumer/udm_service.go index 4d13846..4bb5109 100644 --- a/internal/sbi/consumer/udm_service.go +++ b/internal/sbi/consumer/udm_service.go @@ -24,7 +24,7 @@ func (s *nudmService) GetSDMClient(uri string) *Nudm_SubscriberDataManagement.AP s.nfSDMMu.RLock() client, ok := s.nfSDMClients[uri] if ok { - defer s.nfSDMMu.RUnlock() + s.nfSDMMu.RUnlock() return client } diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go index 4e768e2..7f7df94 100644 --- a/internal/sbi/consumer/udr_service.go +++ b/internal/sbi/consumer/udr_service.go @@ -34,7 +34,7 @@ func (s *nudrService) CreateUDMClientToUDR(id string) (*Nudr_DataRepository.APIC s.nfDRMu.RLock() client, ok := s.nfDRClients[uri] if ok { - defer s.nfDRMu.RUnlock() + s.nfDRMu.RUnlock() return client, nil } diff --git a/pkg/service/init.go b/pkg/service/init.go index 3120809..a844682 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -21,11 +21,6 @@ import ( var _ app.App = &UdmApp{} type UdmApp struct { - app.App - consumer.ConsumerUdm - processor.ProcessorUdm - sbi.ServerUdm - udmCtx *udm_context.UDMContext cfg *factory.Config @@ -120,23 +115,8 @@ func (a *UdmApp) Start() { if err := a.sbiServer.Run(context.Background(), &a.wg); err != nil { logger.MainLog.Fatalf("Run SBI server failed: %+v", err) } -} -func (a *UdmApp) Terminate() { - logger.MainLog.Infof("Terminating UDM...") - a.cancel() - a.CallServerStop() - - // deregister with NRF - problemDetails, err := a.Consumer().SendDeregisterNFInstance() - if problemDetails != nil { - logger.MainLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails) - } else if err != nil { - logger.MainLog.Errorf("Deregister NF instance Error[%+v]", err) - } else { - logger.MainLog.Infof("Deregister from NRF successfully") - } - logger.MainLog.Infof("UDM SBI Server terminated") + a.WaitRoutineStopped() } func (a *UdmApp) listenShutdownEvent() { @@ -149,7 +129,7 @@ func (a *UdmApp) listenShutdownEvent() { }() <-a.ctx.Done() - a.Terminate() + a.terminateProcedure() } func (a *UdmApp) CallServerStop() { @@ -158,6 +138,26 @@ func (a *UdmApp) CallServerStop() { } } +func (a *UdmApp) Terminate() { + a.cancel() +} + +func (a *UdmApp) terminateProcedure() { + logger.MainLog.Infof("Terminating UDM...") + a.CallServerStop() + + // deregister with NRF + problemDetails, err := a.Consumer().SendDeregisterNFInstance() + if problemDetails != nil { + logger.MainLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails) + } else if err != nil { + logger.MainLog.Errorf("Deregister NF instance Error[%+v]", err) + } else { + logger.MainLog.Infof("Deregister from NRF successfully") + } + logger.MainLog.Infof("UDM SBI Server terminated") +} + func (a *UdmApp) WaitRoutineStopped() { a.wg.Wait() logger.MainLog.Infof("UDM App is terminated") From 2d138caa89f5eae9ca4e04435d4d0a8e4214833b Mon Sep 17 00:00:00 2001 From: ubuntu Date: Mon, 24 Jun 2024 05:52:28 +0000 Subject: [PATCH 17/23] fix: fix PR comment --- internal/sbi/api_uecontextmanagement.go | 12 ++++++------ internal/sbi/processor/{callback.go => notifier.go} | 0 internal/sbi/server.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) rename internal/sbi/processor/{callback.go => notifier.go} (100%) diff --git a/internal/sbi/api_uecontextmanagement.go b/internal/sbi/api_uecontextmanagement.go index 00b6cc7..2b38941 100644 --- a/internal/sbi/api_uecontextmanagement.go +++ b/internal/sbi/api_uecontextmanagement.go @@ -377,32 +377,32 @@ func (s *Server) HandleUpdateAmf3gppAccess(c *gin.Context) { // DeregistrationSmsfNon3gppAccess - delete SMSF registration for non 3GPP access func (s *Server) HandleDeregistrationSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // DeregistrationSmsf3gppAccess - delete the SMSF registration for 3GPP access func (s *Server) HandleDeregistrationSmsf3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // GetSmsfNon3gppAccess - retrieve the SMSF registration for non-3GPP access information func (s *Server) HandleGetSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // RegistrationSmsfNon3gppAccess - register as SMSF for non-3GPP access func (s *Server) HandleRegistrationSmsfNon3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // UpdateSMSFReg3GPP - register as SMSF for 3GPP access func (s *Server) HandleUpdateSMSFReg3GPP(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // GetSmsf3gppAccess - retrieve the SMSF registration for 3GPP access information func (s *Server) HandleGetSmsf3gppAccess(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // DeregistrationSmfRegistrations - delete an SMF registration 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/server.go b/internal/sbi/server.go index 2a7c342..2ec1225 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -102,7 +102,7 @@ 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.Info("SBI server (listen on %s) stopped", s.httpServer.Addr) } func (s *Server) Shutdown() { @@ -146,7 +146,7 @@ func newRouter(s *Server) *gin.Engine { udmEEGroup := s.router.Group(factory.UdmEeResUriPrefix) routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NUDM_EE) udmEEGroup.Use(func(c *gin.Context) { - routerAuthorizationCheck.Check(c, udm_context.GetSelf()) + routerAuthorizationCheck.Check(c, s.Context()) }) AddService(udmEEGroup, udmEERoutes) From 0465bd4de2b09f65f252bf2bcf0c5c0352400107 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Mon, 24 Jun 2024 05:55:15 +0000 Subject: [PATCH 18/23] fix: fix log --- internal/sbi/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 2ec1225..86a8e7f 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -102,7 +102,7 @@ func (s *Server) startServer(wg *sync.WaitGroup) { if err != nil && err != http.ErrServerClosed { logger.SBILog.Errorf("SBI server error: %v", err) } - logger.SBILog.Info("SBI server (listen on %s) stopped", s.httpServer.Addr) + logger.SBILog.Infof("SBI server (listen on %s) stopped", s.httpServer.Addr) } func (s *Server) Shutdown() { From 4e578fd2e6e5c4bf4e4357dad4595181a1c43dc5 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Tue, 25 Jun 2024 07:50:25 +0000 Subject: [PATCH 19/23] fix: fix wrong file name & fix implementation of processor follow standard --- internal/sbi/api_eventexposure.go | 29 +- internal/sbi/api_httpcallback.go | 11 +- internal/sbi/api_parameterprovision.go | 11 +- internal/sbi/api_subscriberdatamanagement.go | 274 +----------- internal/sbi/api_ueauthentication.go | 29 +- internal/sbi/api_uecontextmanagement.go | 131 +----- .../{enent_exposure.go => event_exposure.go} | 46 +- internal/sbi/processor/generate_auth_data.go | 117 ++++-- internal/sbi/processor/notifier.go | 11 +- internal/sbi/processor/parameter_provision.go | 23 +- .../processor/subscriber_data_management.go | 396 ++++++++++-------- .../sbi/processor/ue_context_management.go | 188 +++++---- 12 files changed, 489 insertions(+), 777 deletions(-) rename internal/sbi/processor/{enent_exposure.go => event_exposure.go} (83%) diff --git a/internal/sbi/api_eventexposure.go b/internal/sbi/api_eventexposure.go index 056b0df..1c0290e 100644 --- a/internal/sbi/api_eventexposure.go +++ b/internal/sbi/api_eventexposure.go @@ -78,30 +78,14 @@ func (s *Server) HandleCreateEeSubscription(c *gin.Context) { ueIdentity := c.Params.ByName("ueIdentity") - createdEESubscription, problemDetails := s.Processor().CreateEeSubscriptionProcedure(ueIdentity, eesubscription) - if createdEESubscription != nil { - c.JSON(http.StatusCreated, createdEESubscription) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "UNSPECIFIED_NF_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetails) - return - } + s.Processor().CreateEeSubscriptionProcedure(c, ueIdentity, eesubscription) } func (s *Server) HandleDeleteEeSubscription(c *gin.Context) { ueIdentity := c.Params.ByName("ueIdentity") subscriptionID := c.Params.ByName("subscriptionId") - s.Processor().DeleteEeSubscriptionProcedure(ueIdentity, subscriptionID) - // only return 204 no content - c.Status(http.StatusNoContent) + s.Processor().DeleteEeSubscriptionProcedure(c, ueIdentity, subscriptionID) } func (s *Server) HandleUpdateEeSubscription(c *gin.Context) { @@ -139,14 +123,7 @@ func (s *Server) HandleUpdateEeSubscription(c *gin.Context) { logger.EeLog.Infoln("Handle Update EE subscription") logger.EeLog.Warnln("Update EE Subscription is not implemented") - problemDetails := s.Processor().UpdateEeSubscriptionProcedure(ueIdentity, subscriptionID, patchList) - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().UpdateEeSubscriptionProcedure(c, ueIdentity, subscriptionID, patchList) } func (s *Server) HandleIndex(c *gin.Context) { diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index b07e2b1..1f3d558 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -63,14 +63,5 @@ func (s *Server) HandleDataChangeNotificationToNF(c *gin.Context) { logger.CallbackLog.Infof("Handle DataChangeNotificationToNF") - problemDetails := s.Processor().DataChangeNotificationProcedure(dataChangeNotify.NotifyItems, supi) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().DataChangeNotificationProcedure(c, dataChangeNotify.NotifyItems, supi) } diff --git a/internal/sbi/api_parameterprovision.go b/internal/sbi/api_parameterprovision.go index b272ec6..7badc40 100644 --- a/internal/sbi/api_parameterprovision.go +++ b/internal/sbi/api_parameterprovision.go @@ -65,14 +65,5 @@ func (s *Server) HandleUpdate(c *gin.Context) { logger.PpLog.Infoln("Handle UpdateRequest") // step 3: handle the message - problemDetails := s.Processor().UpdateProcedure(ppDataReq, gpsi) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().UpdateProcedure(c, ppDataReq, gpsi) } diff --git a/internal/sbi/api_subscriberdatamanagement.go b/internal/sbi/api_subscriberdatamanagement.go index 26392ff..547b684 100644 --- a/internal/sbi/api_subscriberdatamanagement.go +++ b/internal/sbi/api_subscriberdatamanagement.go @@ -45,24 +45,7 @@ func (s *Server) HandleGetAmData(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetAmDataProcedure(supi, plmnID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetAmDataProcedure(c, supi, plmnID, supportedFeatures) } func (s *Server) getPlmnIDStruct( @@ -116,24 +99,7 @@ func (s *Server) HandleGetSmfSelectData(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetSmfSelectDataProcedure(supi, plmnID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetSmfSelectDataProcedure(c, supi, plmnID, supportedFeatures) } // GetSmsMngData - retrieve a UE's SMS Management Subscription Data @@ -168,24 +134,7 @@ func (s *Server) HandleGetSupi(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetSupiProcedure(supi, plmnID, dataSetNames, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetSupiProcedure(c, supi, plmnID, dataSetNames, supportedFeatures) } // GetSharedData - retrieve shared data @@ -197,24 +146,7 @@ func (s *Server) HandleGetSharedData(c *gin.Context) { sharedDataIds := c.QueryArray("shared-data-ids") supportedFeatures := c.QueryArray("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetSharedDataProcedure(sharedDataIds, supportedFeatures[0]) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetSharedDataProcedure(c, sharedDataIds, supportedFeatures[0]) } // SubscribeToSharedData - subscribe to notifications for shared data @@ -254,30 +186,7 @@ func (s *Server) HandleSubscribeToSharedData(c *gin.Context) { // step 2: retrieve request // step 3: handle the message - header, response, problemDetails := s.Processor().SubscribeToSharedDataProcedure(&sharedDataSubsReq) - - // var rsp *httpwrapper.Response - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - // step 5: response - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - return - } + s.Processor().SubscribeToSharedDataProcedure(c, &sharedDataSubsReq) } // Subscribe - subscribe to notifications @@ -319,23 +228,7 @@ func (s *Server) HandleSubscribe(c *gin.Context) { supi := c.Params.ByName("supi") // step 3: handle the message - header, response, problemDetails := s.Processor().SubscribeProcedure(&sdmSubscriptionReq, supi) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNotFound) - return - } + s.Processor().SubscribeProcedure(c, &sdmSubscriptionReq, supi) } // Unsubscribe - unsubscribe from notifications @@ -347,16 +240,7 @@ func (s *Server) HandleUnsubscribe(c *gin.Context) { subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - problemDetails := s.Processor().UnsubscribeProcedure(supi, subscriptionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().UnsubscribeProcedure(c, supi, subscriptionID) } // UnsubscribeForSharedData - unsubscribe from notifications for shared data @@ -366,16 +250,7 @@ func (s *Server) HandleUnsubscribeForSharedData(c *gin.Context) { // step 2: retrieve request subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - problemDetails := s.Processor().UnsubscribeForSharedDataProcedure(subscriptionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().UnsubscribeForSharedDataProcedure(c, subscriptionID) } // Modify - modify the subscription @@ -417,24 +292,7 @@ func (s *Server) HandleModify(c *gin.Context) { subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - response, problemDetails := s.Processor().ModifyProcedure(&sdmSubsModificationReq, supi, subscriptionID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().ModifyProcedure(c, &sdmSubsModificationReq, supi, subscriptionID) } // ModifyForSharedData - modify the subscription @@ -476,24 +334,7 @@ func (s *Server) HandleModifyForSharedData(c *gin.Context) { subscriptionID := c.Params.ByName("subscriptionId") // step 3: handle the message - response, problemDetails := s.Processor().ModifyForSharedDataProcedure(&sharedDataSubscriptions, supi, subscriptionID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().ModifyForSharedDataProcedure(c, &sharedDataSubscriptions, supi, subscriptionID) } // GetTraceData - retrieve a UE's Trace Configuration Data @@ -506,24 +347,7 @@ func (s *Server) HandleGetTraceData(c *gin.Context) { plmnID := c.Query("plmn-id") // step 3: handle the message - response, problemDetails := s.Processor().GetTraceDataProcedure(supi, plmnID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetTraceDataProcedure(c, supi, plmnID) } // GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data @@ -536,24 +360,7 @@ func (s *Server) HandleGetUeContextInSmfData(c *gin.Context) { supportedFeatures := c.Query("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetUeContextInSmfDataProcedure(supi, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetUeContextInSmfDataProcedure(c, supi, supportedFeatures) } // GetUeContextInSmsfData - retrieve a UE's UE Context In SMSF Data @@ -581,24 +388,7 @@ func (s *Server) HandleGetNssai(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetNssaiProcedure(supi, plmnID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetNssaiProcedure(c, supi, plmnID, supportedFeatures) } // GetSmData - retrieve a UE's Session Management Subscription Data @@ -625,24 +415,7 @@ func (s *Server) HandleGetSmData(c *gin.Context) { supportedFeatures := query.Get("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetSmDataProcedure(supi, plmnID, Dnn, Snssai, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetSmDataProcedure(c, supi, plmnID, Dnn, Snssai, supportedFeatures) } // GetIdTranslationResult - retrieve a UE's SUPI @@ -656,24 +429,7 @@ func (s *Server) HandleGetIdTranslationResult(c *gin.Context) { gpsi := c.Params.ByName("gpsi") // step 3: handle the message - response, problemDetails := s.Processor().GetIdTranslationResultProcedure(gpsi) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetIdTranslationResultProcedure(c, gpsi) } func (s *Server) OneLayerPathHandlerFunc(c *gin.Context) { diff --git a/internal/sbi/api_ueauthentication.go b/internal/sbi/api_ueauthentication.go index 8fa5017..2f7910e 100644 --- a/internal/sbi/api_ueauthentication.go +++ b/internal/sbi/api_ueauthentication.go @@ -64,15 +64,7 @@ func (s *Server) HandleConfirmAuth(c *gin.Context) { logger.UeauLog.Infoln("Handle ConfirmAuthDataRequest") - problemDetails := s.Processor().ConfirmAuthDataProcedure(authEvent, supi) - - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusCreated) - return - } + s.Processor().ConfirmAuthDataProcedure(c, authEvent, supi) } // GenerateAuthData - Generate authentication data for the UE @@ -114,24 +106,7 @@ func (s *Server) HandleGenerateAuthData(c *gin.Context) { supiOrSuci := c.Param("supiOrSuci") // step 3: handle the message - response, problemDetails := s.Processor().GenerateAuthDataProcedure(authInfoReq, supiOrSuci) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GenerateAuthDataProcedure(c, authInfoReq, supiOrSuci) } func (s *Server) GenAuthDataHandlerFunc(c *gin.Context) { diff --git a/internal/sbi/api_uecontextmanagement.go b/internal/sbi/api_uecontextmanagement.go index 2b38941..b17a989 100644 --- a/internal/sbi/api_uecontextmanagement.go +++ b/internal/sbi/api_uecontextmanagement.go @@ -135,24 +135,7 @@ func (s *Server) HandleGetAmfNon3gppAccess(c *gin.Context) { queryAmfContextNon3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) // step 3: handle the message - response, problemDetails := s.Processor().GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts, ueId) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetAmfNon3gppAccessProcedure(c, queryAmfContextNon3gppParamOpts, ueId) } // Register - register as AMF for non-3GPP access @@ -193,23 +176,7 @@ func (s *Server) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { ueID := c.Param("ueId") // step 3: handle the message - header, response, problemDetails := s.Processor().RegisterAmfNon3gppAccessProcedure(amfNon3GppAccessRegistration, ueID) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().RegisterAmfNon3gppAccessProcedure(c, amfNon3GppAccessRegistration, ueID) } // RegistrationAmf3gppAccess - register as AMF for 3GPP access @@ -251,27 +218,7 @@ func (s *Server) HandleRegistrationAmf3gppAccess(c *gin.Context) { logger.UecmLog.Info("UEID: ", ueID) // step 3: handle the message - header, response, problemDetails := s.Processor().RegistrationAmf3gppAccessProcedure(amf3GppAccessRegistration, ueID) - - // step 4: process the return value from step 3 - if response != nil { - if header != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().RegistrationAmf3gppAccessProcedure(c, amf3GppAccessRegistration, ueID) } // UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access @@ -312,16 +259,7 @@ func (s *Server) HandleUpdateAmfNon3gppAccess(c *gin.Context) { ueID := c.Param("ueId") // step 3: handle the message - problemDetails := s.Processor().UpdateAmfNon3gppAccessProcedure(amfNon3GppAccessRegistrationModification, ueID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().UpdateAmfNon3gppAccessProcedure(c, amfNon3GppAccessRegistrationModification, ueID) } // UpdateAmf3gppAccess - Update a parameter in the AMF registration for 3GPP access @@ -363,16 +301,7 @@ func (s *Server) HandleUpdateAmf3gppAccess(c *gin.Context) { ueID := c.Param("ueId") // step 3: handle the message - problemDetails := s.Processor().UpdateAmf3gppAccessProcedure(amf3GppAccessRegistrationModification, ueID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().UpdateAmf3gppAccessProcedure(c, amf3GppAccessRegistrationModification, ueID) } // DeregistrationSmsfNon3gppAccess - delete SMSF registration for non 3GPP access @@ -415,16 +344,7 @@ func (s *Server) HandleDeregistrationSmfRegistrations(c *gin.Context) { pduSessionID := c.Params.ByName("pduSessionId") // step 3: handle the message - problemDetails := s.Processor().DeregistrationSmfRegistrationsProcedure(ueID, pduSessionID) - - // step 4: process the return value from step 3 - if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - c.Status(http.StatusNoContent) - return - } + s.Processor().DeregistrationSmfRegistrationsProcedure(c, ueID, pduSessionID) } // RegistrationSmfRegistrations - register as SMF @@ -467,28 +387,12 @@ func (s *Server) HandleRegistrationSmfRegistrations(c *gin.Context) { pduSessionID := c.Params.ByName("pduSessionId") // step 3: handle the message - header, response, problemDetails := s.Processor().RegistrationSmfRegistrationsProcedure( + s.Processor().RegistrationSmfRegistrationsProcedure( + c, &smfRegistration, ueID, pduSessionID, ) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - // all nil - c.Status(http.StatusNoContent) - return - } } // GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information @@ -501,22 +405,5 @@ func (s *Server) HandleGetAmf3gppAccess(c *gin.Context) { supportedFeatures := c.Query("supported-features") // step 3: handle the message - response, problemDetails := s.Processor().GetAmf3gppAccessProcedure(ueID, supportedFeatures) - - // step 4: process the return value from step 3 - if response != nil { - // status code is based on SPEC, and option headers - c.JSON(http.StatusOK, response) - return - } else if problemDetails != nil { - c.JSON(int(problemDetails.Status), problemDetails) - return - } else { - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", - } - c.JSON(http.StatusForbidden, problemDetails) - return - } + s.Processor().GetAmf3gppAccessProcedure(c, ueID, supportedFeatures) } diff --git a/internal/sbi/processor/enent_exposure.go b/internal/sbi/processor/event_exposure.go similarity index 83% rename from internal/sbi/processor/enent_exposure.go rename to internal/sbi/processor/event_exposure.go index 9f8e2b1..19d8105 100644 --- a/internal/sbi/processor/enent_exposure.go +++ b/internal/sbi/processor/event_exposure.go @@ -5,15 +5,17 @@ import ( "strconv" "strings" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" ) // EE service -func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, +func (p *Processor) CreateEeSubscriptionProcedure(c *gin.Context, ueIdentity string, eesubscription models.EeSubscription, -) (*models.CreatedEeSubscription, *models.ProblemDetails) { +) { udmSelf := udm_context.GetSelf() logger.EeLog.Debugf("udIdentity: %s", ueIdentity) switch { @@ -29,7 +31,8 @@ func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, Status: http.StatusInternalServerError, Cause: "UNSPECIFIED_NF_FAILURE", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } subscriptionID := strconv.Itoa(int(id)) @@ -37,13 +40,13 @@ func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, createdEeSubscription := &models.CreatedEeSubscription{ EeSubscription: &eesubscription, } - return createdEeSubscription, nil + c.JSON(http.StatusCreated, createdEeSubscription) } else { problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "USER_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } // external groupID represents a group of UEs case strings.HasPrefix(ueIdentity, "extgroupid-"): @@ -53,7 +56,8 @@ func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, Status: http.StatusInternalServerError, Cause: "UNSPECIFIED_NF_FAILURE", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } subscriptionID := strconv.Itoa(int(id)) createdEeSubscription := &models.CreatedEeSubscription{ @@ -67,7 +71,7 @@ func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, } return true }) - return createdEeSubscription, nil + c.JSON(http.StatusCreated, createdEeSubscription) // represents any UEs case ueIdentity == "anyUE": id, err := udmSelf.EeSubscriptionIDGenerator.Allocate() @@ -76,7 +80,8 @@ func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, Status: http.StatusInternalServerError, Cause: "UNSPECIFIED_NF_FAILURE", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } subscriptionID := strconv.Itoa(int(id)) createdEeSubscription := &models.CreatedEeSubscription{ @@ -87,7 +92,7 @@ func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, ue.EeSubscriptions[subscriptionID] = &eesubscription return true }) - return createdEeSubscription, nil + c.JSON(http.StatusCreated, createdEeSubscription) default: problemDetails := &models.ProblemDetails{ Status: http.StatusBadRequest, @@ -99,12 +104,12 @@ func (p *Processor) CreateEeSubscriptionProcedure(ueIdentity string, }, }, } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } // TODO: complete this procedure based on TS 29503 5.5 -func (p *Processor) DeleteEeSubscriptionProcedure(ueIdentity string, subscriptionID string) { +func (p *Processor) DeleteEeSubscriptionProcedure(c *gin.Context, ueIdentity string, subscriptionID string) { udmSelf := udm_context.GetSelf() switch { @@ -134,12 +139,15 @@ func (p *Processor) DeleteEeSubscriptionProcedure(ueIdentity string, subscriptio } else { udmSelf.EeSubscriptionIDGenerator.FreeID(id) } + + // only return 204 no content + c.Status(http.StatusNoContent) } // TODO: complete this procedure based on TS 29503 5.5 -func (p *Processor) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptionID string, +func (p *Processor) UpdateEeSubscriptionProcedure(c *gin.Context, ueIdentity string, subscriptionID string, patchList []models.PatchItem, -) *models.ProblemDetails { +) { udmSelf := udm_context.GetSelf() switch { @@ -152,20 +160,20 @@ func (p *Processor) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptio logger.EeLog.Debugf("patch item: %+v", patchItem) // TODO: patch the Eesubscription } - return nil + c.Status(http.StatusNoContent) } else { problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "SUBSCRIPTION_NOT_FOUND", } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } else { problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "SUBSCRIPTION_NOT_FOUND", } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } case strings.HasPrefix(ueIdentity, "extgroupid-"): udmSelf.UdmUePool.Range(func(key, value interface{}) bool { @@ -180,7 +188,7 @@ func (p *Processor) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptio } return true }) - return nil + c.Status(http.StatusNoContent) case ueIdentity == "anyUE": udmSelf.UdmUePool.Range(func(key, value interface{}) bool { ue := value.(*udm_context.UdmUeContext) @@ -192,7 +200,7 @@ func (p *Processor) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptio } return true }) - return nil + c.Status(http.StatusNoContent) default: problemDetails := &models.ProblemDetails{ Status: http.StatusBadRequest, @@ -204,6 +212,6 @@ func (p *Processor) UpdateEeSubscriptionProcedure(ueIdentity string, subscriptio }, }, } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } diff --git a/internal/sbi/processor/generate_auth_data.go b/internal/sbi/processor/generate_auth_data.go index 87c88fa..44f58db 100644 --- a/internal/sbi/processor/generate_auth_data.go +++ b/internal/sbi/processor/generate_auth_data.go @@ -13,6 +13,7 @@ import ( "time" "github.com/antihax/optional" + "github.com/gin-gonic/gin" "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudr_DataRepository" @@ -76,13 +77,14 @@ func (p *Processor) strictHex(ss string, n int) string { } } -func (p *Processor) ConfirmAuthDataProcedure( +func (p *Processor) ConfirmAuthDataProcedure(c *gin.Context, authEvent models.AuthEvent, supi string, -) (problemDetails *models.ProblemDetails) { +) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } var createAuthParam Nudr_DataRepository.CreateAuthenticationStatusParamOpts optInterface := optional.NewInterface(authEvent) @@ -90,20 +92,23 @@ func (p *Processor) ConfirmAuthDataProcedure( client, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } resp, err := client.AuthenticationStatusDocumentApi.CreateAuthenticationStatus( ctx, supi, &createAuthParam) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } logger.UeauLog.Errorln("ConfirmAuth err:", err.Error()) - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -111,41 +116,47 @@ func (p *Processor) ConfirmAuthDataProcedure( } }() - return nil + c.Status(http.StatusCreated) } -func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.AuthenticationInfoRequest, supiOrSuci string) ( - response *models.AuthenticationInfoResult, problemDetails *models.ProblemDetails, +func (p *Processor) GenerateAuthDataProcedure( + c *gin.Context, + authInfoRequest models.AuthenticationInfoRequest, + supiOrSuci string, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } logger.UeauLog.Traceln("In GenerateAuthDataProcedure") - response = &models.AuthenticationInfoResult{} + response := &models.AuthenticationInfoResult{} rand.New(rand.NewSource(time.Now().UnixNano())) supi, err := suci.ToSupi(supiOrSuci, udm_context.GetSelf().SuciProfiles) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: err.Error(), } logger.UeauLog.Errorln("suciToSupi error: ", err.Error()) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } logger.UeauLog.Tracef("supi conversion => [%s]", supi) client, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } authSubs, res, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(ctx, supi, nil) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: err.Error(), @@ -157,7 +168,8 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat default: logger.UeauLog.Errorln("Return from UDR QueryAuthSubsData error") } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := res.Body.Close(); rspCloseErr != nil { @@ -185,22 +197,24 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat hasK = true } } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, } logger.UeauLog.Errorln("kStr length is ", len(kStr)) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, } logger.UeauLog.Errorln("Nil PermanentKey") - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } if authSubs.Milenage != nil { @@ -220,13 +234,14 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat logger.UeauLog.Infoln("Nil Op") } } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, } logger.UeauLog.Infoln("Nil Milenage") - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } if authSubs.Opc != nil && authSubs.Opc.OpcValue != "" { @@ -246,12 +261,12 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat } if !hasOPC && !hasOP { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } if !hasOPC { @@ -261,13 +276,14 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat logger.UeauLog.Errorln("milenage GenerateOPC err:", err) } } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, } logger.UeauLog.Errorln("Unable to derive OPC") - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } @@ -275,14 +291,15 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat logger.UeauLog.Traceln("sqnStr", sqnStr) sqn, err := hex.DecodeString(sqnStr) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: err.Error(), } logger.UeauLog.Errorln("err:", err) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } logger.UeauLog.Tracef("K=[%x], sqn=[%x], OP=[%x], OPC=[%x]", k, sqn, op, opc) @@ -290,28 +307,30 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat RAND := make([]byte, 16) _, err = cryptoRand.Read(RAND) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: err.Error(), } logger.UeauLog.Errorln("err:", err) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } amfStr := p.strictHex(authSubs.AuthenticationManagementField, 4) logger.UeauLog.Traceln("amfStr", amfStr) AMF, err := hex.DecodeString(amfStr) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: err.Error(), } logger.UeauLog.Errorln("err:", err) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } logger.UeauLog.Tracef("RAND=[%x], AMF=[%x]", RAND, AMF) @@ -322,40 +341,43 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat Auts, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Auts) if deCodeErr != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: deCodeErr.Error(), } logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } randHex, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Rand) if deCodeErr != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: deCodeErr.Error(), } logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } SQNms, macS := p.aucSQN(opc, k, Auts, randHex) if reflect.DeepEqual(macS, Auts[6:]) { _, err = cryptoRand.Read(RAND) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: deCodeErr.Error(), } logger.UeauLog.Errorln("err:", deCodeErr) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } // increment sqn authSubs.SequenceNumber @@ -393,11 +415,12 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat logger.UeauLog.Errorln("MACS ", macS) logger.UeauLog.Errorln("Auts[6:] ", Auts[6:]) logger.UeauLog.Errorln("Sqn ", SQNms) - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "modification is rejected", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } @@ -405,14 +428,15 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat bigSQN := big.NewInt(0) sqn, err = hex.DecodeString(sqnStr) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: authenticationRejected, Detail: err.Error(), } logger.UeauLog.Errorln("err:", err) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } bigSQN.SetString(sqnStr, 16) @@ -435,14 +459,15 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat rsp, err = client.AuthenticationDataDocumentApi.ModifyAuthentication( ctx, supi, patchItemArray) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "modification is rejected ", Detail: err.Error(), } logger.UeauLog.Errorln("update sqn error:", err) - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := rsp.Body.Close(); rspCloseErr != nil { @@ -549,5 +574,5 @@ func (p *Processor) GenerateAuthDataProcedure(authInfoRequest models.Authenticat response.AuthenticationVector = &av response.Supi = supi - return response, nil + c.JSON(http.StatusOK, response) } diff --git a/internal/sbi/processor/notifier.go b/internal/sbi/processor/notifier.go index b2ab1bb..9c09b62 100644 --- a/internal/sbi/processor/notifier.go +++ b/internal/sbi/processor/notifier.go @@ -3,18 +3,21 @@ package processor import ( "net/http" + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi/models" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" ) -func (p *Processor) DataChangeNotificationProcedure( +func (p *Processor) DataChangeNotificationProcedure(c *gin.Context, notifyItems []models.NotifyItem, supi string, -) *models.ProblemDetails { +) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } ue, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) @@ -52,7 +55,7 @@ func (p *Processor) DataChangeNotificationProcedure( }() } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } func (p *Processor) SendOnDeregistrationNotification(ueId string, onDeregistrationNotificationUrl string, diff --git a/internal/sbi/processor/parameter_provision.go b/internal/sbi/processor/parameter_provision.go index f6f9fb1..9ed4270 100644 --- a/internal/sbi/processor/parameter_provision.go +++ b/internal/sbi/processor/parameter_provision.go @@ -1,37 +1,46 @@ package processor import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" ) -func (p *Processor) UpdateProcedure( +func (p *Processor) UpdateProcedure(c *gin.Context, updateRequest models.PpData, gpsi string, -) (problemDetails *models.ProblemDetails) { +) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR(gpsi) if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } + res, err := clientAPI.ProvisionedParameterDataDocumentApi.ModifyPpData(ctx, gpsi, nil) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := res.Body.Close(); rspCloseErr != nil { logger.PpLog.Errorf("ModifyPpData response body cannot close: %+v", rspCloseErr) } }() - return nil + c.Status(http.StatusNoContent) } diff --git a/internal/sbi/processor/subscriber_data_management.go b/internal/sbi/processor/subscriber_data_management.go index 0ca3e37..316f016 100644 --- a/internal/sbi/processor/subscriber_data_management.go +++ b/internal/sbi/processor/subscriber_data_management.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/antihax/optional" + "github.com/gin-gonic/gin" "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudr_DataRepository" @@ -13,19 +14,20 @@ import ( "github.com/free5gc/udm/internal/logger" ) -func (p *Processor) GetAmDataProcedure(supi string, plmnID string, supportedFeatures string) ( - response *models.AccessAndMobilitySubscriptionData, problemDetails *models.ProblemDetails, -) { +func (p *Processor) GetAmDataProcedure(c *gin.Context, supi string, plmnID string, supportedFeatures string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. @@ -36,12 +38,13 @@ func (p *Processor) GetAmDataProcedure(supi string, plmnID string, supportedFeat } else if err.Error() != res.Status { logger.SdmLog.Errorf("Response State: %+v", err.Error()) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -56,29 +59,29 @@ func (p *Processor) GetAmDataProcedure(supi string, plmnID string, supportedFeat udmUe = udm_context.GetSelf().NewUdmUe(supi) } udmUe.SetAMSubsriptionData(&accessAndMobilitySubscriptionDataResp) - return &accessAndMobilitySubscriptionDataResp, nil + c.JSON(http.StatusOK, accessAndMobilitySubscriptionDataResp) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) GetIdTranslationResultProcedure(gpsi string) (response *models.IdTranslationResult, - problemDetails *models.ProblemDetails, -) { +func (p *Processor) GetIdTranslationResultProcedure(c *gin.Context, gpsi string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) } var idTranslationResult models.IdTranslationResult var getIdentityDataParamOpts Nudr_DataRepository.GetIdentityDataParamOpts clientAPI, err := p.consumer.CreateUDMClientToUDR(gpsi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } idTranslationResultResp, res, err := clientAPI.QueryIdentityDataBySUPIOrGPSIDocumentApi.GetIdentityData( @@ -89,13 +92,13 @@ func (p *Processor) GetIdTranslationResultProcedure(gpsi string) (response *mode } else if err.Error() != res.Status { logger.SdmLog.Errorf("Response State: %+v", err.Error()) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -109,45 +112,49 @@ func (p *Processor) GetIdTranslationResultProcedure(gpsi string) (response *mode // GetCorrespondingSupi get corresponding Supi(here IMSI) matching the given Gpsi from the queried SUPI list from UDR idTranslationResult.Supi = udm_context.GetCorrespondingSupi(idList) idTranslationResult.Gpsi = gpsi - - return &idTranslationResult, nil + c.JSON(http.StatusOK, idTranslationResult) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "USER_NOT_FOUND", } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames []string, supportedFeatures string) ( - response *models.SubscriptionDataSets, problemDetails *models.ProblemDetails, +func (p *Processor) GetSupiProcedure(c *gin.Context, + supi string, + plmnID string, + dataSetNames []string, + supportedFeatures string, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } if len(dataSetNames) < 2 { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusBadRequest, Cause: "BAD_REQUEST", Detail: "datasetNames must have at least 2 elements", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } var subscriptionDataSets, subsDataSetBody models.SubscriptionDataSets @@ -177,13 +184,14 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] } else if err.Error() != res.Status { logger.SdmLog.Errorf("Response State: %+v", err.Error()) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -199,12 +207,13 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] udmUe.SetAMSubsriptionData(&amData) subscriptionDataSets.AmData = &amData } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } @@ -220,13 +229,14 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] } else if err.Error() != res.Status { logger.SdmLog.Errorln(err.Error()) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -242,12 +252,13 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] udmUe.SetSmfSelectionSubsData(&smfSelData) subscriptionDataSets.SmfSelData = &smfSelData } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } @@ -265,13 +276,14 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] } else if err.Error() != res.Status { logger.SdmLog.Errorf("Response State: %+v", err.Error()) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -329,13 +341,14 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] } else if err.Error() != res.Status { logger.SdmLog.Errorf("Response State: %+v", err.Error()) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -352,12 +365,13 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] udmUe.SetSMSubsData(smData) subscriptionDataSets.SmData = sessionManagementSubscriptionData } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } @@ -373,13 +387,17 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] } else if err.Error() != res.Status { logger.SdmLog.Errorf("Response State: %+v", err.Error()) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } + c.JSON(int(problemDetails.Status), problemDetails) + return } - return nil, problemDetails + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := res.Body.Close(); rspCloseErr != nil { @@ -395,12 +413,13 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] udmUe.TraceDataResponse.TraceData = &traceData subscriptionDataSets.TraceData = &traceData } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } @@ -408,19 +427,20 @@ func (p *Processor) GetSupiProcedure(supi string, plmnID string, dataSetNames [] // if containDataSetName(dataSetNames, string(models.DataSetName_SMS_MNG)) { // } - return &subscriptionDataSets, nil + c.JSON(http.StatusOK, subscriptionDataSets) } -func (p *Processor) GetSharedDataProcedure(sharedDataIds []string, supportedFeatures string) ( - response []models.SharedData, problemDetails *models.ProblemDetails, -) { +func (p *Processor) GetSharedDataProcedure(c *gin.Context, sharedDataIds []string, supportedFeatures string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR("") if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } var getSharedDataParamOpts Nudr_DataRepository.GetSharedDataParamOpts @@ -435,13 +455,14 @@ func (p *Processor) GetSharedDataProcedure(sharedDataIds []string, supportedFeat logger.SdmLog.Warnln(err) } else { logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -453,34 +474,35 @@ func (p *Processor) GetSharedDataProcedure(sharedDataIds []string, supportedFeat if res.StatusCode == http.StatusOK { udm_context.GetSelf().SharedSubsDataMap = udm_context.MappingSharedData(sharedDataResp) sharedData := udm_context.ObtainRequiredSharedData(sharedDataIds, sharedDataResp) - return sharedData, nil + c.JSON(http.StatusOK, sharedData) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } func (p *Processor) GetSmDataProcedure( + c *gin.Context, supi string, plmnID string, Dnn string, Snssai string, supportedFeatures string, -) ( - response interface{}, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) } logger.SdmLog.Infof("getSmDataProcedure: SUPI[%s] PLMNID[%s] DNN[%s] SNssai[%s]", supi, plmnID, Dnn, Snssai) clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } var querySmDataParamOpts Nudr_DataRepository.QuerySmDataParamOpts @@ -495,13 +517,13 @@ func (p *Processor) GetSmDataProcedure( logger.SdmLog.Warnln(err) } else { logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -529,43 +551,44 @@ func (p *Processor) GetSmDataProcedure( switch { case Snssai == "" && Dnn == "": - return AllDnns, nil + c.JSON(http.StatusOK, AllDnns) case Snssai != "" && Dnn == "": udmUe.SmSubsDataLock.RLock() defer udmUe.SmSubsDataLock.RUnlock() - return udmUe.SessionManagementSubsData[snssaikey].DnnConfigurations, nil + c.JSON(http.StatusOK, udmUe.SessionManagementSubsData[snssaikey].DnnConfigurations) case Snssai == "" && Dnn != "": - return AllDnnConfigsbyDnn, nil + c.JSON(http.StatusOK, AllDnnConfigsbyDnn) case Snssai != "" && Dnn != "": - return rspSMSubDataList, nil + c.JSON(http.StatusOK, rspSMSubDataList) default: udmUe.SmSubsDataLock.RLock() defer udmUe.SmSubsDataLock.RUnlock() - return udmUe.SessionManagementSubsData, nil + c.JSON(http.StatusOK, udmUe.SessionManagementSubsData) } } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } -func (p *Processor) GetNssaiProcedure(supi string, plmnID string, supportedFeatures string) ( - *models.Nssai, *models.ProblemDetails, -) { +func (p *Processor) GetNssaiProcedure(c *gin.Context, supi string, plmnID string, supportedFeatures string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) var nssaiResp models.Nssai clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } accessAndMobilitySubscriptionDataResp, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi. @@ -583,7 +606,8 @@ func (p *Processor) GetNssaiProcedure(supi string, plmnID string, supportedFeatu Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -600,22 +624,21 @@ func (p *Processor) GetNssaiProcedure(supi string, plmnID string, supportedFeatu udmUe = udm_context.GetSelf().NewUdmUe(supi) } udmUe.Nssai = &nssaiResp - return udmUe.Nssai, nil + c.JSON(http.StatusOK, udmUe.Nssai) } else { problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) GetSmfSelectDataProcedure(supi string, plmnID string, supportedFeatures string) ( - response *models.SmfSelectionSubscriptionData, problemDetails *models.ProblemDetails, -) { +func (p *Processor) GetSmfSelectDataProcedure(c *gin.Context, supi string, plmnID string, supportedFeatures string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } var querySmfSelectDataParamOpts Nudr_DataRepository.QuerySmfSelectDataParamOpts querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) @@ -623,7 +646,9 @@ func (p *Processor) GetSmfSelectDataProcedure(supi string, plmnID string, suppor clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, body) @@ -637,14 +662,17 @@ func (p *Processor) GetSmfSelectDataProcedure(supi string, plmnID string, suppor logger.SdmLog.Warnln(err) } else { logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } - return nil, problemDetails + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := res.Body.Close(); rspCloseErr != nil { @@ -658,22 +686,21 @@ func (p *Processor) GetSmfSelectDataProcedure(supi string, plmnID string, suppor udmUe = udm_context.GetSelf().NewUdmUe(supi) } udmUe.SetSmfSelectionSubsData(&smfSelectionSubscriptionDataResp) - return udmUe.SmfSelSubsData, nil + c.JSON(http.StatusOK, udmUe.SmfSelSubsData) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) SubscribeToSharedDataProcedure(sdmSubscription *models.SdmSubscription) ( - header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { +func (p *Processor) SubscribeToSharedDataProcedure(c *gin.Context, sdmSubscription *models.SdmSubscription) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } udmClientAPI := p.consumer.GetSDMClient("subscribeToSharedData") @@ -686,12 +713,13 @@ func (p *Processor) SubscribeToSharedDataProcedure(sdmSubscription *models.SdmSu } else if err.Error() != res.Status { logger.SdmLog.Warnln(err) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -701,40 +729,44 @@ func (p *Processor) SubscribeToSharedDataProcedure(sdmSubscription *models.SdmSu }() if res.StatusCode == http.StatusCreated { - header = make(http.Header) + header := make(http.Header) udm_context.GetSelf().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) reourceUri := udm_context.GetSelf(). GetSDMUri() + "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId header.Set("Location", reourceUri) - return header, &sdmSubscriptionResp, nil + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusOK, sdmSubscriptionResp) } else if res.StatusCode == http.StatusNotFound { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotImplemented, Cause: "UNSUPPORTED_RESOURCE_URI", } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) SubscribeProcedure(sdmSubscription *models.SdmSubscription, supi string) ( - header http.Header, response *models.SdmSubscription, problemDetails *models.ProblemDetails, -) { +func (p *Processor) SubscribeProcedure(c *gin.Context, sdmSubscription *models.SdmSubscription, supi string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } sdmSubscriptionResp, res, err := clientAPI.SDMSubscriptionsCollectionApi.CreateSdmSubscriptions( @@ -746,12 +778,13 @@ func (p *Processor) SubscribeProcedure(sdmSubscription *models.SdmSubscription, logger.SdmLog.Warnln(err) } else { logger.SdmLog.Warnln(err) - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -761,33 +794,37 @@ func (p *Processor) SubscribeProcedure(sdmSubscription *models.SdmSubscription, }() if res.StatusCode == http.StatusCreated { - header = make(http.Header) + header := make(http.Header) udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) if udmUe == nil { udmUe = udm_context.GetSelf().NewUdmUe(supi) } udmUe.CreateSubscriptiontoNotifChange(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) header.Set("Location", udmUe.GetLocationURI2(udm_context.LocationUriSdmSubscription, supi)) - return header, &sdmSubscriptionResp, nil + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, sdmSubscriptionResp) } else if res.StatusCode == http.StatusNotFound { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotImplemented, Cause: "UNSUPPORTED_RESOURCE_URI", } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) UnsubscribeForSharedDataProcedure(subscriptionID string) *models.ProblemDetails { +func (p *Processor) UnsubscribeForSharedDataProcedure(c *gin.Context, subscriptionID string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } udmClientAPI := p.consumer.GetSDMClient("unsubscribeForSharedData") @@ -806,7 +843,8 @@ func (p *Processor) UnsubscribeForSharedDataProcedure(subscriptionID string) *mo Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -816,24 +854,27 @@ func (p *Processor) UnsubscribeForSharedDataProcedure(subscriptionID string) *mo }() if res.StatusCode == http.StatusNoContent { - return nil + c.Status(http.StatusNoContent) } else { problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) UnsubscribeProcedure(supi string, subscriptionID string) *models.ProblemDetails { +func (p *Processor) UnsubscribeProcedure(c *gin.Context, supi string, subscriptionID string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } res, err := clientAPI.SDMSubscriptionDocumentApi.RemovesdmSubscriptions(ctx, supi, subscriptionID) @@ -849,7 +890,8 @@ func (p *Processor) UnsubscribeProcedure(supi string, subscriptionID string) *mo Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -859,30 +901,31 @@ func (p *Processor) UnsubscribeProcedure(supi string, subscriptionID string) *mo }() if res.StatusCode == http.StatusNoContent { - return nil + c.Status(http.StatusNoContent) } else { problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "USER_NOT_FOUND", } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) ModifyProcedure( +func (p *Processor) ModifyProcedure(c *gin.Context, sdmSubsModification *models.SdmSubsModification, supi string, subscriptionID string, -) ( - response *models.SdmSubscription, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } sdmSubscription := models.SdmSubscription{} @@ -898,12 +941,13 @@ func (p *Processor) ModifyProcedure( } else if err.Error() != res.Status { logger.SdmLog.Warnln(err) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -913,29 +957,34 @@ func (p *Processor) ModifyProcedure( }() if res.StatusCode == http.StatusOK { - return &sdmSubscription, nil + c.JSON(http.StatusOK, sdmSubscription) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "USER_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } // TS 29.503 5.2.2.7.3 // Modification of a subscription to notifications of shared data change -func (p *Processor) ModifyForSharedDataProcedure(sdmSubsModification *models.SdmSubsModification, supi string, +func (p *Processor) ModifyForSharedDataProcedure(c *gin.Context, + sdmSubsModification *models.SdmSubsModification, + supi string, subscriptionID string, -) (response *models.SdmSubscription, problemDetails *models.ProblemDetails) { +) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } var sdmSubscription models.SdmSubscription @@ -952,12 +1001,13 @@ func (p *Processor) ModifyForSharedDataProcedure(sdmSubsModification *models.Sdm } else if err.Error() != res.Status { logger.SdmLog.Warnln(err) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -967,30 +1017,30 @@ func (p *Processor) ModifyForSharedDataProcedure(sdmSubsModification *models.Sdm }() if res.StatusCode == http.StatusOK { - return &sdmSubscription, nil + c.JSON(http.StatusOK, sdmSubscription) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "USER_NOT_FOUND", } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) GetTraceDataProcedure(supi string, plmnID string) ( - response *models.TraceData, problemDetails *models.ProblemDetails, -) { +func (p *Processor) GetTraceDataProcedure(c *gin.Context, supi string, plmnID string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } var body models.TraceData var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } udm_context.GetSelf().CreateTraceDataforUe(supi, body) @@ -1003,13 +1053,13 @@ func (p *Processor) GetTraceDataProcedure(supi string, plmnID string) ( } else if err.Error() != res.Status { logger.SdmLog.Warnln(err) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -1026,20 +1076,18 @@ func (p *Processor) GetTraceDataProcedure(supi string, plmnID string) ( udmUe.TraceData = &traceDataRes udmUe.TraceDataResponse.TraceData = &traceDataRes - return udmUe.TraceDataResponse.TraceData, nil + c.JSON(http.StatusOK, udmUe.TraceDataResponse.TraceData) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "USER_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } -func (p *Processor) GetUeContextInSmfDataProcedure(supi string, supportedFeatures string) ( - response *models.UeContextInSmfData, problemDetails *models.ProblemDetails, -) { +func (p *Processor) GetUeContextInSmfDataProcedure(c *gin.Context, supi string, supportedFeatures string) { var body models.UeContextInSmfData var ueContextInSmfData models.UeContextInSmfData var pgwInfoArray []models.PgwInfo @@ -1048,7 +1096,9 @@ func (p *Processor) GetUeContextInSmfDataProcedure(supi string, supportedFeature clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } pduSessionMap := make(map[string]models.PduSession) @@ -1056,7 +1106,8 @@ func (p *Processor) GetUeContextInSmfDataProcedure(supi string, supportedFeature ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( @@ -1068,13 +1119,14 @@ func (p *Processor) GetUeContextInSmfDataProcedure(supi string, supportedFeature logger.SdmLog.Infoln(err) } else { logger.SdmLog.Infoln(err) - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(res.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } } defer func() { @@ -1107,13 +1159,13 @@ func (p *Processor) GetUeContextInSmfDataProcedure(supi string, supportedFeature udmUe = udm_context.GetSelf().NewUdmUe(supi) } udmUe.UeCtxtInSmfData = &ueContextInSmfData - return udmUe.UeCtxtInSmfData, nil + c.JSON(http.StatusOK, udmUe.UeCtxtInSmfData) } else { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "DATA_NOT_FOUND", } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) } } diff --git a/internal/sbi/processor/ue_context_management.go b/internal/sbi/processor/ue_context_management.go index 2d4b087..9ab1008 100644 --- a/internal/sbi/processor/ue_context_management.go +++ b/internal/sbi/processor/ue_context_management.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/antihax/optional" + "github.com/gin-gonic/gin" "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudr_DataRepository" @@ -14,30 +15,32 @@ import ( ) // ue_context_managemanet_service -func (p *Processor) GetAmf3gppAccessProcedure(ueID string, supportedFeatures string) ( - response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, -) { +func (p *Processor) GetAmf3gppAccessProcedure(c *gin.Context, ueID string, supportedFeatures string) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) + return } var queryAmfContext3gppParamOpts Nudr_DataRepository.QueryAmfContext3gppParamOpts queryAmfContext3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } amf3GppAccessRegistration, resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi. QueryAmfContext3gpp(ctx, ueID, &queryAmfContext3gppParamOpts) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -45,31 +48,33 @@ func (p *Processor) GetAmf3gppAccessProcedure(ueID string, supportedFeatures str } }() - return &amf3GppAccessRegistration, nil + c.JSON(http.StatusOK, amf3GppAccessRegistration) } -func (p *Processor) GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts Nudr_DataRepository. - QueryAmfContextNon3gppParamOpts, ueID string) (response *models.AmfNon3GppAccessRegistration, - problemDetails *models.ProblemDetails, +func (p *Processor) GetAmfNon3gppAccessProcedure(c *gin.Context, queryAmfContextNon3gppParamOpts Nudr_DataRepository. + QueryAmfContextNon3gppParamOpts, ueID string, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, pd + c.JSON(int(pd.Status), pd) } clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } amfNon3GppAccessRegistration, resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi. QueryAmfContextNon3gpp(ctx, ueID, &queryAmfContextNon3gppParamOpts) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -77,18 +82,17 @@ func (p *Processor) GetAmfNon3gppAccessProcedure(queryAmfContextNon3gppParamOpts } }() - return &amfNon3GppAccessRegistration, nil + c.JSON(http.StatusOK, amfNon3GppAccessRegistration) } -func (p *Processor) RegistrationAmf3gppAccessProcedure( +func (p *Processor) RegistrationAmf3gppAccessProcedure(c *gin.Context, registerRequest models.Amf3GppAccessRegistration, ueID string, -) ( - header http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } // TODO: EPS interworking with N26 is not supported yet in this stage var oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration @@ -103,7 +107,9 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure( clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } var createAmfContext3gppParamOpts Nudr_DataRepository.CreateAmfContext3gppParamOpts @@ -113,12 +119,13 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure( ueID, &createAmfContext3gppParamOpts) if err != nil { logger.UecmLog.Errorln("CreateAmfContext3gpp error : ", err) - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -152,24 +159,27 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure( } }() } - return nil, ®isterRequest, nil + + c.JSON(http.StatusOK, registerRequest) } else { - header = make(http.Header) + header := make(http.Header) udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration)) - return header, ®isterRequest, nil + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, registerRequest) } } -func (p *Processor) RegisterAmfNon3gppAccessProcedure( +func (p *Processor) RegisterAmfNon3gppAccessProcedure(c *gin.Context, registerRequest models.AmfNon3GppAccessRegistration, ueID string, -) ( - header http.Header, response *models.AmfNon3GppAccessRegistration, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } var oldAmfNon3GppAccessRegContext *models.AmfNon3GppAccessRegistration if udm_context.GetSelf().UdmAmfNon3gppRegContextExists(ueID) { @@ -181,7 +191,9 @@ func (p *Processor) RegisterAmfNon3gppAccessProcedure( clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } var createAmfContextNon3gppParamOpts Nudr_DataRepository.CreateAmfContextNon3gppParamOpts @@ -191,12 +203,14 @@ func (p *Processor) RegisterAmfNon3gppAccessProcedure( resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.CreateAmfContextNon3gpp( ctx, ueID, &createAmfContextNon3gppParamOpts) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, nil, problemDetails + + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -214,31 +228,37 @@ func (p *Processor) RegisterAmfNon3gppAccessProcedure( p.SendOnDeregistrationNotification(ueID, oldAmfNon3GppAccessRegContext.DeregCallbackUri, deregistData) // Deregistration Notify Triggered - return nil, nil, nil + return } else { - header = make(http.Header) + header := make(http.Header) udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmfNon3GppAccessRegistration)) - return header, ®isterRequest, nil + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, registerRequest) } } -func (p *Processor) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessRegistrationModification, ueID string) ( - problemDetails *models.ProblemDetails, +func (p *Processor) UpdateAmf3gppAccessProcedure(c *gin.Context, + request models.Amf3GppAccessRegistrationModification, + ueID string, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } var patchItemReqArray []models.PatchItem currentContext := udm_context.GetSelf().GetAmf3gppRegContext(ueID) if currentContext == nil { logger.UecmLog.Errorln("[UpdateAmf3gppAccess] Empty Amf3gppRegContext") - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "CONTEXT_NOT_FOUND", } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } if request.Guami != nil { @@ -248,11 +268,12 @@ func (p *Processor) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessReg request.PurgeFlag = true } else { logger.UecmLog.Errorln("INVALID_GUAMI") - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "INVALID_GUAMI", } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } var patchItemTmp models.PatchItem @@ -296,19 +317,21 @@ func (p *Processor) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessReg clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.AmfContext3gpp(ctx, ueID, patchItemReqArray) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } if request.PurgeFlag { @@ -322,28 +345,28 @@ func (p *Processor) UpdateAmf3gppAccessProcedure(request models.Amf3GppAccessReg } }() - return nil + c.Status(http.StatusNoContent) } -func (p *Processor) UpdateAmfNon3gppAccessProcedure( +func (p *Processor) UpdateAmfNon3gppAccessProcedure(c *gin.Context, request models.AmfNon3GppAccessRegistrationModification, ueID string, -) ( - problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } var patchItemReqArray []models.PatchItem currentContext := udm_context.GetSelf().GetAmfNon3gppRegContext(ueID) if currentContext == nil { logger.UecmLog.Errorln("[UpdateAmfNon3gppAccess] Empty AmfNon3gppRegContext") - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, Cause: "CONTEXT_NOT_FOUND", } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } if request.Guami != nil { @@ -353,10 +376,12 @@ func (p *Processor) UpdateAmfNon3gppAccessProcedure( request.PurgeFlag = true } else { logger.UecmLog.Errorln("INVALID_GUAMI") - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "INVALID_GUAMI", } + c.JSON(int(problemDetails.Status), problemDetails) + return } var patchItemTmp models.PatchItem @@ -400,18 +425,21 @@ func (p *Processor) UpdateAmfNon3gppAccessProcedure( clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } resp, err := clientAPI.AMFNon3GPPAccessRegistrationDocumentApi.AmfContextNon3gpp(ctx, ueID, patchItemReqArray) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -419,30 +447,34 @@ func (p *Processor) UpdateAmfNon3gppAccessProcedure( } }() - return problemDetails + c.Status(http.StatusNoContent) } -func (p *Processor) DeregistrationSmfRegistrationsProcedure( +func (p *Processor) DeregistrationSmfRegistrationsProcedure(c *gin.Context, ueID string, pduSessionID string, -) (problemDetails *models.ProblemDetails) { +) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return pd + c.JSON(int(pd.Status), pd) + return } clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } resp, err := clientAPI.SMFRegistrationDocumentApi.DeleteSmfContext(ctx, ueID, pduSessionID) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -450,19 +482,19 @@ func (p *Processor) DeregistrationSmfRegistrationsProcedure( } }() - return nil + c.Status(http.StatusNoContent) } func (p *Processor) RegistrationSmfRegistrationsProcedure( + c *gin.Context, request *models.SmfRegistration, ueID string, pduSessionID string, -) ( - header http.Header, response *models.SmfRegistration, problemDetails *models.ProblemDetails, ) { ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) if err != nil { - return nil, nil, pd + c.JSON(int(pd.Status), pd) + return } contextExisted := false udm_context.GetSelf().CreateSmfRegContext(ueID, pduSessionID) @@ -482,18 +514,21 @@ func (p *Processor) RegistrationSmfRegistrationsProcedure( clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { - return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error()) + problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) + c.JSON(int(problemDetails.Status), problemDetails) + return } resp, err := clientAPI.SMFRegistrationDocumentApi.CreateSmfContextNon3gpp(ctx, ueID, pduID32, &createSmfContextNon3gppParamOpts) if err != nil { - problemDetails = &models.ProblemDetails{ + problemDetails := &models.ProblemDetails{ Status: int32(resp.StatusCode), Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause, Detail: err.Error(), } - return nil, nil, problemDetails + c.JSON(int(problemDetails.Status), problemDetails) + return } defer func() { if rspCloseErr := resp.Body.Close(); rspCloseErr != nil { @@ -502,11 +537,14 @@ func (p *Processor) RegistrationSmfRegistrationsProcedure( }() if contextExisted { - return nil, nil, nil + c.Status(http.StatusNoContent) } else { - header = make(http.Header) + header := make(http.Header) udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriSmfRegistration)) - return header, request, nil + for key, val := range header { // header response is optional + c.Header(key, val[0]) + } + c.JSON(http.StatusCreated, request) } } From 00010506e37bcb3e2334e176a5223db98fee376e Mon Sep 17 00:00:00 2001 From: ubuntu Date: Tue, 25 Jun 2024 10:46:59 +0000 Subject: [PATCH 20/23] fix: fix PR comment --- .../sbi/processor/ue_context_management.go | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/internal/sbi/processor/ue_context_management.go b/internal/sbi/processor/ue_context_management.go index 9ab1008..295b1ee 100644 --- a/internal/sbi/processor/ue_context_management.go +++ b/internal/sbi/processor/ue_context_management.go @@ -162,12 +162,8 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure(c *gin.Context, c.JSON(http.StatusOK, registerRequest) } else { - header := make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration)) - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } + udmUe, _ := p.Context().UdmUeFindBySupi(ueID) + c.Header("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration)) c.JSON(http.StatusCreated, registerRequest) } } @@ -230,12 +226,8 @@ func (p *Processor) RegisterAmfNon3gppAccessProcedure(c *gin.Context, return } else { - header := make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmfNon3GppAccessRegistration)) - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } + udmUe, _ := p.Context().UdmUeFindBySupi(ueID) + c.Header("Location", udmUe.GetLocationURI(udm_context.LocationUriAmfNon3GppAccessRegistration)) c.JSON(http.StatusCreated, registerRequest) } } @@ -487,7 +479,7 @@ func (p *Processor) DeregistrationSmfRegistrationsProcedure(c *gin.Context, func (p *Processor) RegistrationSmfRegistrationsProcedure( c *gin.Context, - request *models.SmfRegistration, + smfRegistration *models.SmfRegistration, ueID string, pduSessionID string, ) { @@ -509,7 +501,7 @@ func (p *Processor) RegistrationSmfRegistrationsProcedure( pduID32 := int32(pduID64) var createSmfContextNon3gppParamOpts Nudr_DataRepository.CreateSmfContextNon3gppParamOpts - optInterface := optional.NewInterface(*request) + optInterface := optional.NewInterface(*smfRegistration) createSmfContextNon3gppParamOpts.SmfRegistration = optInterface clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) @@ -539,12 +531,8 @@ func (p *Processor) RegistrationSmfRegistrationsProcedure( if contextExisted { c.Status(http.StatusNoContent) } else { - header := make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) - header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriSmfRegistration)) - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } - c.JSON(http.StatusCreated, request) + udmUe, _ := p.Context().UdmUeFindBySupi(ueID) + c.Header("Location", udmUe.GetLocationURI(udm_context.LocationUriSmfRegistration)) + c.JSON(http.StatusCreated, smfRegistration) } } From d4025e089ecc6055ff6943c70b5b306e2f323c3b Mon Sep 17 00:00:00 2001 From: ubuntu Date: Tue, 25 Jun 2024 11:15:37 +0000 Subject: [PATCH 21/23] fix: fix PR comment --- internal/sbi/processor/event_exposure.go | 6 +- internal/sbi/processor/generate_auth_data.go | 9 +- internal/sbi/processor/notifier.go | 7 +- internal/sbi/processor/parameter_provision.go | 3 +- .../processor/subscriber_data_management.go | 116 ++++++++---------- .../sbi/processor/ue_context_management.go | 42 +++---- 6 files changed, 86 insertions(+), 97 deletions(-) diff --git a/internal/sbi/processor/event_exposure.go b/internal/sbi/processor/event_exposure.go index 19d8105..ad083df 100644 --- a/internal/sbi/processor/event_exposure.go +++ b/internal/sbi/processor/event_exposure.go @@ -16,7 +16,7 @@ import ( func (p *Processor) CreateEeSubscriptionProcedure(c *gin.Context, ueIdentity string, eesubscription models.EeSubscription, ) { - udmSelf := udm_context.GetSelf() + udmSelf := p.Context() logger.EeLog.Debugf("udIdentity: %s", ueIdentity) switch { // GPSI (MSISDN identifier) represents a single UE @@ -110,7 +110,7 @@ func (p *Processor) CreateEeSubscriptionProcedure(c *gin.Context, ueIdentity str // TODO: complete this procedure based on TS 29503 5.5 func (p *Processor) DeleteEeSubscriptionProcedure(c *gin.Context, ueIdentity string, subscriptionID string) { - udmSelf := udm_context.GetSelf() + udmSelf := p.Context() switch { case strings.HasPrefix(ueIdentity, "msisdn-"): @@ -148,7 +148,7 @@ func (p *Processor) DeleteEeSubscriptionProcedure(c *gin.Context, ueIdentity str func (p *Processor) UpdateEeSubscriptionProcedure(c *gin.Context, ueIdentity string, subscriptionID string, patchList []models.PatchItem, ) { - udmSelf := udm_context.GetSelf() + udmSelf := p.Context() switch { case strings.HasPrefix(ueIdentity, "msisdn-"): diff --git a/internal/sbi/processor/generate_auth_data.go b/internal/sbi/processor/generate_auth_data.go index 44f58db..02283fa 100644 --- a/internal/sbi/processor/generate_auth_data.go +++ b/internal/sbi/processor/generate_auth_data.go @@ -18,7 +18,6 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudr_DataRepository" "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" "github.com/free5gc/udm/pkg/suci" "github.com/free5gc/util/milenage" @@ -81,7 +80,7 @@ func (p *Processor) ConfirmAuthDataProcedure(c *gin.Context, authEvent models.AuthEvent, supi string, ) { - ctx, pd, err := udm_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 @@ -124,7 +123,7 @@ func (p *Processor) GenerateAuthDataProcedure( authInfoRequest models.AuthenticationInfoRequest, supiOrSuci string, ) { - ctx, pd, err := udm_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 +132,7 @@ func (p *Processor) GenerateAuthDataProcedure( response := &models.AuthenticationInfoResult{} rand.New(rand.NewSource(time.Now().UnixNano())) - supi, err := suci.ToSupi(supiOrSuci, udm_context.GetSelf().SuciProfiles) + supi, err := suci.ToSupi(supiOrSuci, p.Context().SuciProfiles) if err != nil { problemDetails := &models.ProblemDetails{ Status: http.StatusForbidden, @@ -409,7 +408,7 @@ func (p *Processor) GenerateAuthDataProcedure( keyIndex) } else { logger.UeauLog.Errorln("Re-Sync Failed UDM Public Key ", - udm_context.GetSelf().SuciProfiles[keyIndex-1].PublicKey) + p.Context().SuciProfiles[keyIndex-1].PublicKey) } } logger.UeauLog.Errorln("MACS ", macS) diff --git a/internal/sbi/processor/notifier.go b/internal/sbi/processor/notifier.go index 9c09b62..60c6602 100644 --- a/internal/sbi/processor/notifier.go +++ b/internal/sbi/processor/notifier.go @@ -6,7 +6,6 @@ import ( "github.com/gin-gonic/gin" "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" ) @@ -14,13 +13,13 @@ func (p *Processor) DataChangeNotificationProcedure(c *gin.Context, notifyItems []models.NotifyItem, supi string, ) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { c.JSON(int(pd.Status), pd) return } - ue, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) + ue, _ := p.Context().UdmUeFindBySupi(supi) clientAPI := p.consumer.GetSDMClient("DataChangeNotification") @@ -61,7 +60,7 @@ func (p *Processor) DataChangeNotificationProcedure(c *gin.Context, func (p *Processor) SendOnDeregistrationNotification(ueId string, onDeregistrationNotificationUrl string, deregistData models.DeregistrationData, ) *models.ProblemDetails { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NfType_UDM) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NfType_UDM) if err != nil { return pd } diff --git a/internal/sbi/processor/parameter_provision.go b/internal/sbi/processor/parameter_provision.go index 9ed4270..8246cfd 100644 --- a/internal/sbi/processor/parameter_provision.go +++ b/internal/sbi/processor/parameter_provision.go @@ -7,7 +7,6 @@ import ( "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" - udm_context "github.com/free5gc/udm/internal/context" "github.com/free5gc/udm/internal/logger" ) @@ -15,7 +14,7 @@ func (p *Processor) UpdateProcedure(c *gin.Context, updateRequest models.PpData, gpsi string, ) { - ctx, pd, err := udm_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/subscriber_data_management.go b/internal/sbi/processor/subscriber_data_management.go index 316f016..9ceb83c 100644 --- a/internal/sbi/processor/subscriber_data_management.go +++ b/internal/sbi/processor/subscriber_data_management.go @@ -15,7 +15,7 @@ import ( ) func (p *Processor) GetAmDataProcedure(c *gin.Context, supi string, plmnID string, supportedFeatures string) { - ctx, pd, err := udm_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 @@ -54,9 +54,9 @@ func (p *Processor) GetAmDataProcedure(c *gin.Context, supi string, plmnID strin }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.SetAMSubsriptionData(&accessAndMobilitySubscriptionDataResp) c.JSON(http.StatusOK, accessAndMobilitySubscriptionDataResp) @@ -70,7 +70,7 @@ func (p *Processor) GetAmDataProcedure(c *gin.Context, supi string, plmnID strin } func (p *Processor) GetIdTranslationResultProcedure(c *gin.Context, gpsi string) { - ctx, pd, err := udm_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) } @@ -135,7 +135,7 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, dataSetNames []string, supportedFeatures string, ) { - ctx, pd, err := udm_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 @@ -170,11 +170,11 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - udm_context.GetSelf().CreateSubsDataSetsForUe(supi, subsDataSetBody) + p.Context().CreateSubsDataSetsForUe(supi, subsDataSetBody) if p.containDataSetName(dataSetNames, string(models.DataSetName_AM)) { var body models.AccessAndMobilitySubscriptionData - udm_context.GetSelf().CreateAccessMobilitySubsDataForUe(supi, body) + p.Context().CreateAccessMobilitySubsDataForUe(supi, body) amData, res, err := clientAPI.AccessAndMobilitySubscriptionDataDocumentApi.QueryAmData( ctx, supi, plmnID, &queryAmDataParamOpts) @@ -200,9 +200,9 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, } }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.SetAMSubsriptionData(&amData) subscriptionDataSets.AmData = &amData @@ -219,7 +219,7 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, if p.containDataSetName(dataSetNames, string(models.DataSetName_SMF_SEL)) { var smfSelSubsbody models.SmfSelectionSubscriptionData - udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, smfSelSubsbody) + p.Context().CreateSmfSelectionSubsDataforUe(supi, smfSelSubsbody) smfSelData, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi.QuerySmfSelectData(ctx, supi, plmnID, &querySmfSelectDataParamOpts) @@ -245,9 +245,9 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, } }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.SetSmfSelectionSubsData(&smfSelData) subscriptionDataSets.SmfSelData = &smfSelData @@ -266,7 +266,7 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, var UeContextInSmfbody models.UeContextInSmfData var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, UeContextInSmfbody) + p.Context().CreateUeContextInSmfDataforUe(supi, UeContextInSmfbody) pdusess, res, err := clientAPI.SMFRegistrationsCollectionApi.QuerySmfRegList( ctx, supi, &querySmfRegListParamOpts) @@ -311,9 +311,9 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, ueContextInSmfDataResp.PgwInfo = pgwInfoArray if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.UeCtxtInSmfData = &ueContextInSmfDataResp subscriptionDataSets.UecSmfData = &ueContextInSmfDataResp @@ -357,11 +357,11 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, } }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } - smData, _, _, _ := udm_context.GetSelf().ManageSmData(sessionManagementSubscriptionData, "", "") + smData, _, _, _ := p.Context().ManageSmData(sessionManagementSubscriptionData, "", "") udmUe.SetSMSubsData(smData) subscriptionDataSets.SmData = sessionManagementSubscriptionData } else { @@ -377,7 +377,7 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, if p.containDataSetName(dataSetNames, string(models.DataSetName_TRACE)) { var TraceDatabody models.TraceData - udm_context.GetSelf().CreateTraceDataforUe(supi, TraceDatabody) + p.Context().CreateTraceDataforUe(supi, TraceDatabody) traceData, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( ctx, supi, plmnID, &queryTraceDataParamOpts) @@ -405,9 +405,9 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, } }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.TraceData = &traceData udmUe.TraceDataResponse.TraceData = &traceData @@ -431,7 +431,7 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, } func (p *Processor) GetSharedDataProcedure(c *gin.Context, sharedDataIds []string, supportedFeatures string) { - ctx, pd, err := udm_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 @@ -472,7 +472,7 @@ func (p *Processor) GetSharedDataProcedure(c *gin.Context, sharedDataIds []strin }() if res.StatusCode == http.StatusOK { - udm_context.GetSelf().SharedSubsDataMap = udm_context.MappingSharedData(sharedDataResp) + p.Context().SharedSubsDataMap = udm_context.MappingSharedData(sharedDataResp) sharedData := udm_context.ObtainRequiredSharedData(sharedDataIds, sharedDataResp) c.JSON(http.StatusOK, sharedData) } else { @@ -492,7 +492,7 @@ func (p *Processor) GetSmDataProcedure( Snssai string, supportedFeatures string, ) { - ctx, pd, err := udm_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) } @@ -533,11 +533,11 @@ func (p *Processor) GetSmDataProcedure( }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } - smData, snssaikey, AllDnnConfigsbyDnn, AllDnns := udm_context.GetSelf().ManageSmData( + smData, snssaikey, AllDnnConfigsbyDnn, AllDnns := p.Context().ManageSmData( sessionManagementSubscriptionDataResp, Snssai, Dnn) udmUe.SetSMSubsData(smData) @@ -576,7 +576,7 @@ func (p *Processor) GetSmDataProcedure( } func (p *Processor) GetNssaiProcedure(c *gin.Context, supi string, plmnID string, supportedFeatures string) { - ctx, pd, err := udm_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 @@ -619,9 +619,9 @@ func (p *Processor) GetNssaiProcedure(c *gin.Context, supi string, plmnID string nssaiResp = *accessAndMobilitySubscriptionDataResp.Nssai if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.Nssai = &nssaiResp c.JSON(http.StatusOK, udmUe.Nssai) @@ -635,7 +635,7 @@ func (p *Processor) GetNssaiProcedure(c *gin.Context, supi string, plmnID string } func (p *Processor) GetSmfSelectDataProcedure(c *gin.Context, supi string, plmnID string, supportedFeatures string) { - ctx, pd, err := udm_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 @@ -651,7 +651,7 @@ func (p *Processor) GetSmfSelectDataProcedure(c *gin.Context, supi string, plmnI return } - udm_context.GetSelf().CreateSmfSelectionSubsDataforUe(supi, body) + p.Context().CreateSmfSelectionSubsDataforUe(supi, body) smfSelectionSubscriptionDataResp, res, err := clientAPI.SMFSelectionSubscriptionDataDocumentApi. QuerySmfSelectData(ctx, supi, plmnID, &querySmfSelectDataParamOpts) @@ -681,9 +681,9 @@ func (p *Processor) GetSmfSelectDataProcedure(c *gin.Context, supi string, plmnI }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.SetSmfSelectionSubsData(&smfSelectionSubscriptionDataResp) c.JSON(http.StatusOK, udmUe.SmfSelSubsData) @@ -697,7 +697,7 @@ func (p *Processor) GetSmfSelectDataProcedure(c *gin.Context, supi string, plmnI } func (p *Processor) SubscribeToSharedDataProcedure(c *gin.Context, sdmSubscription *models.SdmSubscription) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { c.JSON(int(pd.Status), pd) return @@ -729,15 +729,11 @@ func (p *Processor) SubscribeToSharedDataProcedure(c *gin.Context, sdmSubscripti }() if res.StatusCode == http.StatusCreated { - header := make(http.Header) - udm_context.GetSelf().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) - reourceUri := udm_context.GetSelf(). + p.Context().CreateSubstoNotifSharedData(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) + reourceUri := p.Context(). GetSDMUri() + "//shared-data-subscriptions/" + sdmSubscriptionResp.SubscriptionId - header.Set("Location", reourceUri) - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } + c.Header("Location", reourceUri) c.JSON(http.StatusOK, sdmSubscriptionResp) } else if res.StatusCode == http.StatusNotFound { problemDetails := &models.ProblemDetails{ @@ -757,7 +753,7 @@ func (p *Processor) SubscribeToSharedDataProcedure(c *gin.Context, sdmSubscripti } func (p *Processor) SubscribeProcedure(c *gin.Context, sdmSubscription *models.SdmSubscription, supi string) { - ctx, pd, err := udm_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 @@ -794,16 +790,12 @@ func (p *Processor) SubscribeProcedure(c *gin.Context, sdmSubscription *models.S }() if res.StatusCode == http.StatusCreated { - header := make(http.Header) - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, _ := p.Context().UdmUeFindBySupi(supi) if udmUe == nil { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.CreateSubscriptiontoNotifChange(sdmSubscriptionResp.SubscriptionId, &sdmSubscriptionResp) - header.Set("Location", udmUe.GetLocationURI2(udm_context.LocationUriSdmSubscription, supi)) - for key, val := range header { // header response is optional - c.Header(key, val[0]) - } + c.Header("Location", udmUe.GetLocationURI2(udm_context.LocationUriSdmSubscription, supi)) c.JSON(http.StatusCreated, sdmSubscriptionResp) } else if res.StatusCode == http.StatusNotFound { problemDetails := &models.ProblemDetails{ @@ -821,7 +813,7 @@ func (p *Processor) SubscribeProcedure(c *gin.Context, sdmSubscription *models.S } func (p *Processor) UnsubscribeForSharedDataProcedure(c *gin.Context, subscriptionID string) { - ctx, pd, err := udm_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) if err != nil { c.JSON(int(pd.Status), pd) return @@ -865,7 +857,7 @@ func (p *Processor) UnsubscribeForSharedDataProcedure(c *gin.Context, subscripti } func (p *Processor) UnsubscribeProcedure(c *gin.Context, supi string, subscriptionID string) { - ctx, pd, err := udm_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 @@ -916,7 +908,7 @@ func (p *Processor) ModifyProcedure(c *gin.Context, supi string, subscriptionID string, ) { - ctx, pd, err := udm_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 @@ -975,7 +967,7 @@ func (p *Processor) ModifyForSharedDataProcedure(c *gin.Context, supi string, subscriptionID string, ) { - ctx, pd, err := udm_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 @@ -1028,7 +1020,7 @@ func (p *Processor) ModifyForSharedDataProcedure(c *gin.Context, } func (p *Processor) GetTraceDataProcedure(c *gin.Context, supi string, plmnID string) { - ctx, pd, err := udm_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 @@ -1043,7 +1035,7 @@ func (p *Processor) GetTraceDataProcedure(c *gin.Context, supi string, plmnID st return } - udm_context.GetSelf().CreateTraceDataforUe(supi, body) + p.Context().CreateTraceDataforUe(supi, body) traceDataRes, res, err := clientAPI.TraceDataDocumentApi.QueryTraceData( ctx, supi, plmnID, &queryTraceDataParamOpts) @@ -1069,9 +1061,9 @@ func (p *Processor) GetTraceDataProcedure(c *gin.Context, supi string, plmnID st }() if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.TraceData = &traceDataRes udmUe.TraceDataResponse.TraceData = &traceDataRes @@ -1102,9 +1094,9 @@ func (p *Processor) GetUeContextInSmfDataProcedure(c *gin.Context, supi string, } pduSessionMap := make(map[string]models.PduSession) - udm_context.GetSelf().CreateUeContextInSmfDataforUe(supi, body) + p.Context().CreateUeContextInSmfDataforUe(supi, body) - ctx, pd, err := udm_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 @@ -1154,9 +1146,9 @@ func (p *Processor) GetUeContextInSmfDataProcedure(c *gin.Context, supi string, ueContextInSmfData.PgwInfo = pgwInfoArray if res.StatusCode == http.StatusOK { - udmUe, ok := udm_context.GetSelf().UdmUeFindBySupi(supi) + udmUe, ok := p.Context().UdmUeFindBySupi(supi) if !ok { - udmUe = udm_context.GetSelf().NewUdmUe(supi) + udmUe = p.Context().NewUdmUe(supi) } udmUe.UeCtxtInSmfData = &ueContextInSmfData c.JSON(http.StatusOK, udmUe.UeCtxtInSmfData) diff --git a/internal/sbi/processor/ue_context_management.go b/internal/sbi/processor/ue_context_management.go index 295b1ee..705d159 100644 --- a/internal/sbi/processor/ue_context_management.go +++ b/internal/sbi/processor/ue_context_management.go @@ -16,7 +16,7 @@ import ( // ue_context_managemanet_service func (p *Processor) GetAmf3gppAccessProcedure(c *gin.Context, ueID string, supportedFeatures string) { - ctx, pd, err := udm_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 @@ -54,7 +54,7 @@ func (p *Processor) GetAmf3gppAccessProcedure(c *gin.Context, ueID string, suppo func (p *Processor) GetAmfNon3gppAccessProcedure(c *gin.Context, queryAmfContextNon3gppParamOpts Nudr_DataRepository. QueryAmfContextNon3gppParamOpts, ueID string, ) { - ctx, pd, err := udm_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) } @@ -89,7 +89,7 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure(c *gin.Context, registerRequest models.Amf3GppAccessRegistration, ueID string, ) { - ctx, pd, err := udm_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 @@ -98,12 +98,12 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure(c *gin.Context, var oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration var ue *udm_context.UdmUeContext - if udm_context.GetSelf().UdmAmf3gppRegContextExists(ueID) { - ue, _ = udm_context.GetSelf().UdmUeFindBySupi(ueID) + if p.Context().UdmAmf3gppRegContextExists(ueID) { + ue, _ = p.Context().UdmUeFindBySupi(ueID) oldAmf3GppAccessRegContext = ue.Amf3GppAccessRegistration } - udm_context.GetSelf().CreateAmf3gppRegContext(ueID, registerRequest) + p.Context().CreateAmf3gppRegContext(ueID, registerRequest) clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { @@ -172,18 +172,18 @@ func (p *Processor) RegisterAmfNon3gppAccessProcedure(c *gin.Context, registerRequest models.AmfNon3GppAccessRegistration, ueID string, ) { - ctx, pd, err := udm_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 } var oldAmfNon3GppAccessRegContext *models.AmfNon3GppAccessRegistration - if udm_context.GetSelf().UdmAmfNon3gppRegContextExists(ueID) { - ue, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + if p.Context().UdmAmfNon3gppRegContextExists(ueID) { + ue, _ := p.Context().UdmUeFindBySupi(ueID) oldAmfNon3GppAccessRegContext = ue.AmfNon3GppAccessRegistration } - udm_context.GetSelf().CreateAmfNon3gppRegContext(ueID, registerRequest) + p.Context().CreateAmfNon3gppRegContext(ueID, registerRequest) clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) if err != nil { @@ -236,13 +236,13 @@ func (p *Processor) UpdateAmf3gppAccessProcedure(c *gin.Context, request models.Amf3GppAccessRegistrationModification, ueID string, ) { - ctx, pd, err := udm_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 } var patchItemReqArray []models.PatchItem - currentContext := udm_context.GetSelf().GetAmf3gppRegContext(ueID) + currentContext := p.Context().GetAmf3gppRegContext(ueID) if currentContext == nil { logger.UecmLog.Errorln("[UpdateAmf3gppAccess] Empty Amf3gppRegContext") problemDetails := &models.ProblemDetails{ @@ -254,7 +254,7 @@ func (p *Processor) UpdateAmf3gppAccessProcedure(c *gin.Context, } if request.Guami != nil { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + udmUe, _ := p.Context().UdmUeFindBySupi(ueID) if udmUe.SameAsStoredGUAMI3gpp(*request.Guami) { // deregistration logger.UecmLog.Infoln("UpdateAmf3gppAccess - deregistration") request.PurgeFlag = true @@ -327,7 +327,7 @@ func (p *Processor) UpdateAmf3gppAccessProcedure(c *gin.Context, } if request.PurgeFlag { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + udmUe, _ := p.Context().UdmUeFindBySupi(ueID) udmUe.Amf3GppAccessRegistration = nil } @@ -344,13 +344,13 @@ func (p *Processor) UpdateAmfNon3gppAccessProcedure(c *gin.Context, request models.AmfNon3GppAccessRegistrationModification, ueID string, ) { - ctx, pd, err := udm_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 } var patchItemReqArray []models.PatchItem - currentContext := udm_context.GetSelf().GetAmfNon3gppRegContext(ueID) + currentContext := p.Context().GetAmfNon3gppRegContext(ueID) if currentContext == nil { logger.UecmLog.Errorln("[UpdateAmfNon3gppAccess] Empty AmfNon3gppRegContext") problemDetails := &models.ProblemDetails{ @@ -362,7 +362,7 @@ func (p *Processor) UpdateAmfNon3gppAccessProcedure(c *gin.Context, } if request.Guami != nil { - udmUe, _ := udm_context.GetSelf().UdmUeFindBySupi(ueID) + udmUe, _ := p.Context().UdmUeFindBySupi(ueID) if udmUe.SameAsStoredGUAMINon3gpp(*request.Guami) { // deregistration logger.UecmLog.Infoln("UpdateAmfNon3gppAccess - deregistration") request.PurgeFlag = true @@ -446,7 +446,7 @@ func (p *Processor) DeregistrationSmfRegistrationsProcedure(c *gin.Context, ueID string, pduSessionID string, ) { - ctx, pd, err := udm_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 @@ -483,14 +483,14 @@ func (p *Processor) RegistrationSmfRegistrationsProcedure( ueID string, pduSessionID string, ) { - ctx, pd, err := udm_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 } contextExisted := false - udm_context.GetSelf().CreateSmfRegContext(ueID, pduSessionID) - if !udm_context.GetSelf().UdmSmfRegContextNotExists(ueID) { + p.Context().CreateSmfRegContext(ueID, pduSessionID) + if !p.Context().UdmSmfRegContextNotExists(ueID) { contextExisted = true } From 395e6225c9e85e3e12e1d569d30b768c7c2a3f18 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Wed, 26 Jun 2024 09:17:48 +0000 Subject: [PATCH 22/23] fix : fix PR comment --- internal/sbi/api_eventexposure.go | 1 - internal/sbi/api_httpcallback.go | 2 - internal/sbi/api_parameterprovision.go | 8 +++ internal/sbi/api_subscriberdatamanagement.go | 58 ++------------------ internal/sbi/api_ueauthentication.go | 7 --- internal/sbi/api_uecontextmanagement.go | 33 ----------- 6 files changed, 12 insertions(+), 97 deletions(-) diff --git a/internal/sbi/api_eventexposure.go b/internal/sbi/api_eventexposure.go index 1c0290e..b34ab88 100644 --- a/internal/sbi/api_eventexposure.go +++ b/internal/sbi/api_eventexposure.go @@ -73,7 +73,6 @@ func (s *Server) HandleCreateEeSubscription(c *gin.Context) { return } - // Start logger.EeLog.Infoln("Handle Create EE Subscription") ueIdentity := c.Params.ByName("ueIdentity") diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index 1f3d558..6c79ce6 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -31,7 +31,6 @@ func (s *Server) getHttpCallBackRoutes() []Route { func (s *Server) HandleDataChangeNotificationToNF(c *gin.Context) { var dataChangeNotify models.DataChangeNotify - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -45,7 +44,6 @@ func (s *Server) HandleDataChangeNotificationToNF(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&dataChangeNotify, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() diff --git a/internal/sbi/api_parameterprovision.go b/internal/sbi/api_parameterprovision.go index 7badc40..2e695ca 100644 --- a/internal/sbi/api_parameterprovision.go +++ b/internal/sbi/api_parameterprovision.go @@ -61,6 +61,14 @@ func (s *Server) HandleUpdate(c *gin.Context) { } gpsi := c.Params.ByName("gpsi") + if gpsi == "" { + problemDetails := &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "NO_GPSI", + } + c.JSON(int(problemDetails.Status), problemDetails) + return + } logger.PpLog.Infoln("Handle UpdateRequest") diff --git a/internal/sbi/api_subscriberdatamanagement.go b/internal/sbi/api_subscriberdatamanagement.go index 547b684..52a3cbd 100644 --- a/internal/sbi/api_subscriberdatamanagement.go +++ b/internal/sbi/api_subscriberdatamanagement.go @@ -30,10 +30,8 @@ func (s *Server) HandleGetAmData(c *gin.Context) { query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("plmn-id")) - // step 1: log logger.SdmLog.Infof("Handle GetAmData") - // step 2: retrieve request supi := c.Params.ByName("supi") plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) @@ -44,7 +42,6 @@ func (s *Server) HandleGetAmData(c *gin.Context) { plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc supportedFeatures := query.Get("supported-features") - // step 3: handle the message s.Processor().GetAmDataProcedure(c, supi, plmnID, supportedFeatures) } @@ -71,12 +68,12 @@ func (s *Server) getPlmnIDStruct( // Info - Nudm_Sdm Info service operation func (s *Server) HandleInfo(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // PutUpuAck - Nudm_Sdm Info for UPU service operation func (s *Server) HandlePutUpuAck(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) + c.JSON(http.StatusNotImplemented, gin.H{}) } // GetSmfSelectData - retrieve a UE's SMF Selection Subscription Data @@ -85,10 +82,8 @@ func (s *Server) HandleGetSmfSelectData(c *gin.Context) { query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("supported-features")) - // step 1: log logger.SdmLog.Infof("Handle GetSmfSelectData") - // step 2: retrieve request supi := c.Params.ByName("supi") plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) if problemDetails != nil { @@ -98,7 +93,6 @@ func (s *Server) HandleGetSmfSelectData(c *gin.Context) { plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc supportedFeatures := query.Get("supported-features") - // step 3: handle the message s.Processor().GetSmfSelectDataProcedure(c, supi, plmnID, supportedFeatures) } @@ -119,10 +113,8 @@ func (s *Server) HandleGetSupi(c *gin.Context) { query.Set("dataset-names", c.Query("dataset-names")) query.Set("supported-features", c.Query("supported-features")) - // step 1: log logger.SdmLog.Infof("Handle GetSupiRequest") - // step 2: retrieve request supi := c.Params.ByName("supi") plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) if problemDetails != nil { @@ -133,26 +125,23 @@ func (s *Server) HandleGetSupi(c *gin.Context) { dataSetNames := strings.Split(query.Get("dataset-names"), ",") supportedFeatures := query.Get("supported-features") - // step 3: handle the message s.Processor().GetSupiProcedure(c, supi, plmnID, dataSetNames, supportedFeatures) } // GetSharedData - retrieve shared data func (s *Server) HandleGetSharedData(c *gin.Context) { - // step 1: log logger.SdmLog.Infof("Handle GetSharedData") - // step 2: retrieve request sharedDataIds := c.QueryArray("shared-data-ids") supportedFeatures := c.QueryArray("supported-features") - // step 3: handle the message + s.Processor().GetSharedDataProcedure(c, sharedDataIds, supportedFeatures[0]) } // SubscribeToSharedData - subscribe to notifications for shared data func (s *Server) HandleSubscribeToSharedData(c *gin.Context) { var sharedDataSubsReq models.SdmSubscription - // step 1: retrieve http request body + requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -166,7 +155,6 @@ func (s *Server) HandleSubscribeToSharedData(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&sharedDataSubsReq, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -180,12 +168,8 @@ func (s *Server) HandleSubscribeToSharedData(c *gin.Context) { return } - // step 1: log logger.SdmLog.Infof("Handle SubscribeToSharedData") - // step 2: retrieve request - - // step 3: handle the message s.Processor().SubscribeToSharedDataProcedure(c, &sharedDataSubsReq) } @@ -193,7 +177,6 @@ func (s *Server) HandleSubscribeToSharedData(c *gin.Context) { func (s *Server) HandleSubscribe(c *gin.Context) { var sdmSubscriptionReq models.SdmSubscription - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -207,7 +190,6 @@ func (s *Server) HandleSubscribe(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&sdmSubscriptionReq, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -221,13 +203,10 @@ func (s *Server) HandleSubscribe(c *gin.Context) { return } - // step 1: log logger.SdmLog.Infof("Handle Subscribe") - // step 2: retrieve request supi := c.Params.ByName("supi") - // step 3: handle the message s.Processor().SubscribeProcedure(c, &sdmSubscriptionReq, supi) } @@ -235,11 +214,9 @@ func (s *Server) HandleSubscribe(c *gin.Context) { func (s *Server) HandleUnsubscribe(c *gin.Context) { logger.SdmLog.Infof("Handle Unsubscribe") - // step 2: retrieve request supi := c.Params.ByName("supi") subscriptionID := c.Params.ByName("subscriptionId") - // step 3: handle the message s.Processor().UnsubscribeProcedure(c, supi, subscriptionID) } @@ -247,16 +224,13 @@ func (s *Server) HandleUnsubscribe(c *gin.Context) { func (s *Server) HandleUnsubscribeForSharedData(c *gin.Context) { logger.SdmLog.Infof("Handle UnsubscribeForSharedData") - // step 2: retrieve request subscriptionID := c.Params.ByName("subscriptionId") - // step 3: handle the message s.Processor().UnsubscribeForSharedDataProcedure(c, subscriptionID) } // Modify - modify the subscription func (s *Server) HandleModify(c *gin.Context) { var sdmSubsModificationReq models.SdmSubsModification - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -270,7 +244,6 @@ func (s *Server) HandleModify(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&sdmSubsModificationReq, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -284,21 +257,17 @@ func (s *Server) HandleModify(c *gin.Context) { return } - // step 1: log logger.SdmLog.Infof("Handle Modify") - // step 2: retrieve request supi := c.Params.ByName("supi") subscriptionID := c.Params.ByName("subscriptionId") - // step 3: handle the message s.Processor().ModifyProcedure(c, &sdmSubsModificationReq, supi, subscriptionID) } // ModifyForSharedData - modify the subscription func (s *Server) HandleModifyForSharedData(c *gin.Context) { var sharedDataSubscriptions models.SdmSubsModification - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -312,7 +281,6 @@ func (s *Server) HandleModifyForSharedData(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&sharedDataSubscriptions, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -326,40 +294,31 @@ func (s *Server) HandleModifyForSharedData(c *gin.Context) { return } - // step 1: log logger.SdmLog.Infof("Handle ModifyForSharedData") - // step 2: retrieve request supi := c.Params.ByName("supi") subscriptionID := c.Params.ByName("subscriptionId") - // step 3: handle the message s.Processor().ModifyForSharedDataProcedure(c, &sharedDataSubscriptions, supi, subscriptionID) } // GetTraceData - retrieve a UE's Trace Configuration Data func (s *Server) HandleGetTraceData(c *gin.Context) { - // step 1: log logger.SdmLog.Infof("Handle GetTraceData") - // step 2: retrieve request supi := c.Params.ByName("supi") plmnID := c.Query("plmn-id") - // step 3: handle the message s.Processor().GetTraceDataProcedure(c, supi, plmnID) } // GetUeContextInSmfData - retrieve a UE's UE Context In SMF Data func (s *Server) HandleGetUeContextInSmfData(c *gin.Context) { - // step 1: log logger.SdmLog.Infof("Handle GetUeContextInSmfData") - // step 2: retrieve request supi := c.Params.ByName("supi") supportedFeatures := c.Query("supported-features") - // step 3: handle the message s.Processor().GetUeContextInSmfDataProcedure(c, supi, supportedFeatures) } @@ -374,10 +333,8 @@ func (s *Server) HandleGetNssai(c *gin.Context) { query.Set("plmn-id", c.Query("plmn-id")) query.Set("supported-features", c.Query("supported-features")) - // step 1: log logger.SdmLog.Infof("Handle GetNssai") - // step 2: retrieve request supi := c.Params.ByName("supi") plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) if problemDetails != nil { @@ -387,7 +344,6 @@ func (s *Server) HandleGetNssai(c *gin.Context) { plmnID := plmnIDStruct.Mcc + plmnIDStruct.Mnc supportedFeatures := query.Get("supported-features") - // step 3: handle the message s.Processor().GetNssaiProcedure(c, supi, plmnID, supportedFeatures) } @@ -399,10 +355,8 @@ func (s *Server) HandleGetSmData(c *gin.Context) { query.Set("single-nssai", c.Query("single-nssai")) query.Set("supported-features", c.Query("supported-features")) - // step 1: log logger.SdmLog.Infof("Handle GetSmData") - // step 2: retrieve request supi := c.Params.ByName("supi") plmnIDStruct, problemDetails := s.getPlmnIDStruct(query) if problemDetails != nil { @@ -414,7 +368,6 @@ func (s *Server) HandleGetSmData(c *gin.Context) { Snssai := query.Get("single-nssai") supportedFeatures := query.Get("supported-features") - // step 3: handle the message s.Processor().GetSmDataProcedure(c, supi, plmnID, Dnn, Snssai, supportedFeatures) } @@ -422,13 +375,10 @@ func (s *Server) HandleGetSmData(c *gin.Context) { func (s *Server) HandleGetIdTranslationResult(c *gin.Context) { // req.Query.Set("SupportedFeatures", c.Query("supported-features")) - // step 1: log logger.SdmLog.Infof("Handle GetIdTranslationResultRequest") - // step 2: retrieve request gpsi := c.Params.ByName("gpsi") - // step 3: handle the message s.Processor().GetIdTranslationResultProcedure(c, gpsi) } diff --git a/internal/sbi/api_ueauthentication.go b/internal/sbi/api_ueauthentication.go index 2f7910e..68b61c5 100644 --- a/internal/sbi/api_ueauthentication.go +++ b/internal/sbi/api_ueauthentication.go @@ -32,7 +32,6 @@ func (s *Server) getUEAuthenticationRoutes() []Route { // ConfirmAuth - Create a new confirmation event func (s *Server) HandleConfirmAuth(c *gin.Context) { var authEvent models.AuthEvent - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -46,7 +45,6 @@ func (s *Server) HandleConfirmAuth(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&authEvent, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -71,7 +69,6 @@ func (s *Server) HandleConfirmAuth(c *gin.Context) { func (s *Server) HandleGenerateAuthData(c *gin.Context) { var authInfoReq models.AuthenticationInfoRequest - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -85,7 +82,6 @@ func (s *Server) HandleGenerateAuthData(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&authInfoReq, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -99,13 +95,10 @@ func (s *Server) HandleGenerateAuthData(c *gin.Context) { return } - // step 1: log logger.UeauLog.Infoln("Handle GenerateAuthDataRequest") - // step 2: retrieve request supiOrSuci := c.Param("supiOrSuci") - // step 3: handle the message s.Processor().GenerateAuthDataProcedure(c, authInfoReq, supiOrSuci) } diff --git a/internal/sbi/api_uecontextmanagement.go b/internal/sbi/api_uecontextmanagement.go index b17a989..7725449 100644 --- a/internal/sbi/api_uecontextmanagement.go +++ b/internal/sbi/api_uecontextmanagement.go @@ -124,16 +124,13 @@ func (s *Server) getUEContextManagementRoutes() []Route { // GetAmfNon3gppAccess - retrieve the AMF registration for non-3GPP access information func (s *Server) HandleGetAmfNon3gppAccess(c *gin.Context) { - // step 1: log logger.UecmLog.Infoln("Handle GetAmfNon3gppAccessRequest") - // step 2: retrieve request ueId := c.Param("ueId") supportedFeatures := c.Query("supported-features") var queryAmfContextNon3gppParamOpts Nudr_DataRepository.QueryAmfContextNon3gppParamOpts queryAmfContextNon3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - // step 3: handle the message s.Processor().GetAmfNon3gppAccessProcedure(c, queryAmfContextNon3gppParamOpts, ueId) } @@ -142,7 +139,6 @@ func (s *Server) HandleGetAmfNon3gppAccess(c *gin.Context) { func (s *Server) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { var amfNon3GppAccessRegistration models.AmfNon3GppAccessRegistration - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -156,7 +152,6 @@ func (s *Server) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&amfNon3GppAccessRegistration, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -172,17 +167,14 @@ func (s *Server) HandleRegistrationAmfNon3gppAccess(c *gin.Context) { logger.UecmLog.Infof("Handle RegisterAmfNon3gppAccessRequest") - // step 2: retrieve request ueID := c.Param("ueId") - // step 3: handle the message s.Processor().RegisterAmfNon3gppAccessProcedure(c, amfNon3GppAccessRegistration, ueID) } // RegistrationAmf3gppAccess - register as AMF for 3GPP access func (s *Server) HandleRegistrationAmf3gppAccess(c *gin.Context) { var amf3GppAccessRegistration models.Amf3GppAccessRegistration - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -196,7 +188,6 @@ func (s *Server) HandleRegistrationAmf3gppAccess(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&amf3GppAccessRegistration, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -210,21 +201,17 @@ func (s *Server) HandleRegistrationAmf3gppAccess(c *gin.Context) { return } - // step 1: log logger.UecmLog.Infof("Handle RegistrationAmf3gppAccess") - // step 2: retrieve request ueID := c.Param("ueId") logger.UecmLog.Info("UEID: ", ueID) - // step 3: handle the message s.Processor().RegistrationAmf3gppAccessProcedure(c, amf3GppAccessRegistration, ueID) } // UpdateAmfNon3gppAccess - update a parameter in the AMF registration for non-3GPP access func (s *Server) HandleUpdateAmfNon3gppAccess(c *gin.Context) { var amfNon3GppAccessRegistrationModification models.AmfNon3GppAccessRegistrationModification - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -238,7 +225,6 @@ func (s *Server) HandleUpdateAmfNon3gppAccess(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&amfNon3GppAccessRegistrationModification, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -252,13 +238,10 @@ func (s *Server) HandleUpdateAmfNon3gppAccess(c *gin.Context) { return } - // step 1: log logger.UecmLog.Infof("Handle UpdateAmfNon3gppAccessRequest") - // step 2: retrieve request ueID := c.Param("ueId") - // step 3: handle the message s.Processor().UpdateAmfNon3gppAccessProcedure(c, amfNon3GppAccessRegistrationModification, ueID) } @@ -266,7 +249,6 @@ func (s *Server) HandleUpdateAmfNon3gppAccess(c *gin.Context) { func (s *Server) HandleUpdateAmf3gppAccess(c *gin.Context) { var amf3GppAccessRegistrationModification models.Amf3GppAccessRegistrationModification - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -280,7 +262,6 @@ func (s *Server) HandleUpdateAmf3gppAccess(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&amf3GppAccessRegistrationModification, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -294,13 +275,10 @@ func (s *Server) HandleUpdateAmf3gppAccess(c *gin.Context) { return } - // step 1: log logger.UecmLog.Infof("Handle UpdateAmf3gppAccessRequest") - // step 2: retrieve request ueID := c.Param("ueId") - // step 3: handle the message s.Processor().UpdateAmf3gppAccessProcedure(c, amf3GppAccessRegistrationModification, ueID) } @@ -336,14 +314,11 @@ func (s *Server) HandleGetSmsf3gppAccess(c *gin.Context) { // DeregistrationSmfRegistrations - delete an SMF registration func (s *Server) HandleDeregistrationSmfRegistrations(c *gin.Context) { - // step 1: log logger.UecmLog.Infof("Handle DeregistrationSmfRegistrations") - // step 2: retrieve request ueID := c.Params.ByName("ueId") pduSessionID := c.Params.ByName("pduSessionId") - // step 3: handle the message s.Processor().DeregistrationSmfRegistrationsProcedure(c, ueID, pduSessionID) } @@ -351,7 +326,6 @@ func (s *Server) HandleDeregistrationSmfRegistrations(c *gin.Context) { func (s *Server) HandleRegistrationSmfRegistrations(c *gin.Context) { var smfRegistration models.SmfRegistration - // step 1: retrieve http request body requestBody, err := c.GetRawData() if err != nil { problemDetail := models.ProblemDetails{ @@ -365,7 +339,6 @@ func (s *Server) HandleRegistrationSmfRegistrations(c *gin.Context) { return } - // step 2: convert requestBody to openapi models err = openapi.Deserialize(&smfRegistration, requestBody, "application/json") if err != nil { problemDetail := "[Request Body] " + err.Error() @@ -379,14 +352,11 @@ func (s *Server) HandleRegistrationSmfRegistrations(c *gin.Context) { return } - // step 1: log logger.UecmLog.Infof("Handle RegistrationSmfRegistrations") - // step 2: retrieve request ueID := c.Params.ByName("ueId") pduSessionID := c.Params.ByName("pduSessionId") - // step 3: handle the message s.Processor().RegistrationSmfRegistrationsProcedure( c, &smfRegistration, @@ -397,13 +367,10 @@ func (s *Server) HandleRegistrationSmfRegistrations(c *gin.Context) { // GetAmf3gppAccess - retrieve the AMF registration for 3GPP access information func (s *Server) HandleGetAmf3gppAccess(c *gin.Context) { - // step 1: log logger.UecmLog.Infof("Handle HandleGetAmf3gppAccessRequest") - // step 2: retrieve request ueID := c.Param("ueId") supportedFeatures := c.Query("supported-features") - // step 3: handle the message s.Processor().GetAmf3gppAccessProcedure(c, ueID, supportedFeatures) } From 972efcfd849e27b45af765369a4c99862d89e284 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Thu, 27 Jun 2024 06:48:18 +0000 Subject: [PATCH 23/23] fix: fix PR comment --- internal/sbi/processor/generate_auth_data.go | 4 +-- internal/sbi/processor/notifier.go | 4 +-- internal/sbi/processor/parameter_provision.go | 2 +- internal/sbi/processor/processor.go | 6 ---- .../processor/subscriber_data_management.go | 30 +++++++++---------- .../sbi/processor/ue_context_management.go | 16 +++++----- 6 files changed, 28 insertions(+), 34 deletions(-) diff --git a/internal/sbi/processor/generate_auth_data.go b/internal/sbi/processor/generate_auth_data.go index 02283fa..7135558 100644 --- a/internal/sbi/processor/generate_auth_data.go +++ b/internal/sbi/processor/generate_auth_data.go @@ -89,7 +89,7 @@ func (p *Processor) ConfirmAuthDataProcedure(c *gin.Context, optInterface := optional.NewInterface(authEvent) createAuthParam.AuthEvent = optInterface - client, err := p.consumer.CreateUDMClientToUDR(supi) + client, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -147,7 +147,7 @@ func (p *Processor) GenerateAuthDataProcedure( logger.UeauLog.Tracef("supi conversion => [%s]", supi) - client, err := p.consumer.CreateUDMClientToUDR(supi) + client, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) diff --git a/internal/sbi/processor/notifier.go b/internal/sbi/processor/notifier.go index 60c6602..4e16b71 100644 --- a/internal/sbi/processor/notifier.go +++ b/internal/sbi/processor/notifier.go @@ -21,7 +21,7 @@ func (p *Processor) DataChangeNotificationProcedure(c *gin.Context, ue, _ := p.Context().UdmUeFindBySupi(supi) - clientAPI := p.consumer.GetSDMClient("DataChangeNotification") + clientAPI := p.Consumer().GetSDMClient("DataChangeNotification") var problemDetails *models.ProblemDetails for _, subscriptionDataSubscription := range ue.UdmSubsToNotify { @@ -65,7 +65,7 @@ func (p *Processor) SendOnDeregistrationNotification(ueId string, onDeregistrati return pd } - clientAPI := p.consumer.GetUECMClient("SendOnDeregistrationNotification") + clientAPI := p.Consumer().GetUECMClient("SendOnDeregistrationNotification") httpResponse, err := clientAPI.DeregistrationNotificationCallbackApi.DeregistrationNotify( ctx, onDeregistrationNotificationUrl, deregistData) diff --git a/internal/sbi/processor/parameter_provision.go b/internal/sbi/processor/parameter_provision.go index 8246cfd..bd72ea1 100644 --- a/internal/sbi/processor/parameter_provision.go +++ b/internal/sbi/processor/parameter_provision.go @@ -19,7 +19,7 @@ func (p *Processor) UpdateProcedure(c *gin.Context, c.JSON(int(pd.Status), pd) return } - clientAPI, err := p.consumer.CreateUDMClientToUDR(gpsi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(gpsi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go index b2e7aa4..5fe1516 100644 --- a/internal/sbi/processor/processor.go +++ b/internal/sbi/processor/processor.go @@ -13,17 +13,11 @@ type ProcessorUdm interface { type Processor struct { ProcessorUdm - consumer *consumer.Consumer } func NewProcessor(udm ProcessorUdm) (*Processor, error) { p := &Processor{ ProcessorUdm: udm, - consumer: udm.Consumer(), } return p, nil } - -func (p *Processor) Consumer() *consumer.Consumer { - return p.consumer -} diff --git a/internal/sbi/processor/subscriber_data_management.go b/internal/sbi/processor/subscriber_data_management.go index 9ceb83c..9efeced 100644 --- a/internal/sbi/processor/subscriber_data_management.go +++ b/internal/sbi/processor/subscriber_data_management.go @@ -23,7 +23,7 @@ func (p *Processor) GetAmDataProcedure(c *gin.Context, supi string, plmnID strin var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -77,7 +77,7 @@ func (p *Processor) GetIdTranslationResultProcedure(c *gin.Context, gpsi string) var idTranslationResult models.IdTranslationResult var getIdentityDataParamOpts Nudr_DataRepository.GetIdentityDataParamOpts - clientAPI, err := p.consumer.CreateUDMClientToUDR(gpsi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(gpsi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -150,7 +150,7 @@ func (p *Processor) GetSupiProcedure(c *gin.Context, return } - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -436,7 +436,7 @@ func (p *Processor) GetSharedDataProcedure(c *gin.Context, sharedDataIds []strin c.JSON(int(pd.Status), pd) return } - clientAPI, err := p.consumer.CreateUDMClientToUDR("") + clientAPI, err := p.Consumer().CreateUDMClientToUDR("") if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -498,7 +498,7 @@ func (p *Processor) GetSmDataProcedure( } logger.SdmLog.Infof("getSmDataProcedure: SUPI[%s] PLMNID[%s] DNN[%s] SNssai[%s]", supi, plmnID, Dnn, Snssai) - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -584,7 +584,7 @@ func (p *Processor) GetNssaiProcedure(c *gin.Context, supi string, plmnID string var queryAmDataParamOpts Nudr_DataRepository.QueryAmDataParamOpts queryAmDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) var nssaiResp models.Nssai - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -644,7 +644,7 @@ func (p *Processor) GetSmfSelectDataProcedure(c *gin.Context, supi string, plmnI querySmfSelectDataParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) var body models.SmfSelectionSubscriptionData - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -703,7 +703,7 @@ func (p *Processor) SubscribeToSharedDataProcedure(c *gin.Context, sdmSubscripti return } - udmClientAPI := p.consumer.GetSDMClient("subscribeToSharedData") + udmClientAPI := p.Consumer().GetSDMClient("subscribeToSharedData") sdmSubscriptionResp, res, err := udmClientAPI.SubscriptionCreationForSharedDataApi.SubscribeToSharedData( ctx, *sdmSubscription) @@ -758,7 +758,7 @@ func (p *Processor) SubscribeProcedure(c *gin.Context, sdmSubscription *models.S c.JSON(int(pd.Status), pd) return } - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -819,7 +819,7 @@ func (p *Processor) UnsubscribeForSharedDataProcedure(c *gin.Context, subscripti return } - udmClientAPI := p.consumer.GetSDMClient("unsubscribeForSharedData") + udmClientAPI := p.Consumer().GetSDMClient("unsubscribeForSharedData") res, err := udmClientAPI.SubscriptionDeletionForSharedDataApi.UnsubscribeForSharedData( ctx, subscriptionID) @@ -862,7 +862,7 @@ func (p *Processor) UnsubscribeProcedure(c *gin.Context, supi string, subscripti c.JSON(int(pd.Status), pd) return } - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -913,7 +913,7 @@ func (p *Processor) ModifyProcedure(c *gin.Context, c.JSON(int(pd.Status), pd) return } - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -972,7 +972,7 @@ func (p *Processor) ModifyForSharedDataProcedure(c *gin.Context, c.JSON(int(pd.Status), pd) return } - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -1028,7 +1028,7 @@ func (p *Processor) GetTraceDataProcedure(c *gin.Context, supi string, plmnID st var body models.TraceData var queryTraceDataParamOpts Nudr_DataRepository.QueryTraceDataParamOpts - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -1086,7 +1086,7 @@ func (p *Processor) GetUeContextInSmfDataProcedure(c *gin.Context, supi string, var querySmfRegListParamOpts Nudr_DataRepository.QuerySmfRegListParamOpts querySmfRegListParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - clientAPI, err := p.consumer.CreateUDMClientToUDR(supi) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(supi) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) diff --git a/internal/sbi/processor/ue_context_management.go b/internal/sbi/processor/ue_context_management.go index 705d159..091e650 100644 --- a/internal/sbi/processor/ue_context_management.go +++ b/internal/sbi/processor/ue_context_management.go @@ -24,7 +24,7 @@ func (p *Processor) GetAmf3gppAccessProcedure(c *gin.Context, ueID string, suppo var queryAmfContext3gppParamOpts Nudr_DataRepository.QueryAmfContext3gppParamOpts queryAmfContext3gppParamOpts.SupportedFeatures = optional.NewString(supportedFeatures) - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -58,7 +58,7 @@ func (p *Processor) GetAmfNon3gppAccessProcedure(c *gin.Context, queryAmfContext if err != nil { c.JSON(int(pd.Status), pd) } - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -105,7 +105,7 @@ func (p *Processor) RegistrationAmf3gppAccessProcedure(c *gin.Context, p.Context().CreateAmf3gppRegContext(ueID, registerRequest) - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -185,7 +185,7 @@ func (p *Processor) RegisterAmfNon3gppAccessProcedure(c *gin.Context, p.Context().CreateAmfNon3gppRegContext(ueID, registerRequest) - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -307,7 +307,7 @@ func (p *Processor) UpdateAmf3gppAccessProcedure(c *gin.Context, patchItemReqArray = append(patchItemReqArray, patchItemTmp) } - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -415,7 +415,7 @@ func (p *Processor) UpdateAmfNon3gppAccessProcedure(c *gin.Context, patchItemReqArray = append(patchItemReqArray, patchItemTmp) } - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -451,7 +451,7 @@ func (p *Processor) DeregistrationSmfRegistrationsProcedure(c *gin.Context, c.JSON(int(pd.Status), pd) return } - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails) @@ -504,7 +504,7 @@ func (p *Processor) RegistrationSmfRegistrationsProcedure( optInterface := optional.NewInterface(*smfRegistration) createSmfContextNon3gppParamOpts.SmfRegistration = optInterface - clientAPI, err := p.consumer.CreateUDMClientToUDR(ueID) + clientAPI, err := p.Consumer().CreateUDMClientToUDR(ueID) if err != nil { problemDetails := openapi.ProblemDetailsSystemFailure(err.Error()) c.JSON(int(problemDetails.Status), problemDetails)