diff --git a/go-apps/meep-app-enablement/api/capif-mgmt/swagger.yaml b/go-apps/meep-app-enablement/api/capif-mgmt/swagger.yaml index e803dcdbe5604aa6da75f3045a98139b1544ebf1..b2cd8178bfea67c7408e44b3a5a7843c6ca4e128 100644 --- a/go-apps/meep-app-enablement/api/capif-mgmt/swagger.yaml +++ b/go-apps/meep-app-enablement/api/capif-mgmt/swagger.yaml @@ -955,6 +955,15 @@ components: description: | URI to which notifications will be sent. Shall be set to the value of the "callbackReference" attribute in the "SerAvailabilityNotificationSubscription" structure. format: uri + CAPIFEventFilter: + title: CAPIFEventFilter + type: object + properties: + apiIds: + type: array + description: Identifiers of service instances about which to report events. + items: + type: string EventSubscription: required: - events @@ -965,6 +974,10 @@ components: type: array items: $ref: '#/components/schemas/CAPIFEvent' + eventFilters: + type: array + items: + $ref: '#/components/schemas/CAPIFEventFilter' notificationDestination: type: string description: | 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 552e31521e9376ce8cd4b3072401a43e3bc86e3f..5da1e273738bd31fd945306393c7d5bc9c8eb2a5 100644 --- a/go-apps/meep-app-enablement/server/capif-mgmt/convert.go +++ b/go-apps/meep-app-enablement/server/capif-mgmt/convert.go @@ -68,6 +68,15 @@ func convertSerAvailabilityNotifSubToJson(obj *SerAvailabilityNotificationSubscr return string(jsonInfo) } +func convertSerAvailabilityNotifSubToJson_1(obj *EventSubscription) string { + jsonInfo, err := json.Marshal(*obj) + if err != nil { + log.Error(err.Error()) + return "" + } + return string(jsonInfo) +} + func convertJsonToSerAvailabilityNotifSub(jsonData string) *SerAvailabilityNotificationSubscription { var obj SerAvailabilityNotificationSubscription err := json.Unmarshal([]byte(jsonData), &obj) diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/model_capif_event.go b/go-apps/meep-app-enablement/server/capif-mgmt/model_capif_event.go new file mode 100644 index 0000000000000000000000000000000000000000..fc5c7bcac74fe3e04bd55bf099cccb492ba8936d --- /dev/null +++ b/go-apps/meep-app-enablement/server/capif-mgmt/model_capif_event.go @@ -0,0 +1,20 @@ +/* + * 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 + +// CapifEvent : The CAPIFEvent data type represents the type of events for which the subscription is made. +type CapifEvent string + +// List of CAPIFEvent +const ( + AVAILABLE CapifEvent = "SERVICE_API_AVAILABLE" + UNAVAILABLE CapifEvent = "SERVICE_API_UNAVAILABLE" + UPDATE CapifEvent = "SERVICE_API_UPDATE" +) diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/model_capif_event_filter.go b/go-apps/meep-app-enablement/server/capif-mgmt/model_capif_event_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..5d11b2da844ebd993a1aff6d8277476df37211e5 --- /dev/null +++ b/go-apps/meep-app-enablement/server/capif-mgmt/model_capif_event_filter.go @@ -0,0 +1,15 @@ +/* + * 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 CapifEventFilter struct { + // Identifiers of service instances about which to report events. + ApiIds []string `json:"apiIds,omitempty"` +} diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/model_event_subscription.go b/go-apps/meep-app-enablement/server/capif-mgmt/model_event_subscription.go new file mode 100644 index 0000000000000000000000000000000000000000..1f8fe22ca20dbba3bf911bd01824409c81b53165 --- /dev/null +++ b/go-apps/meep-app-enablement/server/capif-mgmt/model_event_subscription.go @@ -0,0 +1,22 @@ +/* + * 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 EventSubscription struct { + Events []CapifEvent `json:"events"` + + EventFilters []CapifEventFilter `json:"eventFilters,omitempty"` + // URI selected by the MEC application instance to receive notifications on the subscribed MEC service availability information. This shall be included in both the request and the response. + NotificationDestination string `json:"notificationDestination"` + + RequestTestNotification bool `json:"requestTestNotification,omitempty"` + + WebsocketNotifConfig string `json:"websocketNotifConfig,omitempty"` +} diff --git a/go-apps/meep-app-enablement/server/capif-mgmt/model_service_availability_notification_service_references.go b/go-apps/meep-app-enablement/server/capif-mgmt/model_service_availability_notification_service_references.go index 9315e529d65cf80f07b8ddde37faa4405d734d26..025455a7e169a5c239cc5e55ab1450b370d624c1 100644 --- a/go-apps/meep-app-enablement/server/capif-mgmt/model_service_availability_notification_service_references.go +++ b/go-apps/meep-app-enablement/server/capif-mgmt/model_service_availability_notification_service_references.go @@ -19,5 +19,5 @@ type ServiceAvailabilityNotificationServiceReferences struct { State *ServiceState `json:"state"` - ChangeType *ServiceAvailabilityNotificationChangeType `json:"changeType"` + ChangeType *CapifEvent `json:"changeType"` } 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 c885c6f8b45c179cdd9993515a9b4b2a30bd35f8..1e92363157be11afedae48dca4c7843f6cda7a98 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 @@ -394,7 +394,7 @@ func appServicesPOST(w http.ResponseWriter, r *http.Request) { } } - err, retCode := setService(appId, sInfo, ADDED_ServiceAvailabilityNotificationChangeType) + err, retCode := setService(appId, sInfo, AVAILABLE) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), retCode) @@ -541,14 +541,14 @@ func appServicesByIdPUT(w http.ResponseWriter, r *http.Request) { // Compare service info states & update DB if necessary *_sInfo.State = state if *_sInfo.State != *sInfoPrev.State { - err, retCode := setService(appId, &_sInfo, STATE_CHANGED_ServiceAvailabilityNotificationChangeType) + err, retCode := setService(appId, &_sInfo, UPDATE) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), retCode) return } } else { - err, retCode := setService(appId, &_sInfo, ATTRIBUTES_CHANGED_ServiceAvailabilityNotificationChangeType) + err, retCode := setService(appId, &_sInfo, UPDATE) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), retCode) @@ -686,14 +686,14 @@ func appServicesByIdPATCH(w http.ResponseWriter, r *http.Request) { // Compare service info states & update DB if necessary // *_sInfo.State = state if *_sInfo.State != *sInfoPrev.State { - err, retCode := setService(appId, &_sInfo, STATE_CHANGED_ServiceAvailabilityNotificationChangeType) + err, retCode := setService(appId, &_sInfo, UPDATE) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), retCode) return } } else { - err, retCode := setService(appId, &_sInfo, ATTRIBUTES_CHANGED_ServiceAvailabilityNotificationChangeType) + err, retCode := setService(appId, &_sInfo, UPDATE) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), retCode) @@ -769,7 +769,7 @@ func appServicesByIdDELETE(w http.ResponseWriter, r *http.Request) { } // Notify remote listeners (except if global instance) - changeType := REMOVED_ServiceAvailabilityNotificationChangeType + changeType := UNAVAILABLE if mepName != globalMepName { sendSvcUpdateMsg(sInfoJson, appId, mepName, string(changeType)) } @@ -918,7 +918,7 @@ func applicationsSubscriptionsPOST(w http.ResponseWriter, r *http.Request) { errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) return } - var serAvailNotifSub SerAvailabilityNotificationSubscription + var serAvailNotifSub EventSubscription decoder := json.NewDecoder(r.Body) err = decoder.Decode(&serAvailNotifSub) if err != nil { @@ -928,41 +928,22 @@ func applicationsSubscriptionsPOST(w http.ResponseWriter, r *http.Request) { } // Validate mandatory properties - if serAvailNotifSub.CallbackReference == "" { - log.Error("Mandatory CallbackReference parameter not present") - errHandlerProblemDetails(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest) - return - } - if serAvailNotifSub.SubscriptionType != SER_AVAILABILITY_NOTIF_SUB_TYPE { - log.Error("SubscriptionType shall be SerAvailabilityNotificationSubscription") - errHandlerProblemDetails(w, "SubscriptionType shall be SerAvailabilityNotificationSubscription", http.StatusBadRequest) + if serAvailNotifSub.NotificationDestination == "" { + log.Error("Mandatory NotificationDestination parameter not present") + errHandlerProblemDetails(w, "Mandatory NotificationDestination parameter not present", http.StatusBadRequest) return } + // if serAvailNotifSub.SubscriptionType != SER_AVAILABILITY_NOTIF_SUB_TYPE { + // log.Error("SubscriptionType shall be SerAvailabilityNotificationSubscription") + // errHandlerProblemDetails(w, "SubscriptionType shall be SerAvailabilityNotificationSubscription", http.StatusBadRequest) + // return + // } // Validate Service filter params - if serAvailNotifSub.FilteringCriteria != nil { + if serAvailNotifSub.EventFilters != nil { nbMutuallyExclusiveParams := 0 - if serAvailNotifSub.FilteringCriteria.SerInstanceIds != nil { - if len(serAvailNotifSub.FilteringCriteria.SerInstanceIds) > 0 { - nbMutuallyExclusiveParams++ - } - } - if serAvailNotifSub.FilteringCriteria.SerNames != nil { - if len(serAvailNotifSub.FilteringCriteria.SerNames) > 0 { - nbMutuallyExclusiveParams++ - } - } - if serAvailNotifSub.FilteringCriteria.SerCategories != nil { - for _, categoryRef := range serAvailNotifSub.FilteringCriteria.SerCategories { - errStr := validateCategoryRef(&categoryRef) - if errStr != "" { - log.Error(errStr) - errHandlerProblemDetails(w, errStr, http.StatusBadRequest) - return - } - } - - if len(serAvailNotifSub.FilteringCriteria.SerCategories) > 0 { + for _, filter := range serAvailNotifSub.EventFilters { + if filter.ApiIds != nil && len(filter.ApiIds) > 0 { nbMutuallyExclusiveParams++ } } @@ -977,25 +958,29 @@ func applicationsSubscriptionsPOST(w http.ResponseWriter, r *http.Request) { // Get a new subscription ID subId := subMgr.GenerateSubscriptionId() - // Set resource link - serAvailNotifSub.Links = &Self{ - Self: &LinkType{ - Href: hostUrl.String() + basePath + "applications/" + appId + "/subscriptions/" + subId, - }, - } + // // Set resource link + // serAvailNotifSub.Links = &Self{ + // Self: &LinkType{ + // Href: hostUrl.String() + basePath + "applications/" + appId + "/subscriptions/" + subId, + // }, + // } // Create & store subscription - subCfg := newSerAvailabilityNotifSubCfg(&serAvailNotifSub, subId, appId) - jsonSub := convertSerAvailabilityNotifSubToJson(&serAvailNotifSub) + subCfg := newSerAvailabilityNotifSubCfg_1(&serAvailNotifSub, subId, appId) + jsonSub := convertSerAvailabilityNotifSubToJson_1(&serAvailNotifSub) _, err = subMgr.CreateSubscription(subCfg, jsonSub) if err != nil { log.Error("Failed to create subscription") errHandlerProblemDetails(w, "Failed to create subscription", http.StatusInternalServerError) return } - + // Self: + // &LinkType{ + // Href: hostUrl.String() + basePath + "applications/" + appId + "/subscriptions/" + subId, + // } + hrefUrl := hostUrl.String() + basePath + "applications/" + appId + "/subscriptions/" + subId // Send response - w.Header().Set("Location", serAvailNotifSub.Links.Self.Href) + w.Header().Set("Location", hrefUrl) w.WriteHeader(http.StatusCreated) fmt.Fprint(w, jsonSub) } @@ -1369,7 +1354,7 @@ func deleteService(key string, sInfoJson string, data interface{}) error { sInfo := convertJsonToServiceInfo(sInfoJson) // Notify remote listeners (except if global instance) - changeType := REMOVED_ServiceAvailabilityNotificationChangeType + changeType := UNAVAILABLE if mepName != globalMepName { sendSvcUpdateMsg(sInfoJson, appId, mepName, string(changeType)) } @@ -1395,7 +1380,7 @@ func delServiceById(appId string, svcId string) error { return nil } -func setService(appId string, sInfo *ServiceInfo, changeType ServiceAvailabilityNotificationChangeType) (err error, retCode int) { +func setService(appId string, sInfo *ServiceInfo, changeType CapifEvent) (err error, retCode int) { // Create/update service sInfoJson := convertServiceInfoToJson(sInfo) key := baseKey + "app:" + appId + ":svc:" + sInfo.SerInstanceId @@ -1823,10 +1808,10 @@ func processSvcUpdate(sInfoJson, mep, changeType string) { sInfo := convertJsonToServiceInfo(sInfoJson) // Check if notifications must be sent - checkSerAvailNotification(sInfo, mep, ServiceAvailabilityNotificationChangeType(changeType)) + checkSerAvailNotification(sInfo, mep, CapifEvent(changeType)) } -func checkSerAvailNotification(sInfo *ServiceInfo, mep string, changeType ServiceAvailabilityNotificationChangeType) { +func checkSerAvailNotification(sInfo *ServiceInfo, mep string, changeType CapifEvent) { // Set IsLocal flag if *sInfo.ScopeOfLocality == MEC_SYSTEM_LocalityType || (mep != "" && mep == mepName) { sInfo.IsLocal = true @@ -2081,6 +2066,21 @@ func newSerAvailabilityNotifSubCfg(sub *SerAvailabilityNotificationSubscription, return subCfg } +func newSerAvailabilityNotifSubCfg_1(sub *EventSubscription, subId string, appId string) *subs.SubscriptionCfg { + subCfg := &subs.SubscriptionCfg{ + Id: subId, + AppId: appId, + Type: SER_AVAILABILITY_NOTIF_SUB_TYPE, + Self: "", + NotifyUrl: sub.NotificationDestination, + ExpiryTime: nil, + PeriodicInterval: 0, + RequestTestNotif: false, + RequestWebsocketUri: false, + } + return subCfg +} + func errHandlerProblemDetails(w http.ResponseWriter, error string, code int) { var pd ProblemDetails pd.Detail = error