X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=capifcore%2Finternal%2Fprovidermanagement%2Fprovidermanagement.go;h=5fa786c912d25524a321798ceab9c449ef7909d9;hb=8fa464fbe92fe7fa2107915accfe93cb932fb021;hp=0213e89f83da61572ca63b1ccc4f4e9e05f48804;hpb=6edc6544f698b8f5d923f3b2717ab103b7473dfe;p=nonrtric%2Fplt%2Fsme.git diff --git a/capifcore/internal/providermanagement/providermanagement.go b/capifcore/internal/providermanagement/providermanagement.go index 0213e89..5fa786c 100644 --- a/capifcore/internal/providermanagement/providermanagement.go +++ b/capifcore/internal/providermanagement/providermanagement.go @@ -2,7 +2,8 @@ // ========================LICENSE_START================================= // O-RAN-SC // %% -// Copyright (C) 2022: Nordix Foundation +// Copyright (C) 2022-2023: Nordix Foundation +// Copyright (C) 2024: OpenInfra Foundation Europe // %% // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,91 +25,92 @@ import ( "fmt" "net/http" "path" - "strings" "sync" - "github.com/labstack/echo/v4" + echo "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" "oransc.org/nonrtric/capifcore/internal/common29122" provapi "oransc.org/nonrtric/capifcore/internal/providermanagementapi" - - log "github.com/sirupsen/logrus" ) //go:generate mockery --name ServiceRegister type ServiceRegister interface { IsFunctionRegistered(functionId string) bool GetAefsForPublisher(apfId string) []string + IsPublishingFunctionRegistered(apiProvFuncId string) bool } type ProviderManager struct { - onboardedProviders map[string]provapi.APIProviderEnrolmentDetails - lock sync.Mutex + registeredProviders map[string]provapi.APIProviderEnrolmentDetails + lock sync.Mutex } func NewProviderManager() *ProviderManager { return &ProviderManager{ - onboardedProviders: make(map[string]provapi.APIProviderEnrolmentDetails), + registeredProviders: make(map[string]provapi.APIProviderEnrolmentDetails), } } func (pm *ProviderManager) IsFunctionRegistered(functionId string) bool { - registered := false -out: - for _, provider := range pm.onboardedProviders { - for _, registeredFunc := range *provider.ApiProvFuncs { - if *registeredFunc.ApiProvFuncId == functionId { - registered = true - break out - } + for _, provider := range pm.registeredProviders { + if provider.IsFunctionRegistered(functionId) { + return true } } - - return registered + return false } func (pm *ProviderManager) GetAefsForPublisher(apfId string) []string { - for _, provider := range pm.onboardedProviders { - for _, registeredFunc := range *provider.ApiProvFuncs { - if *registeredFunc.ApiProvFuncId == apfId && registeredFunc.ApiProvFuncRole == provapi.ApiProviderFuncRoleAPF { - return getExposedFuncs(provider.ApiProvFuncs) - } + for _, provider := range pm.registeredProviders { + if aefs := provider.GetExposingFunctionIdsForPublisher(apfId); aefs != nil { + return aefs } } return nil } -func getExposedFuncs(providerFuncs *[]provapi.APIProviderFunctionDetails) []string { - exposedFuncs := []string{} - for _, registeredFunc := range *providerFuncs { - if registeredFunc.ApiProvFuncRole == provapi.ApiProviderFuncRoleAEF { - exposedFuncs = append(exposedFuncs, *registeredFunc.ApiProvFuncId) +func (pm *ProviderManager) IsPublishingFunctionRegistered(apiProvFuncId string) bool { + for _, provider := range pm.registeredProviders { + if provider.IsPublishingFunctionRegistered(apiProvFuncId) { + return true } } - return exposedFuncs + return false } func (pm *ProviderManager) PostRegistrations(ctx echo.Context) error { var newProvider provapi.APIProviderEnrolmentDetails - err := ctx.Bind(&newProvider) - if err != nil { - return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider") + errMsg := "Unable to register provider due to %s" + if err := ctx.Bind(&newProvider); err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, "invalid format for provider")) + } + + if err := pm.isProviderRegistered(newProvider); err != nil { + return sendCoreError(ctx, http.StatusForbidden, fmt.Sprintf(errMsg, err)) } - if newProvider.ApiProvDomInfo == nil || *newProvider.ApiProvDomInfo == "" { - return sendCoreError(ctx, http.StatusBadRequest, "Provider missing required ApiProvDomInfo") + if err := newProvider.Validate(); err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } pm.prepareNewProvider(&newProvider) uri := ctx.Request().Host + ctx.Request().URL.String() ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newProvider.ApiProvDomId)) - err = ctx.JSON(http.StatusCreated, newProvider) - if err != nil { + if err := ctx.JSON(http.StatusCreated, newProvider); err != nil { // Something really bad happened, tell Echo that our handler failed return err } + return nil +} +func (pm *ProviderManager) isProviderRegistered(newProvider provapi.APIProviderEnrolmentDetails) error { + for _, prov := range pm.registeredProviders { + if err := prov.ValidateAlreadyRegistered(newProvider); err != nil { + return err + } + } return nil } @@ -116,19 +118,15 @@ func (pm *ProviderManager) prepareNewProvider(newProvider *provapi.APIProviderEn pm.lock.Lock() defer pm.lock.Unlock() - newProvider.ApiProvDomId = pm.getDomainId(newProvider.ApiProvDomInfo) - - pm.registerFunctions(newProvider.ApiProvFuncs) - pm.onboardedProviders[*newProvider.ApiProvDomId] = *newProvider + newProvider.PrepareNewProvider() + pm.registeredProviders[*newProvider.ApiProvDomId] = *newProvider } func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, registrationId string) error { - - log.Debug(pm.onboardedProviders) - if _, ok := pm.onboardedProviders[registrationId]; ok { + log.Debug(pm.registeredProviders) + if _, ok := pm.registeredProviders[registrationId]; ok { pm.deleteProvider(registrationId) } - return ctx.NoContent(http.StatusNoContent) } @@ -136,15 +134,12 @@ func (pm *ProviderManager) deleteProvider(registrationId string) { log.Debug("Deleting provider", registrationId) pm.lock.Lock() defer pm.lock.Unlock() - delete(pm.onboardedProviders, registrationId) + delete(pm.registeredProviders, registrationId) } func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error { - pm.lock.Lock() - defer pm.lock.Unlock() - errMsg := "Unable to update provider due to %s." - registeredProvider, err := pm.checkIfProviderIsRegistered(registrationId, ctx) + registeredProvider, err := pm.checkIfProviderIsRegistered(registrationId) if err != nil { return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } @@ -154,25 +149,33 @@ func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, regi return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } - updateDomainInfo(&updatedProvider, registeredProvider) + if updatedProvider.Validate() != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) + } - registeredProvider.ApiProvFuncs, err = updateFuncs(updatedProvider.ApiProvFuncs, registeredProvider.ApiProvFuncs) - if err != nil { + // Additional validation for PUT + if (updatedProvider.ApiProvDomId == nil) || (*updatedProvider.ApiProvDomId != registrationId) { + errDetail := "APIProviderEnrolmentDetails ApiProvDomId doesn't match path parameter" + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, errDetail)) + } + + if err = pm.updateProvider(updatedProvider, registeredProvider); err != nil { return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } - pm.onboardedProviders[*registeredProvider.ApiProvDomId] = *registeredProvider - err = ctx.JSON(http.StatusOK, *registeredProvider) - if err != nil { + if err = ctx.JSON(http.StatusOK, updatedProvider); err != nil { // Something really bad happened, tell Echo that our handler failed return err } - return nil } -func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string, ctx echo.Context) (*provapi.APIProviderEnrolmentDetails, error) { - registeredProvider, ok := pm.onboardedProviders[registrationId] +func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error { + return ctx.NoContent(http.StatusNotImplemented) +} + +func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string) (*provapi.APIProviderEnrolmentDetails, error) { + registeredProvider, ok := pm.registeredProviders[registrationId] if !ok { return nil, fmt.Errorf("provider not onboarded") } @@ -188,75 +191,16 @@ func getProviderFromRequest(ctx echo.Context) (provapi.APIProviderEnrolmentDetai return updatedProvider, nil } -func updateDomainInfo(updatedProvider, registeredProvider *provapi.APIProviderEnrolmentDetails) { - if updatedProvider.ApiProvDomInfo != nil { - registeredProvider.ApiProvDomInfo = updatedProvider.ApiProvDomInfo - } -} - -func updateFuncs(updatedFuncs, registeredFuncs *[]provapi.APIProviderFunctionDetails) (*[]provapi.APIProviderFunctionDetails, error) { - addedFuncs := []provapi.APIProviderFunctionDetails{} - changedFuncs := []provapi.APIProviderFunctionDetails{} - for _, function := range *updatedFuncs { - if function.ApiProvFuncId == nil { - function.ApiProvFuncId = getFuncId(function.ApiProvFuncRole, function.ApiProvFuncInfo) - addedFuncs = append(addedFuncs, function) - } else { - registeredFunction, ok := getApiFunc(*function.ApiProvFuncId, registeredFuncs) - if !ok { - return nil, fmt.Errorf("function with ID %s is not registered for the provider", *function.ApiProvFuncId) - } - if function.ApiProvFuncInfo != nil { - registeredFunction.ApiProvFuncInfo = function.ApiProvFuncInfo - } - changedFuncs = append(changedFuncs, function) - } - } - modifiedFuncs := append(changedFuncs, addedFuncs...) - return &modifiedFuncs, nil -} - -func getApiFunc(funcId string, apiFunctions *[]provapi.APIProviderFunctionDetails) (provapi.APIProviderFunctionDetails, bool) { - for _, function := range *apiFunctions { - if *function.ApiProvFuncId == funcId { - return function, true - } - } - return provapi.APIProviderFunctionDetails{}, false -} - -func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error { - return ctx.NoContent(http.StatusNotImplemented) -} - -func (pm *ProviderManager) registerFunctions(provFuncs *[]provapi.APIProviderFunctionDetails) { - if provFuncs == nil { - return - } - for i, provFunc := range *provFuncs { - (*provFuncs)[i].ApiProvFuncId = getFuncId(provFunc.ApiProvFuncRole, provFunc.ApiProvFuncInfo) - } -} - -func (pm *ProviderManager) getDomainId(domainInfo *string) *string { - idAsString := "domain_id_" + strings.ReplaceAll(*domainInfo, " ", "_") - return &idAsString -} +func (pm *ProviderManager) updateProvider(updatedProvider provapi.APIProviderEnrolmentDetails, registeredProvider *provapi.APIProviderEnrolmentDetails) error { + pm.lock.Lock() + defer pm.lock.Unlock() -func getFuncId(role provapi.ApiProviderFuncRole, funcInfo *string) *string { - var idPrefix string - switch role { - case provapi.ApiProviderFuncRoleAPF: - idPrefix = "APF_id_" - case provapi.ApiProviderFuncRoleAMF: - idPrefix = "AMF_id_" - case provapi.ApiProviderFuncRoleAEF: - idPrefix = "AEF_id_" - default: - idPrefix = "function_id_" + if err := updatedProvider.UpdateFuncs(*registeredProvider); err == nil { + pm.registeredProviders[*updatedProvider.ApiProvDomId] = updatedProvider + return nil + } else { + return err } - idAsString := idPrefix + strings.ReplaceAll(*funcInfo, " ", "_") - return &idAsString } // This function wraps sending of an error in the Error format, and