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 errMsg := "Unable to register provider due to %s"
75 if err := ctx.Bind(&newProvider); err != nil {
76 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, "invalid format for provider"))
79 if err := pm.isProviderRegistered(newProvider); err != nil {
80 return sendCoreError(ctx, http.StatusForbidden, fmt.Sprintf(errMsg, err))
83 if err := newProvider.Validate(); err != nil {
84 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
87 pm.prepareNewProvider(&newProvider)
89 uri := ctx.Request().Host + ctx.Request().URL.String()
90 ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newProvider.ApiProvDomId))
91 if err := ctx.JSON(http.StatusCreated, newProvider); err != nil {
92 // Something really bad happened, tell Echo that our handler failed
98 func (pm *ProviderManager) isProviderRegistered(newProvider provapi.APIProviderEnrolmentDetails) error {
99 for _, prov := range pm.registeredProviders {
100 if err := prov.ValidateAlreadyRegistered(newProvider); err != nil {
107 func (pm *ProviderManager) prepareNewProvider(newProvider *provapi.APIProviderEnrolmentDetails) {
109 defer pm.lock.Unlock()
111 newProvider.PrepareNewProvider()
112 pm.registeredProviders[*newProvider.ApiProvDomId] = *newProvider
115 func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
116 log.Debug(pm.registeredProviders)
117 if _, ok := pm.registeredProviders[registrationId]; ok {
118 pm.deleteProvider(registrationId)
120 return ctx.NoContent(http.StatusNoContent)
123 func (pm *ProviderManager) deleteProvider(registrationId string) {
124 log.Debug("Deleting provider", registrationId)
126 defer pm.lock.Unlock()
127 delete(pm.registeredProviders, registrationId)
130 func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
131 errMsg := "Unable to update provider due to %s."
132 registeredProvider, err := pm.checkIfProviderIsRegistered(registrationId, ctx)
134 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
137 updatedProvider, err := getProviderFromRequest(ctx)
139 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
142 if updatedProvider.Validate() != nil {
143 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
146 if err = pm.updateProvider(updatedProvider, registeredProvider); err != nil {
147 return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
150 if err = ctx.JSON(http.StatusOK, updatedProvider); err != nil {
151 // Something really bad happened, tell Echo that our handler failed
157 func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error {
158 return ctx.NoContent(http.StatusNotImplemented)
161 func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string, ctx echo.Context) (*provapi.APIProviderEnrolmentDetails, error) {
162 registeredProvider, ok := pm.registeredProviders[registrationId]
164 return nil, fmt.Errorf("provider not onboarded")
166 return ®isteredProvider, nil
169 func getProviderFromRequest(ctx echo.Context) (provapi.APIProviderEnrolmentDetails, error) {
170 var updatedProvider provapi.APIProviderEnrolmentDetails
171 err := ctx.Bind(&updatedProvider)
173 return provapi.APIProviderEnrolmentDetails{}, fmt.Errorf("invalid format for provider")
175 return updatedProvider, nil
178 func (pm *ProviderManager) updateProvider(updatedProvider provapi.APIProviderEnrolmentDetails, registeredProvider *provapi.APIProviderEnrolmentDetails) error {
180 defer pm.lock.Unlock()
182 if err := updatedProvider.UpdateFuncs(*registeredProvider); err == nil {
183 pm.registeredProviders[*updatedProvider.ApiProvDomId] = updatedProvider
190 // This function wraps sending of an error in the Error format, and
191 // handling the failure to marshal that.
192 func sendCoreError(ctx echo.Context, code int, message string) error {
193 pd := common29122.ProblemDetails{
197 err := ctx.JSON(code, pd)