X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=capifcore%2Finternal%2Fpublishservice%2Fpublishservice.go;h=5cea538f1f59f76dcbefa8aad33571fea1f0b0dc;hb=f62685e5a2187fb58c7f27cdd1f14dd2c152880d;hp=17f4b28823a336e6cf6a68bdebbef13f6d4323ba;hpb=37b5fcbb802f06442a9c08c94e709080a747f7ad;p=nonrtric%2Fplt%2Fsme.git diff --git a/capifcore/internal/publishservice/publishservice.go b/capifcore/internal/publishservice/publishservice.go index 17f4b28..5cea538 100644 --- a/capifcore/internal/publishservice/publishservice.go +++ b/capifcore/internal/publishservice/publishservice.go @@ -158,18 +158,26 @@ func (ps *PublishService) GetApfIdServiceApis(ctx echo.Context, apfId string) er // Publish a new API. func (ps *PublishService) PostApfIdServiceApis(ctx echo.Context, apfId string) error { var newServiceAPIDescription publishapi.ServiceAPIDescription + errorMsg := "Unable to publish the service due to %s " err := ctx.Bind(&newServiceAPIDescription) if err != nil { - return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for service "+apfId) + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errorMsg, "invalid format for service "+apfId)) } + if ps.isServicePublished(newServiceAPIDescription) { + return sendCoreError(ctx, http.StatusForbidden, fmt.Sprintf(errorMsg, "service already published")) + } + + if err := newServiceAPIDescription.Validate(); err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errorMsg, err)) + } ps.lock.Lock() defer ps.lock.Unlock() registeredFuncs := ps.serviceRegister.GetAefsForPublisher(apfId) for _, profile := range *newServiceAPIDescription.AefProfiles { if !slices.Contains(registeredFuncs, profile.AefId) { - return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Function %s not registered", profile.AefId)) + return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf(errorMsg, fmt.Sprintf("function %s not registered", profile.AefId))) } } @@ -200,6 +208,17 @@ func (ps *PublishService) PostApfIdServiceApis(ctx echo.Context, apfId string) e return nil } +func (ps *PublishService) isServicePublished(newService publishapi.ServiceAPIDescription) bool { + for _, services := range ps.publishedServices { + for _, service := range services { + if newService.ApiName == service.ApiName { + return true + } + } + } + return false +} + func (ps *PublishService) installHelmChart(newServiceAPIDescription publishapi.ServiceAPIDescription, ctx echo.Context) (bool, error) { info := strings.Split(*newServiceAPIDescription.Description, ",") if len(info) == 5 { @@ -224,8 +243,8 @@ func (ps *PublishService) DeleteApfIdServiceApisServiceApiId(ctx echo.Context, a log.Debug("Deleted service: ", serviceApiId) } ps.lock.Lock() - defer ps.lock.Unlock() ps.publishedServices[string(apfId)] = removeServiceDescription(pos, serviceDescriptions) + ps.lock.Unlock() go ps.sendEvent(*description, eventsapi.CAPIFEventSERVICEAPIUNAVAILABLE) } } @@ -235,9 +254,9 @@ func (ps *PublishService) DeleteApfIdServiceApisServiceApiId(ctx echo.Context, a // Retrieve a published service API. func (ps *PublishService) GetApfIdServiceApisServiceApiId(ctx echo.Context, apfId string, serviceApiId string) error { ps.lock.Lock() - defer ps.lock.Unlock() - serviceDescriptions, ok := ps.publishedServices[apfId] + ps.lock.Unlock() + if ok { _, serviceDescription := getServiceDescription(serviceApiId, serviceDescriptions) if serviceDescription == nil { @@ -277,57 +296,57 @@ func (ps *PublishService) ModifyIndAPFPubAPI(ctx echo.Context, apfId string, ser // Update a published service API. func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfId string, serviceApiId string) error { - pos, publishedService, shouldReturn, returnValue := ps.checkIfServiceIsPublished(apfId, serviceApiId, ctx) - if shouldReturn { - return returnValue + ps.lock.Lock() + defer ps.lock.Unlock() + errMsg := "Unable to update service due to %s." + pos, publishedService, err := ps.checkIfServiceIsPublished(apfId, serviceApiId, ctx) + if err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } - - updatedServiceDescription, shouldReturn, returnValue := getServiceFromRequest(ctx) - if shouldReturn { - return returnValue + updatedServiceDescription, err := getServiceFromRequest(ctx) + if err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } - - if updatedServiceDescription.Description != nil { - ps.lock.Lock() - defer ps.lock.Unlock() - - publishedService.Description = updatedServiceDescription.Description - ps.publishedServices[apfId][pos] = publishedService - go ps.sendEvent(publishedService, eventsapi.CAPIFEventSERVICEAPIUPDATE) + ps.updateDescription(pos, apfId, &updatedServiceDescription, &publishedService) + err = ps.checkProfilesRegistered(apfId, *updatedServiceDescription.AefProfiles) + if err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) } - - err := ctx.JSON(http.StatusOK, ps.publishedServices[apfId][pos]) + 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 return err } return nil } - -func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId string, ctx echo.Context) (int, publishapi.ServiceAPIDescription, bool, error) { +func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId string, ctx echo.Context) (int, publishapi.ServiceAPIDescription, error) { publishedServices, ok := ps.publishedServices[apfId] if !ok { - return 0, publishapi.ServiceAPIDescription{}, true, sendCoreError(ctx, http.StatusBadRequest, "Service must be published before updating it") + return 0, publishapi.ServiceAPIDescription{}, fmt.Errorf("service must be published before updating it") } else { for pos, description := range publishedServices { if *description.ApiId == serviceApiId { - return pos, description, false, nil - + return pos, description, nil } - } - } - return 0, publishapi.ServiceAPIDescription{}, true, sendCoreError(ctx, http.StatusBadRequest, "Service must be published before updating it") + return 0, publishapi.ServiceAPIDescription{}, fmt.Errorf("service must be published before updating it") } - -func getServiceFromRequest(ctx echo.Context) (publishapi.ServiceAPIDescription, bool, error) { +func getServiceFromRequest(ctx echo.Context) (publishapi.ServiceAPIDescription, error) { var updatedServiceDescription publishapi.ServiceAPIDescription err := ctx.Bind(&updatedServiceDescription) if err != nil { - return publishapi.ServiceAPIDescription{}, true, sendCoreError(ctx, http.StatusBadRequest, "Invalid format for service") + return publishapi.ServiceAPIDescription{}, fmt.Errorf("invalid format for service") + } + return updatedServiceDescription, nil +} +func (ps *PublishService) updateDescription(pos int, apfId string, updatedServiceDescription, publishedService *publishapi.ServiceAPIDescription) { + if updatedServiceDescription.Description != nil { + publishedService.Description = updatedServiceDescription.Description + go ps.sendEvent(*publishedService, eventsapi.CAPIFEventSERVICEAPIUPDATE) } - return updatedServiceDescription, false, nil } func (ps *PublishService) sendEvent(service publishapi.ServiceAPIDescription, eventType eventsapi.CAPIFEvent) { @@ -343,6 +362,16 @@ func (ps *PublishService) sendEvent(service publishapi.ServiceAPIDescription, ev ps.eventChannel <- event } +func (ps *PublishService) checkProfilesRegistered(apfId string, updatedProfiles []publishapi.AefProfile) error { + registeredFuncs := ps.serviceRegister.GetAefsForPublisher(apfId) + for _, profile := range updatedProfiles { + if !slices.Contains(registeredFuncs, profile.AefId) { + return fmt.Errorf("function %s not registered", profile.AefId) + } + } + return nil +} + // 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 {