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
41 IsPublishingFunctionRegistered(apiProvFuncId string) bool
44 type ProviderManager struct {
45 registeredProviders map[string]provapi.APIProviderEnrolmentDetails
49 func NewProviderManager() *ProviderManager {
50 return &ProviderManager{
51 registeredProviders: make(map[string]provapi.APIProviderEnrolmentDetails),
55 func (pm *ProviderManager) IsFunctionRegistered(functionId string) bool {
56 for _, provider := range pm.registeredProviders {
57 if provider.IsFunctionRegistered(functionId) {
64 func (pm *ProviderManager) GetAefsForPublisher(apfId string) []string {
65 for _, provider := range pm.registeredProviders {
66 if aefs := provider.GetExposingFunctionIdsForPublisher(apfId); aefs != nil {
73 func (pm *ProviderManager) IsPublishingFunctionRegistered(apiProvFuncId string) bool {
74 for _, provider := range pm.registeredProviders {
75 if provider.IsPublishingFunctionRegistered(apiProvFuncId) {
82 func (pm *ProviderManager) PostRegistrations(ctx echo.Context) error {
83 var newProvider provapi.APIProviderEnrolmentDetails
84 errMsg := "Unable to register provider due to %s"
85 if err := ctx.Bind(&newProvider); err != nil {
86 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, "invalid format for provider"))
89 if err := pm.isProviderRegistered(newProvider); err != nil {
90 return sendCoreError(ctx, http.StatusForbidden, fmt.Sprintf(errMsg, err))
93 if err := newProvider.Validate(); err != nil {
94 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
97 pm.prepareNewProvider(&newProvider)
99 uri := ctx.Request().Host + ctx.Request().URL.String()
100 ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newProvider.ApiProvDomId))
101 if err := ctx.JSON(http.StatusCreated, newProvider); err != nil {
102 // Something really bad happened, tell Echo that our handler failed
108 func (pm *ProviderManager) isProviderRegistered(newProvider provapi.APIProviderEnrolmentDetails) error {
109 for _, prov := range pm.registeredProviders {
110 if err := prov.ValidateAlreadyRegistered(newProvider); err != nil {
117 func (pm *ProviderManager) prepareNewProvider(newProvider *provapi.APIProviderEnrolmentDetails) {
119 defer pm.lock.Unlock()
121 newProvider.PrepareNewProvider()
122 pm.registeredProviders[*newProvider.ApiProvDomId] = *newProvider
125 func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
126 log.Debug(pm.registeredProviders)
127 if _, ok := pm.registeredProviders[registrationId]; ok {
128 pm.deleteProvider(registrationId)
130 return ctx.NoContent(http.StatusNoContent)
133 func (pm *ProviderManager) deleteProvider(registrationId string) {
134 log.Debug("Deleting provider", registrationId)
136 defer pm.lock.Unlock()
137 delete(pm.registeredProviders, registrationId)
140 func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
141 errMsg := "Unable to update provider due to %s."
142 registeredProvider, err := pm.checkIfProviderIsRegistered(registrationId, ctx)
144 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
147 updatedProvider, err := getProviderFromRequest(ctx)
149 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
152 if updatedProvider.Validate() != nil {
153 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
156 if err = pm.updateProvider(updatedProvider, registeredProvider); err != nil {
157 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
160 if err = ctx.JSON(http.StatusOK, updatedProvider); err != nil {
161 // Something really bad happened, tell Echo that our handler failed
167 func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error {
168 return ctx.NoContent(http.StatusNotImplemented)
171 func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string, ctx echo.Context) (*provapi.APIProviderEnrolmentDetails, error) {
172 registeredProvider, ok := pm.registeredProviders[registrationId]
174 return nil, fmt.Errorf("provider not onboarded")
176 return ®isteredProvider, nil
179 func getProviderFromRequest(ctx echo.Context) (provapi.APIProviderEnrolmentDetails, error) {
180 var updatedProvider provapi.APIProviderEnrolmentDetails
181 err := ctx.Bind(&updatedProvider)
183 return provapi.APIProviderEnrolmentDetails{}, fmt.Errorf("invalid format for provider")
185 return updatedProvider, nil
188 func (pm *ProviderManager) updateProvider(updatedProvider provapi.APIProviderEnrolmentDetails, registeredProvider *provapi.APIProviderEnrolmentDetails) error {
190 defer pm.lock.Unlock()
192 if err := updatedProvider.UpdateFuncs(*registeredProvider); err == nil {
193 pm.registeredProviders[*updatedProvider.ApiProvDomId] = updatedProvider
200 // This function wraps sending of an error in the Error format, and
201 // handling the failure to marshal that.
202 func sendCoreError(ctx echo.Context, code int, message string) error {
203 pd := common29122.ProblemDetails{
207 err := ctx.JSON(code, pd)