diff --git a/internal/sbi/consumer/udr_service.go b/internal/sbi/consumer/udr_service.go index e9643bb..a337ca8 100644 --- a/internal/sbi/consumer/udr_service.go +++ b/internal/sbi/consumer/udr_service.go @@ -1,10 +1,13 @@ package consumer import ( + "errors" "strconv" "strings" "sync" + "github.com/antihax/optional" + "github.com/free5gc/openapi" "github.com/free5gc/openapi/Nudr_DataRepository" "github.com/free5gc/openapi/models" @@ -43,6 +46,53 @@ func (s *nudrService) getDataSubscription(uri string) *Nudr_DataRepository.APICl return client } +func (s *nudrService) GetAfInfluenceData( + ue *pcf_context.UeContext, + supi, dnn string, + interGrpIds []string, + sliceInfo *models.Snssai, +) ( + tiData []models.TrafficInfluData, + problemDetails *models.ProblemDetails, + err error, +) { + client := s.getDataSubscription(ue.UdrUri) + ctx, pd, err := s.consumer.Context().GetTokenCtx( + models.ServiceName_NUDR_DR, + models.NfType_UDR) + if err != nil { + return []models.TrafficInfluData{}, pd, err + } + + param := &Nudr_DataRepository.ApplicationDataInfluenceDataGetParamOpts{ + Dnns: optional.NewInterface([]string{dnn}), + Snssais: optional.NewInterface( + util.MarshToJsonString([]models.Snssai{*sliceInfo}), + ), + Supis: optional.NewInterface([]string{supi}), + InfluenceIds: optional.NewInterface(interGrpIds), + } + + tiData, rsp, err := client.InfluenceDataApi.ApplicationDataInfluenceDataGet(ctx, param) + defer func() { + if rsp != nil { + if rsp.Body != nil { + if rsp.Body.Close() != nil { + logger.ConsumerLog.Errorf("getAfInfluenceData response body cannot close") + } + } + } + }() + if err != nil { + apiError := new(openapi.GenericOpenAPIError) + if ok := errors.As(err, &apiError); ok { + problemDetails = apiError.Model().(*models.ProblemDetails) + } + } + + return tiData, problemDetails, err +} + func (s *nudrService) CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.SmPolicyContextData) ( subscriptionID string, problemDetails *models.ProblemDetails, err error, ) { diff --git a/internal/sbi/processor/ampolicy.go b/internal/sbi/processor/ampolicy.go index 546d1b9..ef4e7b8 100644 --- a/internal/sbi/processor/ampolicy.go +++ b/internal/sbi/processor/ampolicy.go @@ -421,8 +421,8 @@ func (p *Processor) SendAMPolicyTerminationRequestNotification(ue *pcf_context.U // returns UDR Uri of Ue, if ue.UdrUri dose not exist, query NRF to get supported Udr Uri func (p *Processor) getUdrUri(ue *pcf_context.UeContext) string { - if ue.UdrUri != "" { - return ue.UdrUri + if ue.UdrUri == "" { + ue.UdrUri = p.Consumer().SendNFInstancesUDR(p.Context().NrfUri, ue.Supi) } - return p.Consumer().SendNFInstancesUDR(p.Context().NrfUri, ue.Supi) + return ue.UdrUri } diff --git a/internal/sbi/processor/smpolicy.go b/internal/sbi/processor/smpolicy.go index 9a2da32..668a595 100644 --- a/internal/sbi/processor/smpolicy.go +++ b/internal/sbi/processor/smpolicy.go @@ -206,6 +206,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( } chargingInterface, err := mongoapi.RestfulAPIGetOne(chargingDataColl, filterCharging, queryStrength) + var defaultChgData *models.ChargingData if err != nil { logger.SmPolicyLog.Errorf("Fail to get charging data to mongoDB err: %+v", err) @@ -225,6 +226,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( ReportingLevel: models.ReportingLevel_RAT_GR_LEVEL, MeteringMethod: models.MeteringMethod_VOLUME, } + defaultChgData = chgData switch chargingInterface["chargingMethod"].(string) { case "Online": @@ -250,6 +252,8 @@ func (p *Processor) HandleCreateSmPolicyRequest( smPolicyData.ChargingIdGenerator++ } + chgDataMap := map[string]*models.ChargingData{} + logger.SmPolicyLog.Traceln("FlowRules for ueId:", ue.Supi, "snssai:", util.SnssaiModelsToHex(*request.SliceInfo)) for i, flowRule := range flowRulesInterface { logger.SmPolicyLog.Tracef("flowRule %d: %s\n", i, openapi.MarshToJsonString(flowRule)) @@ -321,6 +325,7 @@ func (p *Processor) HandleCreateSmPolicyRequest( ReportingLevel: models.ReportingLevel_RAT_GR_LEVEL, MeteringMethod: models.MeteringMethod_VOLUME, } + chgDataMap[val] = chgData switch chargingInterface["chargingMethod"].(string) { case "Online": @@ -367,35 +372,27 @@ func (p *Processor) HandleCreateSmPolicyRequest( smPolicyData.PolicyDecision = &decision // TODO: PCC rule, PraInfo ... // Get Application Data Influence Data from UDR - reqParam := Nudr_DataRepository.ApplicationDataInfluenceDataGetParamOpts{ - Dnns: optional.NewInterface([]string{request.Dnn}), - Snssais: optional.NewInterface(util.MarshToJsonString([]models.Snssai{*request.SliceInfo})), - InternalGroupIds: optional.NewInterface(request.InterGrpIds), - Supis: optional.NewInterface([]string{request.Supi}), - } - ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR) + trafficInfluDatas, pd, err := p.Consumer().GetAfInfluenceData( + ue, + request.Supi, + request.Dnn, + request.InterGrpIds, + request.SliceInfo, + ) if err != nil { c.JSON(int(pd.Status), pd) return } - udrClient := util.GetNudrClient(udrUri) - var resp *http.Response - trafficInfluDatas, resp, err := udrClient.InfluenceDataApi. - ApplicationDataInfluenceDataGet(ctx, &reqParam) - if err != nil || resp == nil || resp.StatusCode != http.StatusOK { - logger.SmPolicyLog.Warnf("Error response from UDR Application Data Influence Data Get") - } - if err = resp.Body.Close(); err != nil { - logger.SmPolicyLog.Warnf("failed to close response of Application Data Influence Data Get") - } logger.SmPolicyLog.Infof("Matched [%d] trafficInfluDatas from UDR", len(trafficInfluDatas)) if len(trafficInfluDatas) != 0 { // UE identity in UDR appData and apply appData to sm poliocy var precedence int32 = 23 for _, tiData := range trafficInfluDatas { pccRule := util.CreatePccRule(smPolicyData.PccRuleIdGenerator, precedence, nil, tiData.AfAppId) + // TODO: select charging data based on the filter (see chgDataMap) + util.SetPccRuleRelatedData(&decision, pccRule, nil, nil, defaultChgData, nil) util.SetSmPolicyDecisionByTrafficInfluData(&decision, pccRule, tiData) influenceID := getInfluenceID(tiData.ResUri) if influenceID != "" { @@ -436,13 +433,13 @@ func (p *Processor) HandleCreateSmPolicyRequest( if bsfUri != "" { bsfClient := util.GetNbsfClient(bsfUri) - ctx, pd, err = p.Context().GetTokenCtx(models.ServiceName_NBSF_MANAGEMENT, models.NfType_BSF) + ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NBSF_MANAGEMENT, models.NfType_BSF) if err != nil { c.JSON(int(pd.Status), pd) return } - _, resp, err = bsfClient.PCFBindingsCollectionApi.CreatePCFBinding(ctx, pcfBinding) + _, resp, err := bsfClient.PCFBindingsCollectionApi.CreatePCFBinding(ctx, pcfBinding) if err != nil || resp == nil || resp.StatusCode != http.StatusCreated { logger.SmPolicyLog.Warnf("Create PCF binding data in BSF error[%+v]", err) // Uncomment the following to return error response --> PDU SessEstReq will fail