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 registeredProviders map[string]provapi.APIProviderEnrolmentDetails
48 func NewProviderManager() *ProviderManager {
49 return &ProviderManager{
50 registeredProviders: make(map[string]provapi.APIProviderEnrolmentDetails),
54 func (pm *ProviderManager) IsFunctionRegistered(functionId string) bool {
55 for _, provider := range pm.registeredProviders {
56 if provider.IsFunctionRegistered(functionId) {
63 func (pm *ProviderManager) GetAefsForPublisher(apfId string) []string {
64 for _, provider := range pm.registeredProviders {
65 if aefs := provider.GetExposingFunctionIdsForPublisher(apfId); aefs != nil {
72 func (pm *ProviderManager) PostRegistrations(ctx echo.Context) error {
73 var newProvider provapi.APIProviderEnrolmentDetails
74 if err := ctx.Bind(&newProvider); err != nil {
75 return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider")
78 if err := newProvider.Validate(); err != nil {
79 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf("Provider not valid due to %s", err))
82 pm.prepareNewProvider(&newProvider)
84 uri := ctx.Request().Host + ctx.Request().URL.String()
85 ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newProvider.ApiProvDomId))
86 if err := ctx.JSON(http.StatusCreated, newProvider); err != nil {
87 // Something really bad happened, tell Echo that our handler failed
93 func (pm *ProviderManager) prepareNewProvider(newProvider *provapi.APIProviderEnrolmentDetails) {
95 defer pm.lock.Unlock()
97 newProvider.PrepareNewProvider()
98 pm.registeredProviders[*newProvider.ApiProvDomId] = *newProvider
101 func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
102 log.Debug(pm.registeredProviders)
103 if _, ok := pm.registeredProviders[registrationId]; ok {
104 pm.deleteProvider(registrationId)
106 return ctx.NoContent(http.StatusNoContent)
109 func (pm *ProviderManager) deleteProvider(registrationId string) {
110 log.Debug("Deleting provider", registrationId)
112 defer pm.lock.Unlock()
113 delete(pm.registeredProviders, registrationId)
116 func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
117 errMsg := "Unable to update provider due to %s."
118 registeredProvider, err := pm.checkIfProviderIsRegistered(registrationId, ctx)
120 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
123 updatedProvider, err := getProviderFromRequest(ctx)
125 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
128 if updatedProvider.Validate() != nil {
129 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
132 if err = pm.updateProvider(updatedProvider, registeredProvider); err != nil {
133 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
136 if err = ctx.JSON(http.StatusOK, updatedProvider); err != nil {
137 // Something really bad happened, tell Echo that our handler failed
143 func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error {
144 return ctx.NoContent(http.StatusNotImplemented)
147 func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string, ctx echo.Context) (*provapi.APIProviderEnrolmentDetails, error) {
148 registeredProvider, ok := pm.registeredProviders[registrationId]
150 return nil, fmt.Errorf("provider not onboarded")
152 return ®isteredProvider, nil
155 func getProviderFromRequest(ctx echo.Context) (provapi.APIProviderEnrolmentDetails, error) {
156 var updatedProvider provapi.APIProviderEnrolmentDetails
157 err := ctx.Bind(&updatedProvider)
159 return provapi.APIProviderEnrolmentDetails{}, fmt.Errorf("invalid format for provider")
161 return updatedProvider, nil
164 func (pm *ProviderManager) updateProvider(updatedProvider provapi.APIProviderEnrolmentDetails, registeredProvider *provapi.APIProviderEnrolmentDetails) error {
166 defer pm.lock.Unlock()
168 if err := updatedProvider.UpdateFuncs(*registeredProvider); err == nil {
169 pm.registeredProviders[*updatedProvider.ApiProvDomId] = updatedProvider
176 // This function wraps sending of an error in the Error format, and
177 // handling the failure to marshal that.
178 func sendCoreError(ctx echo.Context, code int, message string) error {
179 pd := common29122.ProblemDetails{
183 err := ctx.JSON(code, pd)