+++ /dev/null
-// -
-// ========================LICENSE_START=================================
-// O-RAN-SC
-// %%
-// Copyright (C) 2022: 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 publishservice
-
-import (
- "net/http"
- "path"
- "strings"
- "sync"
-
- "github.com/labstack/echo/v4"
-
- "oransc.org/nonrtric/sme/internal/common29122"
- "oransc.org/nonrtric/sme/internal/publishserviceapi"
-
- "oransc.org/nonrtric/sme/internal/helmmanagement"
- "oransc.org/nonrtric/sme/internal/providermanagement"
-
- log "github.com/sirupsen/logrus"
-)
-
-//go:generate mockery --name APIRegister
-type APIRegister interface {
- AreAPIsRegistered(serviceDescriptions *[]publishserviceapi.ServiceAPIDescription) bool
- GetAPIs() *[]publishserviceapi.ServiceAPIDescription
- IsAPIRegistered(aefId, path string) bool
-}
-
-type PublishService struct {
- publishedServices map[string]publishserviceapi.ServiceAPIDescription
- serviceRegister providermanagement.ServiceRegister
- helmManager helmmanagement.HelmManager
- lock sync.Mutex
-}
-
-func NewPublishService(serviceRegister providermanagement.ServiceRegister, hm helmmanagement.HelmManager) *PublishService {
- return &PublishService{
- helmManager: hm,
- publishedServices: make(map[string]publishserviceapi.ServiceAPIDescription),
- serviceRegister: serviceRegister,
- }
-}
-
-func (ps *PublishService) AreAPIsRegistered(serviceDescriptions *[]publishserviceapi.ServiceAPIDescription) bool {
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- allRegistered := true
- if serviceDescriptions != nil {
- out:
- for _, newApi := range *serviceDescriptions {
- registeredApi, ok := ps.publishedServices[*newApi.ApiId]
- if ok {
- if !ps.areProfilesRegistered(newApi.AefProfiles, registeredApi.AefProfiles) {
- allRegistered = false
- break out
- }
- } else {
- allRegistered = false
- break out
- }
- }
- }
- return allRegistered
-}
-
-func (ps *PublishService) areProfilesRegistered(newProfiles *[]publishserviceapi.AefProfile, registeredProfiles *[]publishserviceapi.AefProfile) bool {
- allRegistered := true
- if newProfiles != nil && registeredProfiles != nil {
- out:
- for _, newProfile := range *newProfiles {
- for _, registeredProfile := range *registeredProfiles {
- if newProfile.AefId == registeredProfile.AefId {
- break
- }
- allRegistered = false
- break out
- }
- }
- } else if registeredProfiles == nil {
- allRegistered = false
- }
- return allRegistered
-}
-
-func (ps *PublishService) GetAPIs() *[]publishserviceapi.ServiceAPIDescription {
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- apis := []publishserviceapi.ServiceAPIDescription{}
- for _, service := range ps.publishedServices {
- apis = append(apis, service)
- }
- return &apis
-}
-
-func (ps *PublishService) IsAPIRegistered(aefId, path string) bool {
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- registered := false
-out:
- for _, service := range ps.publishedServices {
- if service.ApiName == path {
- for _, profile := range *service.AefProfiles {
- if profile.AefId == aefId {
- registered = true
- break out
- }
- }
- }
- }
- return registered
-}
-
-func (ps *PublishService) GetApfIdServiceApis(ctx echo.Context, apfId publishserviceapi.ApfId) error {
- return ctx.NoContent(http.StatusNotImplemented)
-}
-
-func (ps *PublishService) PostApfIdServiceApis(ctx echo.Context, apfId publishserviceapi.ApfId) error {
- var newServiceAPIDescription publishserviceapi.ServiceAPIDescription
- err := ctx.Bind(&newServiceAPIDescription)
- if err != nil {
- return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for service")
- }
-
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- for _, profile := range *newServiceAPIDescription.AefProfiles {
- if !ps.serviceRegister.IsFunctionRegistered(profile.AefId) {
- return sendCoreError(ctx, http.StatusNotFound, "Function not registered, "+profile.AefId)
- }
- }
-
- newId := "api_id_" + newServiceAPIDescription.ApiName
- newServiceAPIDescription.ApiId = &newId
- info := strings.Split(*newServiceAPIDescription.Description, ",")
- if len(info) == 5 {
- err = ps.helmManager.InstallHelmChart(info[1], info[2], info[3], info[4])
- if err != nil {
- return sendCoreError(ctx, http.StatusBadRequest, "Unable to install Helm chart due to: "+err.Error())
- }
- log.Info("Installed service: ", newId)
- }
- ps.publishedServices[*newServiceAPIDescription.ApiId] = newServiceAPIDescription
-
- uri := ctx.Request().Host + ctx.Request().URL.String()
- ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newServiceAPIDescription.ApiId))
- err = ctx.JSON(http.StatusCreated, newServiceAPIDescription)
- if err != nil {
- // Something really bad happened, tell Echo that our handler failed
- return err
- }
-
- return nil
-}
-
-func (ps *PublishService) DeleteApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
- serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
- if ok {
- info := strings.Split(*serviceDescription.Description, ",")
- if len(info) == 5 {
- ps.helmManager.UninstallHelmChart(info[1], info[3])
- log.Info("Deleted service: ", serviceApiId)
- }
- delete(ps.publishedServices, string(serviceApiId))
- }
- return ctx.NoContent(http.StatusNoContent)
-}
-
-func (ps *PublishService) GetApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
- serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
- if ok {
- err := ctx.JSON(http.StatusOK, serviceDescription)
- if err != nil {
- // Something really bad happened, tell Echo that our handler failed
- return err
- }
-
- return nil
- }
- return ctx.NoContent(http.StatusNotFound)
-}
-
-func (ps *PublishService) ModifyIndAPFPubAPI(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
- return ctx.NoContent(http.StatusNotImplemented)
-}
-
-func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
- return ctx.NoContent(http.StatusNotImplemented)
-}
-
-// This function wraps sending of an error in the Error format, and
-// handling the failure to marshal that.
-func sendCoreError(ctx echo.Context, code int, message string) error {
- pd := common29122.ProblemDetails{
- Cause: &message,
- Status: &code,
- }
- err := ctx.JSON(code, pd)
- return err
-}