Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Enable NRF response caching #135

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 54 additions & 22 deletions consumer/nf_discovery.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2019 free5GC.org
//
// SPDX-FileCopyrightText: 2024 Canonical Ltd.
// SPDX-License-Identifier: Apache-2.0
//

Expand All @@ -12,7 +12,8 @@ import (

"github.com/omec-project/openapi/Nnrf_NFDiscovery"
"github.com/omec-project/openapi/models"
udm_context "github.com/omec-project/udm/context"
nrfCache "github.com/omec-project/openapi/nrfcache"
udmContext "github.com/omec-project/udm/context"
"github.com/omec-project/udm/logger"
"github.com/omec-project/udm/util"
)
Expand All @@ -24,36 +25,67 @@ const (
NFDiscoveryToUDRParamGpsi
)

func SendNFIntances(nrfUri string, targetNfType, requestNfType models.NfType,
param Nnrf_NFDiscovery.SearchNFInstancesParamOpts,
) (result models.SearchResult, err error) {
configuration := Nnrf_NFDiscovery.NewConfiguration()
configuration.SetBasePath(nrfUri) // addr
clientNRF := Nnrf_NFDiscovery.NewAPIClient(configuration)
var (
CreateSubscription = SendCreateSubscription
NRFCacheSearchNFInstances = nrfCache.SearchNFInstances
StoreApiSearchNFInstances = (*Nnrf_NFDiscovery.NFInstancesStoreApiService).SearchNFInstances
)

result, res, err1 := clientNRF.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType,
requestNfType, &param)
if err1 != nil {
err = err1
return
var SendSearchNFInstances = func(nrfUri string, targetNfType, requestNfType models.NfType, param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts) (
models.SearchResult, error,
) {
if udmContext.UDM_Self().EnableNrfCaching {
return NRFCacheSearchNFInstances(nrfUri, targetNfType, requestNfType, param)
} else {
return SendNfDiscoveryToNrf(nrfUri, targetNfType, requestNfType, param)
}
}

var SendNfDiscoveryToNrf = func(nrfUri string, targetNfType, requesterNfType models.NfType, param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts,
) (models.SearchResult, error) {
// Set client and set url
configuration := Nnrf_NFDiscovery.NewConfiguration()
configuration.SetBasePath(nrfUri)
client := Nnrf_NFDiscovery.NewAPIClient(configuration)
result, res, err := StoreApiSearchNFInstances(client.NFInstancesStoreApi, context.TODO(), targetNfType, requesterNfType, param)
if res != nil && res.StatusCode == http.StatusTemporaryRedirect {
err = fmt.Errorf("temporary redirect for non NRF consumer")
}
defer func() {
if rspCloseErr := res.Body.Close(); rspCloseErr != nil {
logger.Handlelog.Errorf("SearchNFInstances response body cannot close: %+v", rspCloseErr)
if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil {
err = fmt.Errorf("SearchNFInstances' response body cannot close: %w", bodyCloseErr)
}
}()

if res != nil && res.StatusCode == http.StatusTemporaryRedirect {
err = fmt.Errorf("temporary Redirect For Non NRF Consumer")
udmSelf := udmContext.UDM_Self()
var nrfSubData models.NrfSubscriptionData
var problemDetails *models.ProblemDetails
for _, nfProfile := range result.NfInstances {
// checking whether the UDM subscribed to this target nfinstanceid or not
if _, ok := udmSelf.NfStatusSubscriptions.Load(nfProfile.NfInstanceId); !ok {
nrfSubscriptionData := models.NrfSubscriptionData{
NfStatusNotificationUri: fmt.Sprintf("%s/nudm-callback/v1/nf-status-notify", udmSelf.GetIPv4Uri()),
SubscrCond: &models.NfInstanceIdCond{NfInstanceId: nfProfile.NfInstanceId},
ReqNfType: requesterNfType,
}
nrfSubData, problemDetails, err = CreateSubscription(nrfUri, nrfSubscriptionData)
if problemDetails != nil {
logger.ConsumerLog.Errorf("SendCreateSubscription to NRF, Problem[%+v]", problemDetails)
} else if err != nil {
logger.ConsumerLog.Errorf("SendCreateSubscription Error[%+v]", err)
}
udmSelf.NfStatusSubscriptions.Store(nfProfile.NfInstanceId, nrfSubData.SubscriptionId)
}
}
return

return result, err
}

func SendNFIntancesUDR(id string, types int) string {
self := udm_context.UDM_Self()
func SendNFInstancesUDR(id string, types int) string {
self := udmContext.UDM_Self()
targetNfType := models.NfType_UDR
requestNfType := models.NfType_UDM
localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{
localVarOptionals := &Nnrf_NFDiscovery.SearchNFInstancesParamOpts{
// DataSet: optional.NewInterface(models.DataSetId_SUBSCRIPTION),
}
// switch types {
Expand All @@ -65,7 +97,7 @@ func SendNFIntancesUDR(id string, types int) string {
// localVarOptionals.Gpsi = optional.NewString(id)
// }
fmt.Println(self.NrfUri)
gab-arrobo marked this conversation as resolved.
Show resolved Hide resolved
result, err := SendNFIntances(self.NrfUri, targetNfType, requestNfType, localVarOptionals)
result, err := SendSearchNFInstances(self.NrfUri, targetNfType, requestNfType, localVarOptionals)
if err != nil {
logger.Handlelog.Error(err.Error())
return ""
Expand Down
79 changes: 69 additions & 10 deletions consumer/nf_management.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
// Copyright 2019 free5GC.org
//
// SPDX-FileCopyrightText: 2024 Canonical Ltd.
// SPDX-License-Identifier: Apache-2.0
//

Expand All @@ -16,11 +16,11 @@ import (
"github.com/omec-project/openapi"
"github.com/omec-project/openapi/Nnrf_NFManagement"
"github.com/omec-project/openapi/models"
udm_context "github.com/omec-project/udm/context"
udmContext "github.com/omec-project/udm/context"
"github.com/omec-project/udm/logger"
)

func BuildNFInstance(udmContext *udm_context.UDMContext) (profile models.NfProfile, err error) {
func BuildNFInstance(udmContext *udmContext.UDMContext) (profile models.NfProfile, err error) {
profile.NfInstanceId = udmContext.NfId
profile.NfStatus = models.NfStatus_REGISTERED
profile.NfType = models.NfType_UDM
Expand Down Expand Up @@ -52,7 +52,7 @@ func BuildNFInstance(udmContext *udm_context.UDMContext) (profile models.NfProfi
return
}

var SendRegisterNFInstance = func(nrfUri, nfInstanceId string, profile models.NfProfile) (prof models.NfProfile, resouceNrfUri string,
var SendRegisterNFInstance = func(nrfUri, nfInstanceId string, profile models.NfProfile) (prof models.NfProfile, resourceNrfUri string,
retrieveNfInstanceId string, err error,
) {
configuration := Nnrf_NFManagement.NewConfiguration()
Expand Down Expand Up @@ -81,21 +81,20 @@ var SendRegisterNFInstance = func(nrfUri, nfInstanceId string, profile models.Nf
} else if status == http.StatusCreated {
// NFRegister
resourceUri := res.Header.Get("Location")
resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")]
resourceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")]
retrieveNfInstanceId = resourceUri[strings.LastIndex(resourceUri, "/")+1:]
break
} else {
fmt.Println("handler returned wrong status code", status)
fmt.Println("NRF return wrong status code", status)
logger.ConsumerLog.Errorf("NRF returned wrong status code: %+v", status)
}
}
return prof, resouceNrfUri, retrieveNfInstanceId, err
return prof, resourceNrfUri, retrieveNfInstanceId, err
}

func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) {
logger.ConsumerLog.Infof("Send Deregister NFInstance")

udmSelf := udm_context.UDM_Self()
udmSelf := udmContext.UDM_Self()
// Set client and set url
configuration := Nnrf_NFManagement.NewConfiguration()
configuration.SetBasePath(udmSelf.NrfUri)
Expand Down Expand Up @@ -127,7 +126,7 @@ func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err erro
var SendUpdateNFInstance = func(patchItem []models.PatchItem) (nfProfile models.NfProfile, problemDetails *models.ProblemDetails, err error) {
logger.ConsumerLog.Debugf("Send Update NFInstance")

udmSelf := udm_context.UDM_Self()
udmSelf := udmContext.UDM_Self()
configuration := Nnrf_NFManagement.NewConfiguration()
configuration.SetBasePath(udmSelf.NrfUri)
client := Nnrf_NFManagement.NewAPIClient(configuration)
Expand All @@ -153,3 +152,63 @@ var SendUpdateNFInstance = func(patchItem []models.PatchItem) (nfProfile models.
}
return
}

func SendCreateSubscription(nrfUri string, nrfSubscriptionData models.NrfSubscriptionData) (nrfSubData models.NrfSubscriptionData, problemDetails *models.ProblemDetails, err error) {
logger.ConsumerLog.Debugf("Send Create Subscription")

// Set client and set url
configuration := Nnrf_NFManagement.NewConfiguration()
configuration.SetBasePath(nrfUri)
client := Nnrf_NFManagement.NewAPIClient(configuration)

var res *http.Response
nrfSubData, res, err = client.SubscriptionsCollectionApi.CreateSubscription(context.TODO(), nrfSubscriptionData)
if err == nil {
return
} else if res != nil {
defer func() {
if resCloseErr := res.Body.Close(); resCloseErr != nil {
logger.ConsumerLog.Errorf("SendCreateSubscription response cannot close: %+v", resCloseErr)
}
}()
if res.Status != err.Error() {
logger.ConsumerLog.Errorf("SendCreateSubscription received error response: %v", res.Status)
return
}
problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
} else {
err = openapi.ReportError("server no response")
}
return
}

func SendRemoveSubscription(subscriptionId string) (problemDetails *models.ProblemDetails, err error) {
logger.ConsumerLog.Infoln("Send Remove Subscription")

udmSelf := udmContext.UDM_Self()
// 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.SubscriptionIDDocumentApi.RemoveSubscription(context.Background(), subscriptionId)
if err == nil {
return
} else if res != nil {
defer func() {
if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil {
err = fmt.Errorf("RemoveSubscription's response body cannot close: %w", bodyCloseErr)
}
}()
if res.Status != err.Error() {
return
}
problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
} else {
err = openapi.ReportError("server no response")
}
return
}
6 changes: 5 additions & 1 deletion context/context.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
// Copyright 2019 free5GC.org
//
// SPDX-FileCopyrightText: 2024 Canonical Ltd.
// SPDX-License-Identifier: Apache-2.0
//

Expand All @@ -12,6 +12,7 @@ import (
"strconv"
"strings"
"sync"
"time"

"github.com/omec-project/openapi"
"github.com/omec-project/openapi/Nnrf_NFDiscovery"
Expand Down Expand Up @@ -50,10 +51,13 @@ type UDMContext struct {
GpsiSupiList models.IdentityData
SharedSubsDataMap map[string]models.SharedData // sharedDataIds as key
SubscriptionOfSharedDataChange sync.Map // subscriptionID as key
NfStatusSubscriptions sync.Map // map[NfInstanceID]models.NrfSubscriptionData.SubscriptionId
SuciProfiles []suci.SuciProfile
EeSubscriptionIDGenerator *idgenerator.IDGenerator
PlmnList []factory.PlmnSupportItem
SBIPort int
EnableNrfCaching bool
NrfCacheEvictionInterval time.Duration
}

type UdmUeContext struct {
Expand Down
20 changes: 11 additions & 9 deletions factory/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
// Copyright 2019 free5GC.org
//
// SPDX-FileCopyrightText: 2024 Canonical Ltd.
// SPDX-License-Identifier: Apache-2.0
//

Expand Down Expand Up @@ -37,14 +37,16 @@ const (
)

type Configuration struct {
UdmName string `yaml:"udmName,omitempty"`
Sbi *Sbi `yaml:"sbi,omitempty"`
ServiceNameList []string `yaml:"serviceNameList,omitempty"`
NrfUri string `yaml:"nrfUri,omitempty"`
WebuiUri string `yaml:"webuiUri"`
Keys *Keys `yaml:"keys,omitempty"`
PlmnSupportList []models.PlmnId `yaml:"plmnSupportList,omitempty"`
PlmnList []PlmnSupportItem `yaml:"plmnList,omitempty"`
UdmName string `yaml:"udmName,omitempty"`
Sbi *Sbi `yaml:"sbi,omitempty"`
ServiceList []string `yaml:"serviceList,omitempty"`
NrfUri string `yaml:"nrfUri,omitempty"`
WebuiUri string `yaml:"webuiUri"`
Keys *Keys `yaml:"keys,omitempty"`
PlmnSupportList []models.PlmnId `yaml:"plmnSupportList,omitempty"`
PlmnList []PlmnSupportItem `yaml:"plmnList,omitempty"`
EnableNrfCaching bool `yaml:"enableNrfCaching"`
NrfCacheEvictionInterval int `yaml:"nrfCacheEvictionInterval,omitempty"`
}

type Sbi struct {
Expand Down
4 changes: 3 additions & 1 deletion factory/udmcfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ configuration:
keys:
udmProfileAHNPrivateKey: whatever private key
nrfUri: https://nrf:443
enableNrfCaching: true
nrfCacheEvictionInterval: 900
sbi:
bindingIPv4: 0.0.0.0
port: 29503
Expand All @@ -14,7 +16,7 @@ configuration:
key: free5gc/support/TLS/udm.key
log: free5gc/udmsslkey.log
pem: free5gc/support/TLS/udm.pem
serviceNameList:
serviceList:
- nudm-sdm
- nudm-uecm
- nudm-ueau
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/gin-gonic/gin v1.10.0
github.com/google/uuid v1.6.0
github.com/omec-project/config5g v1.4.2
github.com/omec-project/openapi v1.2.0
github.com/omec-project/openapi v1.2.1
github.com/omec-project/util v1.1.0
github.com/prometheus/client_golang v1.20.0
github.com/sirupsen/logrus v1.9.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/omec-project/config5g v1.4.2 h1:Mujr5RVeSyPOBXxFhH0FUqwuES+WwnY3ltt3ULByeYQ=
github.com/omec-project/config5g v1.4.2/go.mod h1:r2v1CX9+Hye5SwQNieeSFEpDutGF5g9mLrIK+Ot9P5Q=
github.com/omec-project/openapi v1.2.0 h1:7Wvi0HLvhvxMyQtqGcqtMCPC/0QCGAFP5htrXCfWxRc=
github.com/omec-project/openapi v1.2.0/go.mod h1:hjU13MB1m9MHTko87JfsUNCdeD6/m6VkNZDD8Vq5U9M=
github.com/omec-project/openapi v1.2.1 h1:7ccFadoGfoqZq4sw7twXatbRGmkg4pARe6sWmCVVmrs=
github.com/omec-project/openapi v1.2.1/go.mod h1:hjU13MB1m9MHTko87JfsUNCdeD6/m6VkNZDD8Vq5U9M=
github.com/omec-project/util v1.1.0 h1:TUuLmzqTLChIEXQlK9g5Ihgmw4FUm/UJnjfu0wT8Gz0=
github.com/omec-project/util v1.1.0/go.mod h1:BEv8nCokB4j0fgAQ6VVkKuQ2PSP3DJMEmz25pFMw5X8=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
Expand Down
4 changes: 3 additions & 1 deletion logger/logger.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
// Copyright 2019 free5GC.org
//
// SPDX-FileCopyrightText: 2024 Canonical Ltd.
// SPDX-License-Identifier: Apache-2.0
//

Expand Down Expand Up @@ -31,6 +31,7 @@ var (
ConsumerLog *logrus.Entry
GinLog *logrus.Entry
GrpcLog *logrus.Entry
ProducerLog *logrus.Entry
)

func init() {
Expand Down Expand Up @@ -61,6 +62,7 @@ func init() {
ConsumerLog = log.WithFields(logrus.Fields{"component": "UDM", "category": "Consumer"})
GinLog = log.WithFields(logrus.Fields{"component": "UDM", "category": "GIN"})
GrpcLog = log.WithFields(logrus.Fields{"component": "UDM", "category": "GRPC"})
ProducerLog = log.WithFields(logrus.Fields{"component": "UDM", "category": "Producer"})
}

func SetLogLevel(level logrus.Level) {
Expand Down
Loading