From: elinuxhenrik Date: Mon, 28 Nov 2022 15:31:19 +0000 (+0100) Subject: Add more provider update functionality X-Git-Tag: 1.0.0~17 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=c58285c8b76f7833877e328f94e947b0384c4a86;p=nonrtric%2Fplt%2Fsme.git Add more provider update functionality Issue-ID: NONRTRIC-814 Signed-off-by: elinuxhenrik Change-Id: I34882dd4bdedf530638e22563d300ec4ea30b0c4 --- diff --git a/capifcore/internal/providermanagement/providermanagement.go b/capifcore/internal/providermanagement/providermanagement.go index 63ed4d8..82dfba2 100644 --- a/capifcore/internal/providermanagement/providermanagement.go +++ b/capifcore/internal/providermanagement/providermanagement.go @@ -21,6 +21,7 @@ package providermanagement import ( + "fmt" "net/http" "path" "strings" @@ -131,38 +132,95 @@ func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, r } func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error { + pm.lock.Lock() + defer pm.lock.Unlock() + + registeredProvider, shouldReturn, returnValue := pm.checkIfProviderIsRegistered(registrationId, ctx) + if shouldReturn { + return returnValue + } + + updatedProvider, shouldReturn1, returnValue1 := getProviderFromRequest(ctx) + if shouldReturn1 { + return returnValue1 + } + + if updatedProvider.ApiProvDomInfo != nil { + registeredProvider.ApiProvDomInfo = updatedProvider.ApiProvDomInfo + } + + shouldReturn, returnValue = pm.updateFunctions(updatedProvider, registeredProvider, ctx) + if shouldReturn { + return returnValue + } + + err := ctx.JSON(http.StatusOK, pm.onboardedProviders[registrationId]) + if 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, bool, error) { registeredProvider, ok := pm.onboardedProviders[registrationId] if !ok { - return sendCoreError(ctx, http.StatusBadRequest, "Provider must be onboarded before updating it") - + return provapi.APIProviderEnrolmentDetails{}, true, sendCoreError(ctx, http.StatusBadRequest, "Provider must be onboarded before updating it") } + return registeredProvider, false, nil +} +func getProviderFromRequest(ctx echo.Context) (provapi.APIProviderEnrolmentDetails, bool, error) { var updatedProvider provapi.APIProviderEnrolmentDetails err := ctx.Bind(&updatedProvider) if err != nil { - return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider") + return provapi.APIProviderEnrolmentDetails{}, true, sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider") } + return updatedProvider, false, nil +} - pm.lock.Lock() - defer pm.lock.Unlock() - +func (pm *ProviderManager) updateFunctions(updatedProvider provapi.APIProviderEnrolmentDetails, registeredProvider provapi.APIProviderEnrolmentDetails, ctx echo.Context) (bool, error) { for _, function := range *updatedProvider.ApiProvFuncs { if function.ApiProvFuncId == nil { - function.ApiProvFuncId = pm.getFuncId(function.ApiProvFuncRole, function.ApiProvFuncInfo) - registeredFuncs := *registeredProvider.ApiProvFuncs - newFuncs := append(registeredFuncs, function) - registeredProvider.ApiProvFuncs = &newFuncs - pm.onboardedProviders[*registeredProvider.ApiProvDomId] = registeredProvider + pm.addFunction(function, registeredProvider) + } else { + shouldReturn, returnValue := pm.updateFunction(function, registeredProvider, ctx) + if shouldReturn { + return true, returnValue + } } } + return false, nil +} - err = ctx.JSON(http.StatusOK, registeredProvider) +func (pm *ProviderManager) addFunction(function provapi.APIProviderFunctionDetails, registeredProvider provapi.APIProviderEnrolmentDetails) { + function.ApiProvFuncId = pm.getFuncId(function.ApiProvFuncRole, function.ApiProvFuncInfo) + registeredFuncs := *registeredProvider.ApiProvFuncs + newFuncs := append(registeredFuncs, function) + registeredProvider.ApiProvFuncs = &newFuncs + pm.onboardedProviders[*registeredProvider.ApiProvDomId] = registeredProvider +} + +func (*ProviderManager) updateFunction(function provapi.APIProviderFunctionDetails, registeredProvider provapi.APIProviderEnrolmentDetails, ctx echo.Context) (bool, error) { + pos, registeredFunction, err := getApiFunc(*function.ApiProvFuncId, registeredProvider.ApiProvFuncs) if err != nil { - // Something really bad happened, tell Echo that our handler failed - return err + return true, sendCoreError(ctx, http.StatusBadRequest, "Unable to update provider due to: "+err.Error()) + } + if function.ApiProvFuncInfo != nil { + registeredFunction.ApiProvFuncInfo = function.ApiProvFuncInfo + (*registeredProvider.ApiProvFuncs)[pos] = registeredFunction } + return false, nil +} - return nil +func getApiFunc(funcId string, apiFunctions *[]provapi.APIProviderFunctionDetails) (int, provapi.APIProviderFunctionDetails, error) { + for pos, function := range *apiFunctions { + if *function.ApiProvFuncId == funcId { + return pos, function, nil + } + } + return 0, provapi.APIProviderFunctionDetails{}, fmt.Errorf("function with ID %s is not registered for the provider", funcId) } func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error { diff --git a/capifcore/internal/providermanagement/providermanagement_test.go b/capifcore/internal/providermanagement/providermanagement_test.go index 8d8c9b4..b5c899b 100644 --- a/capifcore/internal/providermanagement/providermanagement_test.go +++ b/capifcore/internal/providermanagement/providermanagement_test.go @@ -49,7 +49,7 @@ var ( funcIdAEF = "AEF_id_rApp_as_AEF" ) -func TestProviderHandlingSuccessfully(t *testing.T) { +func TestRegisterValidProvider(t *testing.T) { managerUnderTest, requestHandler := getEcho() newProvider := getProvider() @@ -68,36 +68,91 @@ func TestProviderHandlingSuccessfully(t *testing.T) { assert.Empty(t, resultProvider.FailReason) assert.Equal(t, "http://example.com/registrations/"+*resultProvider.ApiProvDomId, result.Recorder.Header().Get(echo.HeaderLocation)) assert.True(t, managerUnderTest.IsFunctionRegistered("APF_id_rApp_as_APF")) +} + +func TestUpdateValidProvider(t *testing.T) { + managerUnderTest, requestHandler := getEcho() - // Update the provider - newProvider.ApiProvDomId = &domainID - (*newProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF - (*newProvider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF - (*newProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF + provider := getProvider() + provider.ApiProvDomId = &domainID + (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF + (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF + (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF + managerUnderTest.onboardedProviders[domainID] = provider + + // Modify the provider + updatedProvider := getProvider() + updatedProvider.ApiProvDomId = &domainID + (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF + (*updatedProvider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF + (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF + newDomainInfo := "New domain info" + updatedProvider.ApiProvDomInfo = &newDomainInfo + newFunctionInfo := "New function info" + (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo newFuncInfoAEF := "new func as AEF" - testFuncs := *newProvider.ApiProvFuncs + testFuncs := *updatedProvider.ApiProvFuncs testFuncs = append(testFuncs, provapi.APIProviderFunctionDetails{ ApiProvFuncInfo: &newFuncInfoAEF, - ApiProvFuncRole: "AEF", + ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF, }) - newProvider.ApiProvFuncs = &testFuncs + updatedProvider.ApiProvFuncs = &testFuncs - result = testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(newProvider).Go(t, requestHandler) + result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler) + var resultProvider provapi.APIProviderEnrolmentDetails assert.Equal(t, http.StatusOK, result.Code()) - err = result.UnmarshalBodyToObject(&resultProvider) + err := result.UnmarshalBodyToObject(&resultProvider) assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, newDomainInfo, *resultProvider.ApiProvDomInfo) + assert.Equal(t, newFunctionInfo, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncInfo) assert.Equal(t, *(*resultProvider.ApiProvFuncs)[3].ApiProvFuncId, "AEF_id_new_func_as_AEF") assert.Empty(t, resultProvider.FailReason) assert.True(t, managerUnderTest.IsFunctionRegistered("AEF_id_new_func_as_AEF")) +} - // Delete the provider - result = testutil.NewRequest().Delete("/registrations/"+*resultProvider.ApiProvDomId).Go(t, requestHandler) +func TestUpdateMissingFunction(t *testing.T) { + managerUnderTest, requestHandler := getEcho() - assert.Equal(t, http.StatusNoContent, result.Code()) - assert.False(t, managerUnderTest.IsFunctionRegistered("APF_id_rApp_as_APF")) + provider := getProvider() + provider.ApiProvDomId = &domainID + otherId := "otherId" + (*provider.ApiProvFuncs)[0].ApiProvFuncId = &otherId + (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF + (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF + managerUnderTest.onboardedProviders[domainID] = provider + + // Modify the provider + updatedProvider := getProvider() + updatedProvider.ApiProvDomId = &domainID + (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF + newFunctionInfo := "New function info" + (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo + + result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler) + + var errorObj common29122.ProblemDetails + assert.Equal(t, http.StatusBadRequest, result.Code()) + err := result.UnmarshalBodyToObject(&errorObj) + assert.NoError(t, err, "error unmarshaling response") + assert.Contains(t, *errorObj.Cause, funcIdAPF) + assert.Contains(t, *errorObj.Cause, "not registered") } +func TestDeleteProvider(t *testing.T) { + managerUnderTest, requestHandler := getEcho() + + provider := getProvider() + provider.ApiProvDomId = &domainID + (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF + managerUnderTest.onboardedProviders[domainID] = provider + assert.True(t, managerUnderTest.IsFunctionRegistered(funcIdAPF)) + + result := testutil.NewRequest().Delete("/registrations/"+domainID).Go(t, requestHandler) + + assert.Equal(t, http.StatusNoContent, result.Code()) + assert.False(t, managerUnderTest.IsFunctionRegistered(funcIdAPF)) +} func TestProviderHandlingValidation(t *testing.T) { _, requestHandler := getEcho() @@ -119,7 +174,12 @@ func TestProviderHandlingValidation(t *testing.T) { func TestGetExposedFunctionsForPublishingFunction(t *testing.T) { managerUnderTest := NewProviderManager() - managerUnderTest.onboardedProviders[domainID] = getProvider() + provider := getProvider() + provider.ApiProvDomId = &domainID + (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF + (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF + (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF + managerUnderTest.onboardedProviders[domainID] = provider managerUnderTest.onboardedProviders[otherDomainID] = getOtherProvider() exposedFuncs := managerUnderTest.GetAefsForPublisher(funcIdAPF) @@ -130,23 +190,19 @@ func TestGetExposedFunctionsForPublishingFunction(t *testing.T) { func getProvider() provapi.APIProviderEnrolmentDetails { testFuncs := []provapi.APIProviderFunctionDetails{ { - ApiProvFuncId: &funcIdAPF, ApiProvFuncInfo: &funcInfoAPF, ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF, }, { - ApiProvFuncId: &funcIdAMF, ApiProvFuncInfo: &funcInfoAMF, ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF, }, { - ApiProvFuncId: &funcIdAEF, ApiProvFuncInfo: &funcInfoAEF, ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF, }, } return provapi.APIProviderEnrolmentDetails{ - ApiProvDomId: &domainID, ApiProvDomInfo: &domainInfo, ApiProvFuncs: &testFuncs, }