X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=capifcore%2Finternal%2Fpublishservice%2Fpublishservice.go;h=52434e8528e79ed104ac3da1c7d46bb65175fc37;hb=3928f2d539956636d31902d9e3650a3a50410df3;hp=a4b84f1a106bf081ee0a7d75c2a19eb7aae3a7a6;hpb=d172c2eb8e9072f16caa9d0c3c7b990b3503f879;p=nonrtric%2Fplt%2Fsme.git diff --git a/capifcore/internal/publishservice/publishservice.go b/capifcore/internal/publishservice/publishservice.go index a4b84f1..52434e8 100644 --- a/capifcore/internal/publishservice/publishservice.go +++ b/capifcore/internal/publishservice/publishservice.go @@ -31,6 +31,7 @@ import ( "k8s.io/utils/strings/slices" "oransc.org/nonrtric/capifcore/internal/common29122" + "oransc.org/nonrtric/capifcore/internal/eventsapi" publishapi "oransc.org/nonrtric/capifcore/internal/publishserviceapi" "oransc.org/nonrtric/capifcore/internal/helmmanagement" @@ -56,15 +57,17 @@ type PublishService struct { publishedServices map[string][]publishapi.ServiceAPIDescription serviceRegister providermanagement.ServiceRegister helmManager helmmanagement.HelmManager + eventChannel chan<- eventsapi.EventNotification lock sync.Mutex } // Creates a service that implements both the PublishRegister and the publishserviceapi.ServerInterface interfaces. -func NewPublishService(serviceRegister providermanagement.ServiceRegister, hm helmmanagement.HelmManager) *PublishService { +func NewPublishService(serviceRegister providermanagement.ServiceRegister, hm helmmanagement.HelmManager, eventChannel chan<- eventsapi.EventNotification) *PublishService { return &PublishService{ helmManager: hm, publishedServices: make(map[string][]publishapi.ServiceAPIDescription), serviceRegister: serviceRegister, + eventChannel: eventChannel, } } @@ -177,6 +180,7 @@ func (ps *PublishService) PostApfIdServiceApis(ctx echo.Context, apfId string) e if shouldReturn { return returnValue } + go ps.sendEvent(newServiceAPIDescription, eventsapi.CAPIFEventSERVICEAPIAVAILABLE) _, ok := ps.publishedServices[apfId] if ok { @@ -220,8 +224,9 @@ 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) } } return ctx.NoContent(http.StatusNoContent) @@ -230,9 +235,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 { @@ -272,9 +277,6 @@ 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 { - ps.lock.Lock() - defer ps.lock.Unlock() - pos, publishedService, shouldReturn, returnValue := ps.checkIfServiceIsPublished(apfId, serviceApiId, ctx) if shouldReturn { return returnValue @@ -286,8 +288,17 @@ func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfI } 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) + } + + pos, shouldReturn, returnValue = ps.updateProfiles(pos, apfId, updatedServiceDescription, publishedService, ctx) + if shouldReturn { + return returnValue } err := ctx.JSON(http.StatusOK, ps.publishedServices[apfId][pos]) @@ -295,12 +306,10 @@ func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfI // 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) { - publishedServices, ok := ps.publishedServices[apfId] if !ok { return 0, publishapi.ServiceAPIDescription{}, true, sendCoreError(ctx, http.StatusBadRequest, "Service must be published before updating it") @@ -315,7 +324,6 @@ func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId s } return 0, publishapi.ServiceAPIDescription{}, true, sendCoreError(ctx, http.StatusBadRequest, "Service must be published before updating it") - } func getServiceFromRequest(ctx echo.Context) (publishapi.ServiceAPIDescription, bool, error) { @@ -327,6 +335,78 @@ func getServiceFromRequest(ctx echo.Context) (publishapi.ServiceAPIDescription, return updatedServiceDescription, false, nil } +func (ps *PublishService) updateProfiles(pos int, apfId string, updatedServiceDescription publishapi.ServiceAPIDescription, publishedService publishapi.ServiceAPIDescription, ctx echo.Context) (int, bool, error) { + registeredFuncs := ps.serviceRegister.GetAefsForPublisher(apfId) + for _, profile := range *updatedServiceDescription.AefProfiles { + if !slices.Contains(registeredFuncs, profile.AefId) { + return 0, false, sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Function %s not registered", profile.AefId)) + } + if ps.checkIfProfileIsNew(profile.AefId, *publishedService.AefProfiles) { + + publishedService.AefProfiles = ps.addProfile(profile, publishedService) + ps.publishedServices[apfId][pos] = publishedService + + } else { + pos, shouldReturn, returnValue := ps.updateProfile(profile, publishedService, ctx) + if shouldReturn { + return pos, true, returnValue + } + } + + } + return 0, false, nil +} + +func (ps *PublishService) sendEvent(service publishapi.ServiceAPIDescription, eventType eventsapi.CAPIFEvent) { + apiIds := []string{*service.ApiId} + apis := []publishapi.ServiceAPIDescription{service} + event := eventsapi.EventNotification{ + EventDetail: &eventsapi.CAPIFEventDetail{ + ApiIds: &apiIds, + ServiceAPIDescriptions: &apis, + }, + Events: eventType, + } + ps.eventChannel <- event +} + +func (ps *PublishService) checkIfProfileIsNew(aefId string, publishedPofiles []publishapi.AefProfile) bool { + for _, profile := range publishedPofiles { + if profile.AefId == aefId { + return false + } + } + return true +} +func (ps *PublishService) addProfile(profile publishapi.AefProfile, publishedService publishapi.ServiceAPIDescription) *[]publishapi.AefProfile { + registeredProfiles := *publishedService.AefProfiles + newProfiles := append(registeredProfiles, profile) + publishedService.AefProfiles = &newProfiles + return &newProfiles + +} + +func (*PublishService) updateProfile(profile publishapi.AefProfile, publishedService publishapi.ServiceAPIDescription, ctx echo.Context) (int, bool, error) { + pos, registeredProfile, err := getProfile(profile.AefId, publishedService.AefProfiles) + if err != nil { + return pos, true, sendCoreError(ctx, http.StatusBadRequest, "Unable to update service due to: "+err.Error()) + } + if profile.DomainName != nil { + registeredProfile.DomainName = profile.DomainName + (*publishedService.AefProfiles)[pos] = registeredProfile + } + return -1, false, nil +} + +func getProfile(profileId string, apiProfiles *[]publishapi.AefProfile) (int, publishapi.AefProfile, error) { + for pos, profile := range *apiProfiles { + if profile.AefId == profileId { + return pos, profile, nil + } + } + return 0, publishapi.AefProfile{}, fmt.Errorf("profile with ID %s is not registered for the service", profileId) +} + // 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 {