From dfdc927e01e3bb72a2051c8da300a31adfee17f4 Mon Sep 17 00:00:00 2001 From: Tang Date: Fri, 17 Jan 2025 09:15:07 +0800 Subject: [PATCH 1/4] feat: modify for indirect communication --- internal/context/context.go | 12 +++++ internal/sbi/processor/nf_discovery.go | 61 +++++++++++++++++++++++++ internal/sbi/processor/nf_management.go | 17 +++++++ 3 files changed, 90 insertions(+) diff --git a/internal/context/context.go b/internal/context/context.go index 3dcea3f..a90d4c8 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -28,6 +28,11 @@ type NRFContext struct { NrfCert *x509.Certificate NfRegistNum int nfRegistNumLock sync.RWMutex + ScpUri string + ScpIp string + ScpPortInt int + ScpHasRegister bool + ScpRegisterLock sync.RWMutex } const ( @@ -48,6 +53,7 @@ func InitNrfContext() error { config.Info.Version, config.Info.Description) configuration := config.Configuration + nrfContext.ModifyScpHasRegister(false) nrfContext.NrfNfProfile.NfInstanceId = uuid.New().String() nrfContext.NrfNfProfile.NfType = models.NfType_NRF nrfContext.NrfNfProfile.NfStatus = models.NfStatus_REGISTERED @@ -226,3 +232,9 @@ func (ctx *NRFContext) DelNfRegister() { defer ctx.nfRegistNumLock.Unlock() ctx.NfRegistNum -= 1 } + +func (ctx *NRFContext) ModifyScpHasRegister(value bool) { + ctx.nfRegistNumLock.Lock() + defer ctx.nfRegistNumLock.Unlock() + ctx.ScpHasRegister = value +} diff --git a/internal/sbi/processor/nf_discovery.go b/internal/sbi/processor/nf_discovery.go index 2524077..f83c5e7 100644 --- a/internal/sbi/processor/nf_discovery.go +++ b/internal/sbi/processor/nf_discovery.go @@ -50,6 +50,7 @@ func validateQueryParameters(queryParameters url.Values) bool { "BSF": true, "CHF": true, "NWDAF": true, + "SCP": true, } var tgt, req string if queryParameters["target-nf-type"] != nil { @@ -173,6 +174,66 @@ func (p *Processor) NFDiscoveryProcedure(c *gin.Context, queryParameters url.Val } validityPeriod := 100 + // Indirect Communication, only the following NF pairs support indirect communication + nrfSelf := nrf_context.GetSelf() + scpEnable := nrfSelf.ScpHasRegister + if scpEnable { + supportNFPairForIndirectCommunication := false + npPairs := map[string][]string{ + "AMF": {"AUSF", "SMF"}, + "AUSF": {"UDM", "AMF"}, + "UDM": {"UDR", "AUSF"}, + "UDR": {"UDM", "NEF"}, + "SMF": {"AMF"}, + "NEF": {"UDR"}, + } + sourceNF := "" + targetNF := "" + if values, exists := queryParameters["requester-nf-type"]; exists && len(values) > 0 { + sourceNF = values[0] + } + if values, exists := queryParameters["target-nf-type"]; exists && len(values) > 0 { + targetNF = values[0] + } + + if validTargets, exists := npPairs[sourceNF]; exists { + for _, validTarget := range validTargets { + if validTarget == targetNF { + supportNFPairForIndirectCommunication = true + } + } + } + if supportNFPairForIndirectCommunication { + logger.DiscLog.Infof( + "Discovery with indirect communication, the message will pass to SCP: [%v]", + ScpUri + ) + if len(nfProfilesStruct) > 0 { + for i := range nfProfilesStruct { + nfProfilesStruct[i].Ipv4Addresses[0] = ScpUri + + if nfProfilesStruct[i].NfServices != nil { + for j := range *nfProfilesStruct[i].NfServices { + nfService := &(*nfProfilesStruct[i].NfServices)[j] + + if nfService.IpEndPoints != nil { + for k := range *nfService.IpEndPoints { + ipEndPoint := &(*nfService.IpEndPoints)[k] + ipEndPoint.Ipv4Address = nrfSelf.ScpIp + ipEndPoint.Port = nrfSelf.ScpPortInt + } + } + // for UDM search + if nfService.ApiPrefix != "" { + nfService.ApiPrefix = nrfSelf.ScpUri + } + } + } + } + } + } + } + // Build SearchResult model searchResult := &models.SearchResult{ ValidityPeriod: int32(validityPeriod), diff --git a/internal/sbi/processor/nf_management.go b/internal/sbi/processor/nf_management.go index 29692b8..6e96824 100644 --- a/internal/sbi/processor/nf_management.go +++ b/internal/sbi/processor/nf_management.go @@ -42,6 +42,20 @@ func (p *Processor) HandleGetNFInstanceRequest(c *gin.Context, nfInstanceId stri func (p *Processor) HandleNFRegisterRequest(c *gin.Context, nfProfile models.NfProfile) { logger.NfmLog.Infoln("Handle NFRegisterRequest") + logger.NfmLog.Infof("NfProfile: %v", nfProfile) + // Set ScpUri for support indirect communication + // TODO: Support multiple SCP situation (This version only support for a single SCP) + if nfProfile.NfType == models.NfType_SCP { + nrfSelf := nrf_context.GetSelf() + nrfSelf.ModifyScpHasRegister(true) + ScpIp := nfProfile.Ipv4Addresses[0] + ScpUri := "http://" + ScpIp + ":8000" // default port + nrfSelf.ScpUri = ScpUri + nrfSelf.ScpIp = ScpIp + nrfSelf.ScpPortInt = 8000 + logger.NfmLog.Infof("Recieve SCP register request, ScpUri: %v", ScpUri) + } + p.NFRegisterProcedure(c, nfProfile) } @@ -320,6 +334,9 @@ func (p *Processor) NFDeregisterProcedure(nfInstanceID string) *models.ProblemDe logger.NfmLog.Warningf("Can not delete NFCertPem file: %v: %v", nfCertPath, removeErr) } } + if nfInstanceType == models.NfType_SCP { + nrf_context.GetSelf().ModifyScpHasRegister(false) + } // Minus NF Register Conter p.Context().DelNfRegister() logger.NfmLog.Infof("NfDeregister Success: %v [%v]", nfInstanceType, nfInstanceID) From eeead1e06982356e81db7bcb7df543688c4dc1b7 Mon Sep 17 00:00:00 2001 From: mamie1031 Date: Sun, 19 Jan 2025 17:16:18 -0800 Subject: [PATCH 2/4] fix: modify for runing successfully --- internal/sbi/processor/nf_discovery.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/sbi/processor/nf_discovery.go b/internal/sbi/processor/nf_discovery.go index f83c5e7..64e0a96 100644 --- a/internal/sbi/processor/nf_discovery.go +++ b/internal/sbi/processor/nf_discovery.go @@ -50,7 +50,7 @@ func validateQueryParameters(queryParameters url.Values) bool { "BSF": true, "CHF": true, "NWDAF": true, - "SCP": true, + "SCP": true, } var tgt, req string if queryParameters["target-nf-type"] != nil { @@ -206,21 +206,21 @@ func (p *Processor) NFDiscoveryProcedure(c *gin.Context, queryParameters url.Val if supportNFPairForIndirectCommunication { logger.DiscLog.Infof( "Discovery with indirect communication, the message will pass to SCP: [%v]", - ScpUri + nrfSelf.ScpUri, ) if len(nfProfilesStruct) > 0 { for i := range nfProfilesStruct { - nfProfilesStruct[i].Ipv4Addresses[0] = ScpUri - + nfProfilesStruct[i].Ipv4Addresses[0] = nrfSelf.ScpUri + if nfProfilesStruct[i].NfServices != nil { for j := range *nfProfilesStruct[i].NfServices { nfService := &(*nfProfilesStruct[i].NfServices)[j] - + if nfService.IpEndPoints != nil { for k := range *nfService.IpEndPoints { ipEndPoint := &(*nfService.IpEndPoints)[k] ipEndPoint.Ipv4Address = nrfSelf.ScpIp - ipEndPoint.Port = nrfSelf.ScpPortInt + ipEndPoint.Port = int32(nrfSelf.ScpPortInt) } } // for UDM search From a4a63fb120f374b62b6df58e7c0d3597343c635a Mon Sep 17 00:00:00 2001 From: mamie1031 Date: Wed, 29 Jan 2025 19:14:39 -0800 Subject: [PATCH 3/4] refactor: add comments based on PR feedback and improve code structure --- internal/context/context.go | 17 ++++++++++------- internal/sbi/processor/nf_discovery.go | 19 ++++++++++--------- internal/sbi/processor/nf_management.go | 11 +++-------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/internal/context/context.go b/internal/context/context.go index a90d4c8..3b03713 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -28,11 +28,11 @@ type NRFContext struct { NrfCert *x509.Certificate NfRegistNum int nfRegistNumLock sync.RWMutex - ScpUri string + ScpUri string ScpIp string ScpPortInt int ScpHasRegister bool - ScpRegisterLock sync.RWMutex + ScpInfoLock sync.RWMutex } const ( @@ -53,7 +53,7 @@ func InitNrfContext() error { config.Info.Version, config.Info.Description) configuration := config.Configuration - nrfContext.ModifyScpHasRegister(false) + nrfContext.ModifyScpIpInfo(false, "", "", -1) // Initiation for SCP info nrfContext.NrfNfProfile.NfInstanceId = uuid.New().String() nrfContext.NrfNfProfile.NfType = models.NfType_NRF nrfContext.NrfNfProfile.NfStatus = models.NfStatus_REGISTERED @@ -233,8 +233,11 @@ func (ctx *NRFContext) DelNfRegister() { ctx.NfRegistNum -= 1 } -func (ctx *NRFContext) ModifyScpHasRegister(value bool) { - ctx.nfRegistNumLock.Lock() - defer ctx.nfRegistNumLock.Unlock() - ctx.ScpHasRegister = value +func (ctx *NRFContext) ModifyScpIpInfo(hasRegister bool, uri string, ip string, port int) { + ctx.ScpInfoLock.Lock() + defer ctx.ScpInfoLock.Unlock() + ctx.ScpHasRegister = hasRegister + ctx.ScpUri = uri + ctx.ScpIp = ip + ctx.ScpPortInt = port } diff --git a/internal/sbi/processor/nf_discovery.go b/internal/sbi/processor/nf_discovery.go index 64e0a96..ec53036 100644 --- a/internal/sbi/processor/nf_discovery.go +++ b/internal/sbi/processor/nf_discovery.go @@ -174,18 +174,19 @@ func (p *Processor) NFDiscoveryProcedure(c *gin.Context, queryParameters url.Val } validityPeriod := 100 - // Indirect Communication, only the following NF pairs support indirect communication + // Indirect communication implementation nrfSelf := nrf_context.GetSelf() scpEnable := nrfSelf.ScpHasRegister if scpEnable { supportNFPairForIndirectCommunication := false - npPairs := map[string][]string{ - "AMF": {"AUSF", "SMF"}, - "AUSF": {"UDM", "AMF"}, - "UDM": {"UDR", "AUSF"}, - "UDR": {"UDM", "NEF"}, - "SMF": {"AMF"}, - "NEF": {"UDR"}, + // Only the following NF pairs support indirect communication + nfPairs := map[string][]string{ + "AMF": {"AUSF", "SMF"}, // AMF consumes AUSF, SMF (via SCP) + "AUSF": {"UDM", "AMF"}, // AUSF consumes UDM, AMF + "UDM": {"UDR", "AUSF"}, // UDM consumes UDR, AUSF + "UDR": {"UDM", "NEF"}, // UDR consumes UDM, NEF + "SMF": {"AMF"}, // SMF consumes AMF + "NEF": {"UDR"}, // NEF consumes UDR } sourceNF := "" targetNF := "" @@ -196,7 +197,7 @@ func (p *Processor) NFDiscoveryProcedure(c *gin.Context, queryParameters url.Val targetNF = values[0] } - if validTargets, exists := npPairs[sourceNF]; exists { + if validTargets, exists := nfPairs[sourceNF]; exists { for _, validTarget := range validTargets { if validTarget == targetNF { supportNFPairForIndirectCommunication = true diff --git a/internal/sbi/processor/nf_management.go b/internal/sbi/processor/nf_management.go index 6e96824..217eb92 100644 --- a/internal/sbi/processor/nf_management.go +++ b/internal/sbi/processor/nf_management.go @@ -41,19 +41,14 @@ func (p *Processor) HandleGetNFInstanceRequest(c *gin.Context, nfInstanceId stri func (p *Processor) HandleNFRegisterRequest(c *gin.Context, nfProfile models.NfProfile) { logger.NfmLog.Infoln("Handle NFRegisterRequest") - - logger.NfmLog.Infof("NfProfile: %v", nfProfile) // Set ScpUri for support indirect communication // TODO: Support multiple SCP situation (This version only support for a single SCP) if nfProfile.NfType == models.NfType_SCP { nrfSelf := nrf_context.GetSelf() - nrfSelf.ModifyScpHasRegister(true) ScpIp := nfProfile.Ipv4Addresses[0] ScpUri := "http://" + ScpIp + ":8000" // default port - nrfSelf.ScpUri = ScpUri - nrfSelf.ScpIp = ScpIp - nrfSelf.ScpPortInt = 8000 - logger.NfmLog.Infof("Recieve SCP register request, ScpUri: %v", ScpUri) + nrfSelf.ModifyScpIpInfo(true, ScpUri, ScpIp, 8000) + logger.NfmLog.Infof("Receive SCP register request, ScpUri: %v", ScpUri) } p.NFRegisterProcedure(c, nfProfile) @@ -335,7 +330,7 @@ func (p *Processor) NFDeregisterProcedure(nfInstanceID string) *models.ProblemDe } } if nfInstanceType == models.NfType_SCP { - nrf_context.GetSelf().ModifyScpHasRegister(false) + nrf_context.GetSelf().ModifyScpIpInfo(false, "", "", -1) } // Minus NF Register Conter p.Context().DelNfRegister() From 9b46c3ddc07f691eee9cc7fcdb497081d8d39d76 Mon Sep 17 00:00:00 2001 From: mamie1031 Date: Mon, 3 Feb 2025 17:06:02 -0800 Subject: [PATCH 4/4] refactor: Modify the code for updating the SCP URI to NFRegisterProcedure --- internal/sbi/processor/nf_management.go | 43 +++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/internal/sbi/processor/nf_management.go b/internal/sbi/processor/nf_management.go index 217eb92..4ee2be1 100644 --- a/internal/sbi/processor/nf_management.go +++ b/internal/sbi/processor/nf_management.go @@ -41,15 +41,6 @@ func (p *Processor) HandleGetNFInstanceRequest(c *gin.Context, nfInstanceId stri func (p *Processor) HandleNFRegisterRequest(c *gin.Context, nfProfile models.NfProfile) { logger.NfmLog.Infoln("Handle NFRegisterRequest") - // Set ScpUri for support indirect communication - // TODO: Support multiple SCP situation (This version only support for a single SCP) - if nfProfile.NfType == models.NfType_SCP { - nrfSelf := nrf_context.GetSelf() - ScpIp := nfProfile.Ipv4Addresses[0] - ScpUri := "http://" + ScpIp + ":8000" // default port - nrfSelf.ModifyScpIpInfo(true, ScpUri, ScpIp, 8000) - logger.NfmLog.Infof("Receive SCP register request, ScpUri: %v", ScpUri) - } p.NFRegisterProcedure(c, nfProfile) } @@ -329,6 +320,7 @@ func (p *Processor) NFDeregisterProcedure(nfInstanceID string) *models.ProblemDe logger.NfmLog.Warningf("Can not delete NFCertPem file: %v: %v", nfCertPath, removeErr) } } + // Set SCP to unable if nfInstanceType == models.NfType_SCP { nrf_context.GetSelf().ModifyScpIpInfo(false, "", "", -1) } @@ -481,6 +473,22 @@ func (p *Processor) NFRegisterProcedure( } } + // Set scp uri for support indirect communication + // TODO: Support multiple SCP situation (This version only support for a single SCP) + if nfProfile.NfType == models.NfType_SCP && len(nfProfile.Ipv4Addresses) > 0 { + if len(nfProfile.Ipv4Addresses[0]) > 0 { + nrfSelf := nrf_context.GetSelf() + ScpIp := nfProfile.Ipv4Addresses[0] + ScpUri := "http://" + ScpIp + ":8000" // default port + nrfSelf.ModifyScpIpInfo(true, ScpUri, ScpIp, 8000) + logger.NfmLog.Infof("Update ScpUri: %v", ScpUri) + } else { + logger.NfmLog.Warnln("SCP registration request received but missing IP address.") + } + } else { + logger.NfmLog.Warnln("SCP registration request received but missing IP address.") + } + c.Writer.Header().Add("Location", locationHeaderValue) c.JSON(http.StatusOK, putData) return @@ -501,6 +509,23 @@ func (p *Processor) NFRegisterProcedure( return } } + + // Set SCP uri for support indirect communication + // TODO: Support multiple SCP situation (This version only support for a single SCP) + if nfProfile.NfType == models.NfType_SCP && len(nfProfile.Ipv4Addresses) > 0 { + if len(nfProfile.Ipv4Addresses[0]) > 0 { + nrfSelf := nrf_context.GetSelf() + ScpIp := nfProfile.Ipv4Addresses[0] + ScpUri := "http://" + ScpIp + ":8000" // default port + nrfSelf.ModifyScpIpInfo(true, ScpUri, ScpIp, 8000) + logger.NfmLog.Infof("Receive SCP register request, ScpUri: %v", ScpUri) + } else { + logger.NfmLog.Warnln("SCP registration request received but missing IP address.") + } + } else { + logger.NfmLog.Warnln("SCP registration request received but missing IP address.") + } + c.Writer.Header().Add("Location", locationHeaderValue) if factory.NrfConfig.GetOAuth() {