2 // ========================LICENSE_START=================================
5 // Copyright (C) 2022: Nordix Foundation
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 // ========================LICENSE_END===================================
21 package providermanagement
29 "github.com/labstack/echo/v4"
31 "oransc.org/nonrtric/capifcore/internal/common29122"
32 provapi "oransc.org/nonrtric/capifcore/internal/providermanagementapi"
34 log "github.com/sirupsen/logrus"
37 //go:generate mockery --name ServiceRegister
38 type ServiceRegister interface {
39 IsFunctionRegistered(functionId string) bool
40 GetAefsForPublisher(apfId string) []string
43 type ProviderManager struct {
44 onboardedProviders map[string]provapi.APIProviderEnrolmentDetails
48 func NewProviderManager() *ProviderManager {
49 return &ProviderManager{
50 onboardedProviders: make(map[string]provapi.APIProviderEnrolmentDetails),
54 func (pm *ProviderManager) IsFunctionRegistered(functionId string) bool {
57 for _, provider := range pm.onboardedProviders {
58 for _, registeredFunc := range *provider.ApiProvFuncs {
59 if *registeredFunc.ApiProvFuncId == functionId {
69 func (pm *ProviderManager) GetAefsForPublisher(apfId string) []string {
70 for _, provider := range pm.onboardedProviders {
71 for _, registeredFunc := range *provider.ApiProvFuncs {
72 if *registeredFunc.ApiProvFuncId == apfId && registeredFunc.ApiProvFuncRole == provapi.ApiProviderFuncRoleAPF {
73 return getExposedFuncs(provider.ApiProvFuncs)
80 func getExposedFuncs(providerFuncs *[]provapi.APIProviderFunctionDetails) []string {
81 exposedFuncs := []string{}
82 for _, registeredFunc := range *providerFuncs {
83 if registeredFunc.ApiProvFuncRole == provapi.ApiProviderFuncRoleAEF {
84 exposedFuncs = append(exposedFuncs, *registeredFunc.ApiProvFuncId)
90 func (pm *ProviderManager) PostRegistrations(ctx echo.Context) error {
91 var newProvider provapi.APIProviderEnrolmentDetails
92 err := ctx.Bind(&newProvider)
94 return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider")
97 if newProvider.ApiProvDomInfo == nil || *newProvider.ApiProvDomInfo == "" {
98 return sendCoreError(ctx, http.StatusBadRequest, "Provider missing required ApiProvDomInfo")
102 defer pm.lock.Unlock()
104 newProvider.ApiProvDomId = pm.getDomainId(newProvider.ApiProvDomInfo)
106 pm.registerFunctions(newProvider.ApiProvFuncs)
107 pm.onboardedProviders[*newProvider.ApiProvDomId] = newProvider
109 uri := ctx.Request().Host + ctx.Request().URL.String()
110 ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newProvider.ApiProvDomId))
111 err = ctx.JSON(http.StatusCreated, newProvider)
113 // Something really bad happened, tell Echo that our handler failed
120 func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
122 defer pm.lock.Unlock()
124 log.Debug(pm.onboardedProviders)
125 if _, ok := pm.onboardedProviders[registrationId]; ok {
126 log.Debug("Deleting provider", registrationId)
127 delete(pm.onboardedProviders, registrationId)
130 return ctx.NoContent(http.StatusNoContent)
133 func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
134 registeredProvider, ok := pm.onboardedProviders[registrationId]
136 return sendCoreError(ctx, http.StatusBadRequest, "Provider must be onboarded before updating it")
140 var updatedProvider provapi.APIProviderEnrolmentDetails
141 err := ctx.Bind(&updatedProvider)
143 return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider")
147 defer pm.lock.Unlock()
149 for _, function := range *updatedProvider.ApiProvFuncs {
150 if function.ApiProvFuncId == nil {
151 function.ApiProvFuncId = pm.getFuncId(function.ApiProvFuncRole, function.ApiProvFuncInfo)
152 registeredFuncs := *registeredProvider.ApiProvFuncs
153 newFuncs := append(registeredFuncs, function)
154 registeredProvider.ApiProvFuncs = &newFuncs
155 pm.onboardedProviders[*registeredProvider.ApiProvDomId] = registeredProvider
159 err = ctx.JSON(http.StatusOK, registeredProvider)
161 // Something really bad happened, tell Echo that our handler failed
168 func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error {
169 return ctx.NoContent(http.StatusNotImplemented)
172 func (pm *ProviderManager) registerFunctions(provFuncs *[]provapi.APIProviderFunctionDetails) {
173 if provFuncs == nil {
176 for i, provFunc := range *provFuncs {
177 (*provFuncs)[i].ApiProvFuncId = pm.getFuncId(provFunc.ApiProvFuncRole, provFunc.ApiProvFuncInfo)
181 func (pm *ProviderManager) getDomainId(domainInfo *string) *string {
182 idAsString := "domain_id_" + strings.ReplaceAll(*domainInfo, " ", "_")
186 func (pm *ProviderManager) getFuncId(role provapi.ApiProviderFuncRole, funcInfo *string) *string {
189 case provapi.ApiProviderFuncRoleAPF:
191 case provapi.ApiProviderFuncRoleAMF:
193 case provapi.ApiProviderFuncRoleAEF:
196 idPrefix = "function_id_"
198 idAsString := idPrefix + strings.ReplaceAll(*funcInfo, " ", "_")
202 // This function wraps sending of an error in the Error format, and
203 // handling the failure to marshal that.
204 func sendCoreError(ctx echo.Context, code int, message string) error {
205 pd := common29122.ProblemDetails{
209 err := ctx.JSON(code, pd)