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 publishservice
29 "github.com/labstack/echo/v4"
31 "oransc.org/nonrtric/capifcore/internal/common29122"
32 "oransc.org/nonrtric/capifcore/internal/publishserviceapi"
34 "oransc.org/nonrtric/capifcore/internal/helmmanagement"
35 "oransc.org/nonrtric/capifcore/internal/providermanagement"
37 log "github.com/sirupsen/logrus"
40 //go:generate mockery --name APIRegister
41 type APIRegister interface {
42 AreAPIsRegistered(serviceDescriptions *[]publishserviceapi.ServiceAPIDescription) bool
43 GetAPIs() *[]publishserviceapi.ServiceAPIDescription
44 IsAPIRegistered(aefId, path string) bool
47 type PublishService struct {
48 publishedServices map[string]publishserviceapi.ServiceAPIDescription
49 serviceRegister providermanagement.ServiceRegister
50 helmManager helmmanagement.HelmManager
54 func NewPublishService(serviceRegister providermanagement.ServiceRegister, hm helmmanagement.HelmManager) *PublishService {
55 return &PublishService{
57 publishedServices: make(map[string]publishserviceapi.ServiceAPIDescription),
58 serviceRegister: serviceRegister,
62 func (ps *PublishService) AreAPIsRegistered(serviceDescriptions *[]publishserviceapi.ServiceAPIDescription) bool {
64 defer ps.lock.Unlock()
67 if serviceDescriptions != nil {
69 for _, newApi := range *serviceDescriptions {
70 registeredApi, ok := ps.publishedServices[*newApi.ApiId]
72 if !ps.areProfilesRegistered(newApi.AefProfiles, registeredApi.AefProfiles) {
85 func (ps *PublishService) areProfilesRegistered(newProfiles *[]publishserviceapi.AefProfile, registeredProfiles *[]publishserviceapi.AefProfile) bool {
87 if newProfiles != nil && registeredProfiles != nil {
89 for _, newProfile := range *newProfiles {
90 for _, registeredProfile := range *registeredProfiles {
91 if newProfile.AefId == registeredProfile.AefId {
98 } else if registeredProfiles == nil {
104 func (ps *PublishService) GetAPIs() *[]publishserviceapi.ServiceAPIDescription {
106 defer ps.lock.Unlock()
108 apis := []publishserviceapi.ServiceAPIDescription{}
109 for _, service := range ps.publishedServices {
110 apis = append(apis, service)
115 func (ps *PublishService) IsAPIRegistered(aefId, path string) bool {
117 defer ps.lock.Unlock()
121 for _, service := range ps.publishedServices {
122 if service.ApiName == path {
123 for _, profile := range *service.AefProfiles {
124 if profile.AefId == aefId {
134 func (ps *PublishService) GetApfIdServiceApis(ctx echo.Context, apfId publishserviceapi.ApfId) error {
135 return ctx.NoContent(http.StatusNotImplemented)
138 func (ps *PublishService) PostApfIdServiceApis(ctx echo.Context, apfId publishserviceapi.ApfId) error {
139 var newServiceAPIDescription publishserviceapi.ServiceAPIDescription
140 err := ctx.Bind(&newServiceAPIDescription)
142 return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for service")
146 defer ps.lock.Unlock()
148 for _, profile := range *newServiceAPIDescription.AefProfiles {
149 if !ps.serviceRegister.IsFunctionRegistered(profile.AefId) {
150 return sendCoreError(ctx, http.StatusNotFound, "Function not registered, "+profile.AefId)
154 newId := "api_id_" + newServiceAPIDescription.ApiName
155 newServiceAPIDescription.ApiId = &newId
156 info := strings.Split(*newServiceAPIDescription.Description, ",")
158 err = ps.helmManager.InstallHelmChart(info[1], info[2], info[3], info[4])
160 return sendCoreError(ctx, http.StatusBadRequest, "Unable to install Helm chart due to: "+err.Error())
162 log.Info("Installed service: ", newId)
164 ps.publishedServices[*newServiceAPIDescription.ApiId] = newServiceAPIDescription
166 uri := ctx.Request().Host + ctx.Request().URL.String()
167 ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newServiceAPIDescription.ApiId))
168 err = ctx.JSON(http.StatusCreated, newServiceAPIDescription)
170 // Something really bad happened, tell Echo that our handler failed
177 func (ps *PublishService) DeleteApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
178 serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
180 info := strings.Split(*serviceDescription.Description, ",")
182 ps.helmManager.UninstallHelmChart(info[1], info[3])
183 log.Info("Deleted service: ", serviceApiId)
185 delete(ps.publishedServices, string(serviceApiId))
187 return ctx.NoContent(http.StatusNoContent)
190 func (ps *PublishService) GetApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
191 serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
193 err := ctx.JSON(http.StatusOK, serviceDescription)
195 // Something really bad happened, tell Echo that our handler failed
201 return ctx.NoContent(http.StatusNotFound)
204 func (ps *PublishService) ModifyIndAPFPubAPI(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
205 return ctx.NoContent(http.StatusNotImplemented)
208 func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
209 return ctx.NoContent(http.StatusNotImplemented)
212 // This function wraps sending of an error in the Error format, and
213 // handling the failure to marshal that.
214 func sendCoreError(ctx echo.Context, code int, message string) error {
215 pd := common29122.ProblemDetails{
219 err := ctx.JSON(code, pd)