Refactor providermaagement
Move functionality for accessing and handling apit ypes from providermanagement to providermanagamentapi to enhance separation.
Issue-ID: NONRTRIC-814
Signed-off-by: elinuxhenrik <henrik.b.andersson@est.tech>
Change-Id: Ia6db81d3b1cb593567544f372763b63655a8b9f7
diff --git a/capifcore/internal/providermanagement/providermanagement.go b/capifcore/internal/providermanagement/providermanagement.go
index ea1f1e6..cb76c3a 100644
--- a/capifcore/internal/providermanagement/providermanagement.go
+++ b/capifcore/internal/providermanagement/providermanagement.go
@@ -24,7 +24,6 @@
"fmt"
"net/http"
"path"
- "strings"
"sync"
"github.com/labstack/echo/v4"
@@ -53,62 +52,41 @@
}
func (pm *ProviderManager) IsFunctionRegistered(functionId string) bool {
- registered := false
-out:
for _, provider := range pm.registeredProviders {
- for _, registeredFunc := range *provider.ApiProvFuncs {
- if *registeredFunc.ApiProvFuncId == functionId {
- registered = true
- break out
- }
+ if provider.IsFunctionRegistered(functionId) {
+ return true
}
}
-
- return registered
+ return false
}
func (pm *ProviderManager) GetAefsForPublisher(apfId string) []string {
for _, provider := range pm.registeredProviders {
- for _, registeredFunc := range *provider.ApiProvFuncs {
- if *registeredFunc.ApiProvFuncId == apfId && registeredFunc.ApiProvFuncRole == provapi.ApiProviderFuncRoleAPF {
- return getExposedFuncs(provider.ApiProvFuncs)
- }
+ 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)
- }
- }
- return exposedFuncs
-}
-
func (pm *ProviderManager) PostRegistrations(ctx echo.Context) error {
var newProvider provapi.APIProviderEnrolmentDetails
- err := ctx.Bind(&newProvider)
- if err != nil {
+ if err := ctx.Bind(&newProvider); err != nil {
return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider")
}
- 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("Provider not valid due to %s", 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
}
@@ -116,19 +94,15 @@
pm.lock.Lock()
defer pm.lock.Unlock()
- newProvider.ApiProvDomId = pm.getDomainId(newProvider.ApiProvDomInfo)
-
- pm.registerFunctions(newProvider.ApiProvFuncs)
+ newProvider.PrepareNewProvider()
pm.registeredProviders[*newProvider.ApiProvDomId] = *newProvider
}
func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
-
log.Debug(pm.registeredProviders)
if _, ok := pm.registeredProviders[registrationId]; ok {
pm.deleteProvider(registrationId)
}
-
return ctx.NoContent(http.StatusNoContent)
}
@@ -151,20 +125,25 @@
return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
}
- err = pm.updateProvider(updatedProvider, registeredProvider)
- if err != nil {
+ if updatedProvider.Validate() != nil {
return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
}
- err = ctx.JSON(http.StatusOK, *registeredProvider)
- if err != nil {
+ if err = pm.updateProvider(updatedProvider, registeredProvider); err != nil {
+ return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
+ }
+
+ 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) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error {
+ return ctx.NoContent(http.StatusNotImplemented)
+}
+
func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string, ctx echo.Context) (*provapi.APIProviderEnrolmentDetails, error) {
registeredProvider, ok := pm.registeredProviders[registrationId]
if !ok {
@@ -186,87 +165,12 @@
pm.lock.Lock()
defer pm.lock.Unlock()
- updateDomainInfo(&updatedProvider, registeredProvider)
-
- funcsAfterUpdate, err := updateFuncs(updatedProvider.ApiProvFuncs, registeredProvider.ApiProvFuncs)
- if err == nil {
- registeredProvider.ApiProvFuncs = funcsAfterUpdate
-
- pm.registeredProviders[*registeredProvider.ApiProvDomId] = *registeredProvider
+ if err := updatedProvider.UpdateFuncs(*registeredProvider); err == nil {
+ pm.registeredProviders[*updatedProvider.ApiProvDomId] = updatedProvider
return nil
+ } else {
+ return err
}
- return err
-}
-
-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 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_"
- }
- idAsString := idPrefix + strings.ReplaceAll(*funcInfo, " ", "_")
- return &idAsString
}
// This function wraps sending of an error in the Error format, and
diff --git a/capifcore/internal/providermanagement/providermanagement_test.go b/capifcore/internal/providermanagement/providermanagement_test.go
index 7373ac7..de647fa 100644
--- a/capifcore/internal/providermanagement/providermanagement_test.go
+++ b/capifcore/internal/providermanagement/providermanagement_test.go
@@ -95,6 +95,9 @@
testFuncs = append(testFuncs, provapi.APIProviderFunctionDetails{
ApiProvFuncInfo: &newFuncInfoAEF,
ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
+ RegInfo: provapi.RegistrationInformation{
+ ApiProvPubKey: "key",
+ },
})
updatedProvider.ApiProvFuncs = &testFuncs
@@ -190,7 +193,7 @@
newProvider := provapi.APIProviderEnrolmentDetails{}
- // Register a valid provider
+ // Register an invalid provider
result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
assert.Equal(t, http.StatusBadRequest, result.Code())
@@ -199,8 +202,8 @@
assert.NoError(t, err, "error unmarshaling response")
badRequest := http.StatusBadRequest
assert.Equal(t, &badRequest, problemDetails.Status)
- errMsg := "Provider missing required ApiProvDomInfo"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, "Provider not valid")
+ assert.Contains(t, *problemDetails.Cause, "regSec")
}
func TestGetExposedFunctionsForPublishingFunction(t *testing.T) {
@@ -224,17 +227,27 @@
{
ApiProvFuncInfo: &funcInfoAPF,
ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
+ RegInfo: provapi.RegistrationInformation{
+ ApiProvPubKey: "key",
+ },
},
{
ApiProvFuncInfo: &funcInfoAMF,
ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
+ RegInfo: provapi.RegistrationInformation{
+ ApiProvPubKey: "key",
+ },
},
{
ApiProvFuncInfo: &funcInfoAEF,
ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
+ RegInfo: provapi.RegistrationInformation{
+ ApiProvPubKey: "key",
+ },
},
}
return provapi.APIProviderEnrolmentDetails{
+ RegSec: "sec",
ApiProvDomInfo: &domainInfo,
ApiProvFuncs: &testFuncs,
}
diff --git a/capifcore/internal/providermanagementapi/typeaccess.go b/capifcore/internal/providermanagementapi/typeaccess.go
new file mode 100644
index 0000000..78b68c0
--- /dev/null
+++ b/capifcore/internal/providermanagementapi/typeaccess.go
@@ -0,0 +1,57 @@
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2023: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package providermanagementapi
+
+func (ed APIProviderEnrolmentDetails) GetExposingFunctionIdsForPublisher(apfId string) []string {
+ for _, registeredFunc := range *ed.ApiProvFuncs {
+ if *registeredFunc.ApiProvFuncId == apfId && registeredFunc.isProvidingFunction() {
+ return ed.getExposingFunctionIds()
+ }
+ }
+ return nil
+}
+
+func (ed APIProviderEnrolmentDetails) getExposingFunctionIds() []string {
+ exposedFuncs := []string{}
+ for _, registeredFunc := range *ed.ApiProvFuncs {
+ if registeredFunc.isExposingFunction() {
+ exposedFuncs = append(exposedFuncs, *registeredFunc.ApiProvFuncId)
+ }
+ }
+ return exposedFuncs
+}
+
+func (ed APIProviderEnrolmentDetails) IsFunctionRegistered(functionId string) bool {
+ for _, registeredFunc := range *ed.ApiProvFuncs {
+ if *registeredFunc.ApiProvFuncId == functionId {
+ return true
+ }
+ }
+ return false
+}
+
+func (fd APIProviderFunctionDetails) isProvidingFunction() bool {
+ return fd.ApiProvFuncRole == ApiProviderFuncRoleAPF
+}
+
+func (fd APIProviderFunctionDetails) isExposingFunction() bool {
+ return fd.ApiProvFuncRole == ApiProviderFuncRoleAEF
+}
diff --git a/capifcore/internal/providermanagementapi/typeaccess_test.go b/capifcore/internal/providermanagementapi/typeaccess_test.go
new file mode 100644
index 0000000..e108185
--- /dev/null
+++ b/capifcore/internal/providermanagementapi/typeaccess_test.go
@@ -0,0 +1,52 @@
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2023: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package providermanagementapi
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGetExposedFunctionIds(t *testing.T) {
+ providerUnderTest := getProvider()
+
+ exposedFuncs := providerUnderTest.GetExposingFunctionIdsForPublisher(funcIdAPF)
+
+ assert.Len(t, exposedFuncs, 1)
+ assert.Equal(t, funcIdAEF, exposedFuncs[0])
+
+ exposedFuncs = providerUnderTest.GetExposingFunctionIdsForPublisher("anyId")
+
+ assert.Len(t, exposedFuncs, 0)
+}
+
+func TestIsFunctionRegistered(t *testing.T) {
+ providerUnderTest := getProvider()
+
+ registered := providerUnderTest.IsFunctionRegistered(funcIdAPF)
+
+ assert.True(t, registered)
+
+ registered = providerUnderTest.IsFunctionRegistered("anyID")
+
+ assert.False(t, registered)
+}
diff --git a/capifcore/internal/providermanagementapi/typeupdate.go b/capifcore/internal/providermanagementapi/typeupdate.go
new file mode 100644
index 0000000..cbeb1cd
--- /dev/null
+++ b/capifcore/internal/providermanagementapi/typeupdate.go
@@ -0,0 +1,94 @@
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2023: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package providermanagementapi
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/google/uuid"
+)
+
+var uuidFunc = getUUID
+
+func (ed *APIProviderEnrolmentDetails) UpdateFuncs(registeredProvider APIProviderEnrolmentDetails) error {
+ for pos, function := range *ed.ApiProvFuncs {
+ if function.ApiProvFuncId == nil {
+ (*ed.ApiProvFuncs)[pos].ApiProvFuncId = getFuncId(function.ApiProvFuncRole, function.ApiProvFuncInfo)
+ } else {
+ if !registeredProvider.IsFunctionRegistered(*function.ApiProvFuncId) {
+ return fmt.Errorf("function with ID %s is not registered for the provider", *function.ApiProvFuncId)
+ }
+ }
+ }
+ return nil
+}
+
+func (ed *APIProviderEnrolmentDetails) PrepareNewProvider() {
+ ed.ApiProvDomId = ed.getDomainId()
+
+ ed.registerFunctions()
+
+}
+
+func (ed *APIProviderEnrolmentDetails) getDomainId() *string {
+ var idAsString string
+ if ed.ApiProvDomInfo != nil {
+ idAsString = strings.ReplaceAll(*ed.ApiProvDomInfo, " ", "_")
+ } else {
+ idAsString = uuidFunc()
+ }
+ newId := "domain_id_" + idAsString
+ return &newId
+}
+
+func (ed *APIProviderEnrolmentDetails) registerFunctions() {
+ if ed.ApiProvFuncs == nil {
+ return
+ }
+ for i, provFunc := range *ed.ApiProvFuncs {
+ (*ed.ApiProvFuncs)[i].ApiProvFuncId = getFuncId(provFunc.ApiProvFuncRole, provFunc.ApiProvFuncInfo)
+ }
+}
+
+func getFuncId(role ApiProviderFuncRole, funcInfo *string) *string {
+ var idPrefix string
+ switch role {
+ case ApiProviderFuncRoleAPF:
+ idPrefix = "APF_id_"
+ case ApiProviderFuncRoleAMF:
+ idPrefix = "AMF_id_"
+ case ApiProviderFuncRoleAEF:
+ idPrefix = "AEF_id_"
+ }
+ var id string
+ if funcInfo != nil {
+ id = strings.ReplaceAll(*funcInfo, " ", "_")
+ } else {
+ id = uuidFunc()
+ }
+ idAsString := idPrefix + id
+ return &idAsString
+}
+
+func getUUID() string {
+ return uuid.NewString()
+}
diff --git a/capifcore/internal/providermanagementapi/typeupdate_test.go b/capifcore/internal/providermanagementapi/typeupdate_test.go
new file mode 100644
index 0000000..f693359
--- /dev/null
+++ b/capifcore/internal/providermanagementapi/typeupdate_test.go
@@ -0,0 +1,83 @@
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2023: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package providermanagementapi
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPrepareNewProvider(t *testing.T) {
+ domainInfo := "domain info"
+ funcInfo := "func info"
+ providerUnderTest := APIProviderEnrolmentDetails{
+ ApiProvDomInfo: &domainInfo,
+ ApiProvFuncs: &[]APIProviderFunctionDetails{
+ {
+ ApiProvFuncRole: ApiProviderFuncRoleAPF,
+ ApiProvFuncInfo: &funcInfo,
+ },
+ {
+ ApiProvFuncRole: ApiProviderFuncRoleAEF,
+ },
+ },
+ }
+ uuidFunc = func() string {
+ return "1"
+ }
+
+ providerUnderTest.PrepareNewProvider()
+
+ assert.Equal(t, "domain_id_domain_info", *providerUnderTest.ApiProvDomId)
+ assert.Equal(t, "APF_id_func_info", *(*providerUnderTest.ApiProvFuncs)[0].ApiProvFuncId)
+ assert.Equal(t, "AEF_id_1", *(*providerUnderTest.ApiProvFuncs)[1].ApiProvFuncId)
+
+ providerUnderTest = APIProviderEnrolmentDetails{}
+
+ providerUnderTest.PrepareNewProvider()
+
+ assert.Equal(t, "domain_id_1", *providerUnderTest.ApiProvDomId)
+}
+
+func TestUpdateFuncs(t *testing.T) {
+ registeredProvider := getProvider()
+
+ funcInfo := "func info"
+ updatedFuncs := []APIProviderFunctionDetails{
+ (*registeredProvider.ApiProvFuncs)[0],
+ (*registeredProvider.ApiProvFuncs)[2],
+ {
+ ApiProvFuncRole: ApiProviderFuncRoleAEF,
+ ApiProvFuncInfo: &funcInfo,
+ },
+ }
+ providerUnderTest := APIProviderEnrolmentDetails{
+ ApiProvFuncs: &updatedFuncs,
+ }
+ err := providerUnderTest.UpdateFuncs(registeredProvider)
+
+ assert.Nil(t, err)
+ assert.Len(t, *providerUnderTest.ApiProvFuncs, 3)
+ assert.Equal(t, funcIdAPF, *(*providerUnderTest.ApiProvFuncs)[0].ApiProvFuncId)
+ assert.Equal(t, funcIdAEF, *(*providerUnderTest.ApiProvFuncs)[1].ApiProvFuncId)
+ assert.Equal(t, "AEF_id_func_info", *(*providerUnderTest.ApiProvFuncs)[2].ApiProvFuncId)
+}
diff --git a/capifcore/internal/providermanagementapi/typevalidation.go b/capifcore/internal/providermanagementapi/typevalidation.go
new file mode 100644
index 0000000..1b2e582
--- /dev/null
+++ b/capifcore/internal/providermanagementapi/typevalidation.go
@@ -0,0 +1,66 @@
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2023: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package providermanagementapi
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+func (ri RegistrationInformation) Validate() error {
+ if len(strings.TrimSpace(ri.ApiProvPubKey)) == 0 {
+ return errors.New("RegistrationInformation missing required apiProvPubKey")
+ }
+ return nil
+}
+
+func (fd APIProviderFunctionDetails) Validate() error {
+ switch role := fd.ApiProvFuncRole; role {
+ case ApiProviderFuncRoleAEF:
+ case ApiProviderFuncRoleAPF:
+ case ApiProviderFuncRoleAMF:
+ default:
+ return errors.New("APIProviderFunctionDetails missing required apiProvFuncRole")
+ }
+
+ return fd.RegInfo.Validate()
+}
+
+func (pd APIProviderEnrolmentDetails) Validate() error {
+ if len(strings.TrimSpace(pd.RegSec)) == 0 {
+ return errors.New("APIProviderEnrolmentDetails missing required regSec")
+ }
+ if pd.ApiProvFuncs != nil {
+ return pd.validateFunctions()
+ }
+ return nil
+}
+
+func (pd APIProviderEnrolmentDetails) validateFunctions() error {
+ for _, function := range *pd.ApiProvFuncs {
+ err := function.Validate()
+ if err != nil {
+ return fmt.Errorf("apiProvFuncs contains invalid function: %s", err)
+ }
+ }
+ return nil
+}
diff --git a/capifcore/internal/providermanagementapi/typevalidation_test.go b/capifcore/internal/providermanagementapi/typevalidation_test.go
new file mode 100644
index 0000000..fb5ad81
--- /dev/null
+++ b/capifcore/internal/providermanagementapi/typevalidation_test.go
@@ -0,0 +1,166 @@
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2023: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package providermanagementapi
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+var (
+ domainID = "domain_id_rApp_domain"
+ otherDomainID = "domain_id_other_domain"
+ domainInfo = "rApp domain"
+ funcInfoAPF = "rApp as APF"
+ funcIdAPF = "APF_id_rApp_as_APF"
+ funcInfoAMF = "rApp as AMF"
+ funcIdAMF = "AMF_id_rApp_as_AMF"
+ funcInfoAEF = "rApp as AEF"
+ funcIdAEF = "AEF_id_rApp_as_AEF"
+)
+
+func TestValidateRegistrationInformation(t *testing.T) {
+ regInfoUnderTest := RegistrationInformation{}
+ err := regInfoUnderTest.Validate()
+ if assert.Error(t, err) {
+ assert.Contains(t, err.Error(), "missing")
+ assert.Contains(t, err.Error(), "apiProvPubKey")
+ }
+
+ regInfoUnderTest.ApiProvPubKey = "key"
+ err = regInfoUnderTest.Validate()
+ assert.Nil(t, err)
+}
+
+func TestValidateAPIProviderFunctionDetails(t *testing.T) {
+ funcDetailsUnderTest := APIProviderFunctionDetails{}
+ err := funcDetailsUnderTest.Validate()
+ if assert.Error(t, err) {
+ assert.Contains(t, err.Error(), "missing")
+ assert.Contains(t, err.Error(), "apiProvFuncRole")
+ }
+
+ funcDetailsUnderTest.ApiProvFuncRole = ApiProviderFuncRoleAEF
+ err = funcDetailsUnderTest.Validate()
+ if assert.Error(t, err) {
+ assert.Contains(t, err.Error(), "missing")
+ assert.Contains(t, err.Error(), "apiProvPubKey")
+ }
+
+ funcDetailsUnderTest.RegInfo = RegistrationInformation{
+ ApiProvPubKey: "key",
+ }
+ assert.Nil(t, funcDetailsUnderTest.Validate())
+}
+
+func TestValidateAPIProviderEnrolmentDetails(t *testing.T) {
+ providerDetailsUnderTest := APIProviderEnrolmentDetails{}
+ err := providerDetailsUnderTest.Validate()
+ if assert.Error(t, err) {
+ assert.Contains(t, err.Error(), "missing")
+ assert.Contains(t, err.Error(), "regSec")
+ }
+
+ providerDetailsUnderTest.RegSec = "sec"
+ funcs := []APIProviderFunctionDetails{{}}
+ providerDetailsUnderTest.ApiProvFuncs = &funcs
+ err = providerDetailsUnderTest.Validate()
+ if assert.Error(t, err) {
+ assert.Contains(t, err.Error(), "apiProvFuncs")
+ assert.Contains(t, err.Error(), "contains invalid")
+ }
+}
+
+func TestUpdateFuncs_addNewFunction(t *testing.T) {
+ providerUnderTest := getProvider()
+
+ newFuncInfoAEF := "new func as AEF"
+ newFuncs := append(*providerUnderTest.ApiProvFuncs, APIProviderFunctionDetails{
+ ApiProvFuncInfo: &newFuncInfoAEF,
+ ApiProvFuncRole: ApiProviderFuncRoleAEF,
+ })
+ providerUnderTest.ApiProvFuncs = &newFuncs
+
+ err := providerUnderTest.UpdateFuncs(getProvider())
+
+ assert.Nil(t, err)
+ assert.Len(t, *providerUnderTest.ApiProvFuncs, 4)
+ assert.True(t, providerUnderTest.IsFunctionRegistered("AEF_id_new_func_as_AEF"))
+}
+
+func TestUpdateFuncs_deleteFunction(t *testing.T) {
+ providerUnderTest := getProvider()
+
+ modFuncs := []APIProviderFunctionDetails{(*providerUnderTest.ApiProvFuncs)[0], (*providerUnderTest.ApiProvFuncs)[1]}
+ providerUnderTest.ApiProvFuncs = &modFuncs
+
+ err := providerUnderTest.UpdateFuncs(getProvider())
+
+ assert.Nil(t, err)
+ assert.Len(t, *providerUnderTest.ApiProvFuncs, 2)
+ assert.True(t, providerUnderTest.IsFunctionRegistered(funcIdAPF))
+ assert.True(t, providerUnderTest.IsFunctionRegistered(funcIdAMF))
+}
+
+func TestUpdateFuncs_unregisteredFunction(t *testing.T) {
+ providerUnderTest := getProvider()
+
+ unRegId := "unRegId"
+ modFuncs := []APIProviderFunctionDetails{
+ {
+ ApiProvFuncId: &unRegId,
+ },
+ }
+ providerUnderTest.ApiProvFuncs = &modFuncs
+
+ err := providerUnderTest.UpdateFuncs(getProvider())
+ if assert.Error(t, err) {
+ assert.Contains(t, err.Error(), unRegId)
+ assert.Contains(t, err.Error(), "not registered")
+ }
+}
+
+func getProvider() APIProviderEnrolmentDetails {
+ testFuncs := []APIProviderFunctionDetails{
+ {
+ ApiProvFuncId: &funcIdAPF,
+ ApiProvFuncInfo: &funcInfoAPF,
+ ApiProvFuncRole: ApiProviderFuncRoleAPF,
+ },
+ {
+ ApiProvFuncId: &funcIdAMF,
+ ApiProvFuncInfo: &funcInfoAMF,
+ ApiProvFuncRole: ApiProviderFuncRoleAMF,
+ },
+ {
+ ApiProvFuncId: &funcIdAEF,
+ ApiProvFuncInfo: &funcInfoAEF,
+ ApiProvFuncRole: ApiProviderFuncRoleAEF,
+ },
+ }
+ return APIProviderEnrolmentDetails{
+ ApiProvDomId: &domainID,
+ ApiProvDomInfo: &domainInfo,
+ ApiProvFuncs: &testFuncs,
+ }
+
+}