diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/api_mec_service_mgmt.go b/go-apps/meep-app-enablement/server/capif-mgmt/api_mec_service_mgmt.go index e9e31a0abe5e8809104d0c8ed26e1bab1a5194b2..95e58c21cea5bc82d7ba78ca22571f45804ba4f6 100644 --- a/go-apps/meep-app-enablement/server/capif-mgmt/api_mec_service_mgmt.go +++ b/go-apps/meep-app-enablement/server/capif-mgmt/api_mec_service_mgmt.go @@ -69,6 +69,11 @@ func ApplicationsSubscriptionsPOST(w http.ResponseWriter, r *http.Request) { func ApplicationsSubscriptionsPUT(w http.ResponseWriter, r *http.Request) { applicationsSubscriptionsPUT(w, r) } + +func ApplicationsSubscriptionsPATCH(w http.ResponseWriter, r *http.Request) { + applicationsSubscriptionsPATCH(w, r) +} + func ServicesGET(w http.ResponseWriter, r *http.Request) { servicesGET(w, r) } diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/convert.go b/go-apps/meep-app-enablement/server/capif-mgmt/convert.go index cd72190c95bac10df72e5b52aac252a15d7ed84e..fb49112e5e76e52cf63217807d8210fc529784dd 100644 --- a/go-apps/meep-app-enablement/server/capif-mgmt/convert.go +++ b/go-apps/meep-app-enablement/server/capif-mgmt/convert.go @@ -87,6 +87,26 @@ func convertJsonToSerAvailabilityNotifSub(jsonData string) *SerAvailabilityNotif return &obj } +// Convert []string back to []CapifEventFilter +func convertStringsToEventFilters(stringFilters []string) []CapifEventFilter { + var eventFilters []CapifEventFilter + for _, filter := range stringFilters { + eventFilters = append(eventFilters, CapifEventFilter{ + ApiIds: []string{filter}, // Assuming each string corresponds to an ApiId in the CapifEventFilter + }) + } + return eventFilters +} + +// Convert []string back to []CapifEvent +func convertStringsToEvents(stringEvents []string) []CapifEvent { + var events []CapifEvent + for _, event := range stringEvents { + events = append(events, CapifEvent(event)) // Assuming the string directly maps to CapifEvent + } + return events +} + func convertEventFiltersToStrings(filters []CapifEventFilter) []string { var stringFilters []string for _, filter := range filters { diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/model_event_subscription_patch.go b/go-apps/meep-app-enablement/server/capif-mgmt/model_event_subscription_patch.go new file mode 100644 index 0000000000000000000000000000000000000000..7591b2aea30af34ff2631e9598aee57e07d68ac7 --- /dev/null +++ b/go-apps/meep-app-enablement/server/capif-mgmt/model_event_subscription_patch.go @@ -0,0 +1,18 @@ +/* + * MEC service management realized by CAPIF APIs + * + * The ETSI MEC ISG MEC011 MEC Service Management realized by CAPIF APIs described using OpenAPI + * + * API version: 3.2.1 + * Contact: cti_support@etsi.org + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +type EventSubscriptionPatch struct { + // The events for which the subscription is modified. + Events []CapifEvent `json:"events"` + EventFilters []CapifEventFilter `json:"eventFilters,omitempty"` + // URI to which notifications will be sent. Shall be set to the value of the \"callbackReference\" attribute in the \"SerAvailabilityNotificationSubscription\" structure. + NotificationDestination string `json:"notificationDestination,omitempty"` +} diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/service-mgmt.go b/go-apps/meep-app-enablement/server/capif-mgmt/service-mgmt.go index af23f8ea58a383b31e3d5daaa9b29f2eec72b6b8..183c7b06b7ac3ac70346f8cdc80579708b6df537 100644 --- a/go-apps/meep-app-enablement/server/capif-mgmt/service-mgmt.go +++ b/go-apps/meep-app-enablement/server/capif-mgmt/service-mgmt.go @@ -882,6 +882,96 @@ func servicesGET(w http.ResponseWriter, r *http.Request) { } } +func applicationsSubscriptionsPATCH(w http.ResponseWriter, r *http.Request) { + log.Info("applicationsSubscriptionsPATCH") + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + vars := mux.Vars(r) + subId := vars["subscriptionId"] + appId := vars["subscriberId"] + + mutex.Lock() + defer mutex.Unlock() + + // Get App instance + appInfo, err := getAppInfo(appId) + if err != nil { + errHandlerProblemDetails(w, err.Error(), http.StatusNotFound) + return + } + + // Validate App info + code, problemDetails, err := validateAppInfo(appInfo) + if err != nil { + log.Error(err.Error()) + if problemDetails != "" { + w.WriteHeader(code) + fmt.Fprint(w, problemDetails) + } else { + errHandlerProblemDetails(w, err.Error(), code) + } + return + } + + // Retrieve the existing subscription + sub, err := subMgr.GetSubscription(subId) + if err != nil { + log.Error("Subscription not found: ", err.Error()) + errHandlerProblemDetails(w, "Subscription not found", http.StatusNotFound) + return + } + + // Retrieve the patch request body + if r.Body == nil { + err := errors.New("Request body is missing") + errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) + return + } + + var patchSub EventSubscriptionPatch + decoder := json.NewDecoder(r.Body) + err = decoder.Decode(&patchSub) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, "Failed to decode request body", http.StatusInternalServerError) + return + } + + // Apply partial updates + if patchSub.NotificationDestination != "" { + sub.Cfg.NotifyUrl = patchSub.NotificationDestination + } + + if patchSub.EventFilters != nil { + sub.Cfg.EventFilters = convertEventFiltersToStrings(patchSub.EventFilters) + } + + if patchSub.Events != nil { + sub.Cfg.CapifEvent = convertEventToStrings(patchSub.Events) + } + + // Update the subscription in the manager + err = subMgr.UpdateSubscription(sub) + if err != nil { + log.Error("Failed to update subscription: ", err.Error()) + errHandlerProblemDetails(w, "Failed to update subscription", http.StatusInternalServerError) + return + } + + // Convert the updated subscription to an EventSubscription struct + updatedSub := EventSubscription{ + NotificationDestination: sub.Cfg.NotifyUrl, + EventFilters: convertStringsToEventFilters(sub.Cfg.EventFilters), + Events: convertStringsToEvents(sub.Cfg.CapifEvent), + } + + // Convert the updated EventSubscription to JSON format for the response + jsonSub := convertSerAvailabilityNotifSubToJson_1(&updatedSub) + + // Send the full updated subscription in the response + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, jsonSub) +} + func applicationsSubscriptionsPUT(w http.ResponseWriter, r *http.Request) { log.Info("applicationsSubscriptionsPUT") w.Header().Set("Content-Type", "application/json; charset=UTF-8") @@ -932,8 +1022,21 @@ func applicationsSubscriptionsPUT(w http.ResponseWriter, r *http.Request) { return } if updatedSub.NotificationDestination == "" { - log.Error("Either NotificationDestination must be set") - errHandlerProblemDetails(w, "Either NotificationDestination must be set", http.StatusBadRequest) + log.Error("NotificationDestination is required for PUT") + errHandlerProblemDetails(w, "NotificationDestination is required", http.StatusBadRequest) + return + } + + // Assume `EventFilters` and `Events` are mandatory for `PUT` as well + if updatedSub.EventFilters == nil || len(updatedSub.EventFilters) == 0 { + log.Error("EventFilters are required for PUT") + errHandlerProblemDetails(w, "EventFilters are required", http.StatusBadRequest) + return + } + + if updatedSub.Events == nil || len(updatedSub.Events) == 0 { + log.Error("Events are required for PUT") + errHandlerProblemDetails(w, "Events are required", http.StatusBadRequest) return } // Update the subscription object diff --git a/go-apps/meep-app-enablement/server/routers.go b/go-apps/meep-app-enablement/server/routers.go index 6bc61bc6de5d002c1ae90ddbf2b8e559181cd369..1ad8f96b930446f4da7f46b1126c995e0ab2596b 100644 --- a/go-apps/meep-app-enablement/server/routers.go +++ b/go-apps/meep-app-enablement/server/routers.go @@ -399,6 +399,13 @@ var routes = Routes{ capifMgmt.ApplicationsSubscriptionsPUT, }, + Route{ + "ApplicationsSubscriptionsPATCH", + strings.ToUpper("Patch"), + "/capif-events/v1/{subscriberId}/subscriptions/{subscriptionId}", + capifMgmt.ApplicationsSubscriptionsPATCH, + }, + Route{ "ApplicationsSubscriptionDELETE", strings.ToUpper("Delete"),