X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=capifcore%2Finternal%2Fpublishservice%2Fpublishservice.go;h=670d2ed53c9c5e69712579913f3287eb005bc16d;hb=refs%2Fchanges%2F85%2F12585%2F1;hp=2fe5b2e96364600547cf7fc8d48b16ca1cea6b6b;hpb=6f91b6ac28e733561200c5faf12029cafed39d3f;p=nonrtric%2Fplt%2Fsme.git diff --git a/capifcore/internal/publishservice/publishservice.go b/capifcore/internal/publishservice/publishservice.go index 2fe5b2e..670d2ed 100644 --- a/capifcore/internal/publishservice/publishservice.go +++ b/capifcore/internal/publishservice/publishservice.go @@ -2,7 +2,8 @@ // ========================LICENSE_START================================= // O-RAN-SC // %% -// Copyright (C) 2022: Nordix Foundation +// Copyright (C) 2022-2023: Nordix Foundation +// Copyright (C) 2024: OpenInfra Foundation Europe // %% // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,7 +28,7 @@ import ( "strings" "sync" - "github.com/labstack/echo/v4" + echo "github.com/labstack/echo/v4" "k8s.io/utils/strings/slices" "oransc.org/nonrtric/capifcore/internal/common29122" @@ -48,6 +49,7 @@ type PublishRegister interface { // Gets all published APIs. // Returns a list of all APIs that has been published. GetAllPublishedServices() []publishapi.ServiceAPIDescription + GetAllowedPublishedServices(invokerApiList []publishapi.ServiceAPIDescription) []publishapi.ServiceAPIDescription } type PublishService struct { @@ -93,19 +95,43 @@ func (ps *PublishService) GetAllPublishedServices() []publishapi.ServiceAPIDescr return publishedDescriptions } +func (ps *PublishService) GetAllowedPublishedServices(apiListRequestedServices []publishapi.ServiceAPIDescription) []publishapi.ServiceAPIDescription { + apiListAllPublished := ps.GetAllPublishedServices() + allowedPublishedServices := intersection(apiListAllPublished, apiListRequestedServices) + return allowedPublishedServices +} + +func intersection(a, b []publishapi.ServiceAPIDescription) []publishapi.ServiceAPIDescription { + var result []publishapi.ServiceAPIDescription + + if (a == nil) || (b == nil) || (len(a) == 0) || (len(b) == 0) { + return result + } + + for _, itemA := range a { + for _, itemB := range b { + if (itemA.ApiId != nil) && (itemB.ApiId != nil) && (*itemA.ApiId == *itemB.ApiId) { + result = append(result, itemA) + break + } + } + } + return result +} + // Retrieve all published APIs. func (ps *PublishService) GetApfIdServiceApis(ctx echo.Context, apfId string) error { - serviceDescriptions, ok := ps.publishedServices[apfId] - if ok { - err := ctx.JSON(http.StatusOK, serviceDescriptions) - if err != nil { - // Something really bad happened, tell Echo that our handler failed - return err - } - } else { - return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Provider %s not registered", apfId)) + if !ps.serviceRegister.IsPublishingFunctionRegistered(apfId) { + errorMsg := fmt.Sprintf("Unable to get the service due to %s api is only available for publishers", apfId) + return sendCoreError(ctx, http.StatusNotFound, errorMsg) } + serviceDescriptions := ps.publishedServices[apfId] + err := ctx.JSON(http.StatusOK, serviceDescriptions) + if err != nil { + // Something really bad happened, tell Echo that our handler failed + return err + } return nil } @@ -232,7 +258,8 @@ func (ps *PublishService) GetApfIdServiceApisServiceApiId(ctx echo.Context, apfI func getServiceDescription(serviceApiId string, descriptions []publishapi.ServiceAPIDescription) (int, *publishapi.ServiceAPIDescription) { for pos, description := range descriptions { - if serviceApiId == *description.ApiId { + // Check for nil as we had a failure here when running unit tests in parallel against a single Capifcore instance + if (description.ApiId != nil) && (serviceApiId == *description.ApiId) { return pos, &description } } @@ -256,21 +283,33 @@ func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfI ps.lock.Lock() defer ps.lock.Unlock() errMsg := "Unable to update service due to %s." - pos, publishedService, err := ps.checkIfServiceIsPublished(apfId, serviceApiId, ctx) + + pos, publishedService, err := ps.checkIfServiceIsPublished(apfId, serviceApiId) if err != nil { return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } + updatedServiceDescription, err := getServiceFromRequest(ctx) if err != nil { return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } + + // Additional validation for PUT + if (updatedServiceDescription.ApiId == nil) || (*updatedServiceDescription.ApiId != serviceApiId) { + errDetail := "ServiceAPIDescription ApiId doesn't match path parameter" + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, errDetail)) + } + err = ps.checkProfilesRegistered(apfId, *updatedServiceDescription.AefProfiles) if err != nil { return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } - ps.updateDescription(pos, apfId, &updatedServiceDescription, &publishedService) + + ps.updateDescription(&updatedServiceDescription, &publishedService) + publishedService.AefProfiles = updatedServiceDescription.AefProfiles ps.publishedServices[apfId][pos] = publishedService + err = ctx.JSON(http.StatusOK, publishedService) if err != nil { // Something really bad happened, tell Echo that our handler failed @@ -278,7 +317,8 @@ func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfI } return nil } -func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId string, ctx echo.Context) (int, publishapi.ServiceAPIDescription, error) { + +func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId string) (int, publishapi.ServiceAPIDescription, error) { publishedServices, ok := ps.publishedServices[apfId] if !ok { return 0, publishapi.ServiceAPIDescription{}, fmt.Errorf("service must be published before updating it") @@ -291,6 +331,7 @@ func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId s } return 0, publishapi.ServiceAPIDescription{}, fmt.Errorf("service must be published before updating it") } + func getServiceFromRequest(ctx echo.Context) (publishapi.ServiceAPIDescription, error) { var updatedServiceDescription publishapi.ServiceAPIDescription err := ctx.Bind(&updatedServiceDescription) @@ -299,7 +340,8 @@ func getServiceFromRequest(ctx echo.Context) (publishapi.ServiceAPIDescription, } return updatedServiceDescription, nil } -func (ps *PublishService) updateDescription(pos int, apfId string, updatedServiceDescription, publishedService *publishapi.ServiceAPIDescription) { + +func (ps *PublishService) updateDescription(updatedServiceDescription, publishedService *publishapi.ServiceAPIDescription) { if updatedServiceDescription.Description != nil { publishedService.Description = updatedServiceDescription.Description go ps.sendEvent(*publishedService, eventsapi.CAPIFEventSERVICEAPIUPDATE)