From 0fceb460e24dd3119b55cdeb6cea786a0c51e828 Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Wed, 28 May 2025 11:22:51 -0600 Subject: [PATCH 1/8] Initialize EAM /appinstances callback --- .../Edge-Application-Management.yaml | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/code/API_definitions/Edge-Application-Management.yaml b/code/API_definitions/Edge-Application-Management.yaml index 51731dab..d356034a 100644 --- a/code/API_definitions/Edge-Application-Management.yaml +++ b/code/API_definitions/Edge-Application-Management.yaml @@ -395,6 +395,8 @@ paths: $ref: '#/components/schemas/EdgeCloudZoneId' kubernetesClusterRef: $ref: '#/components/schemas/KubernetesClusterRef' + notificationSink: + $ref: '#/components/schemas/NotificationSink' required: true responses: '202': @@ -434,6 +436,9 @@ paths: $ref: '#/components/responses/501' '503': $ref: '#/components/responses/503' + callbacks: + onAppStatusChange: + $ref: '#/components/callbacks/onAppStatusChange' get: security: - openId: @@ -679,6 +684,40 @@ components: schema: type: string format: uuid + ######################################################################### + # Events/Callbacks # + ######################################################################### + callbacks: + onAppStatusChange: + '{$request.body.notificationSink.sink}': + post: + tags: + - App Instance CALLBACK Operation + summary: Provide a notification for a change in status + of the instantiated application + description: Instantiating an application is an asyncronous task. After the + application has been started, the server will return a callback + at the specified URL. + operationId: EdgeApplicationManagementCallback + parameters: + - $ref: '#/components/parameters/x-correlator' + security: + - notificationsBearerAuth: [] + requestBody: + description: Body containing the status of the Application + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AppCallback' + responses: + '202': + description: Your server implementation should return this HTTP + status code if the data was received successfully + content: {} + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' schemas: AccessEndpoint: @@ -965,6 +1004,20 @@ components: pattern: ^[A-Za-z][A-Za-z0-9_]{7,63}$ description: Human readable name of the Application Provider. + AppCallback: + type: object + required: + - status + - appInstanceId + properties: + status: + type: string + enum: [Running, Failed] + description: Status of the application instance + (Running, Failed) + appInstanceId: + $ref: '#/components/schemas/AppInstanceId' + ClusterInfo: description: Kubernetes cluster information required: @@ -1163,6 +1216,44 @@ components: - vfio-pci - interface + NotificationSink: + description: "" + type: object + required: + - sink + properties: + sink: + description: 'https callback address where the notification + must be POST-ed' + type: string + format: uri + sinkCredentials: + description: Sink credential provides authorization information + necessary to enable delivery of events to a target + type: object + properties: + credentialtype: + type: string + description: Type of the credential - MUST be set to + ACCESSTOKEN for now + enum: + - "ACCESSTOKEN" + accessToken: + type: string + description: Access Token granting access to the POST + operation to create notification + accessTokenExpireUtc: + type: string + format: date-time + description: An absolute UTC instant at which the access + token shall be considered expired. + accessTokenType: + type: string + description: Type of access token - MUST be set to bearer + for now + enum: + - "bearer" + AdditionalStorage: description: Additional storage for the application. type: array From 2bd31ab583f354c492f2bab0ecdf871658c9e3a8 Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Wed, 28 May 2025 13:00:40 -0600 Subject: [PATCH 2/8] Commit for EasyCLA --- code/API_definitions/Edge-Application-Management.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/API_definitions/Edge-Application-Management.yaml b/code/API_definitions/Edge-Application-Management.yaml index d356034a..da95e1b9 100644 --- a/code/API_definitions/Edge-Application-Management.yaml +++ b/code/API_definitions/Edge-Application-Management.yaml @@ -696,7 +696,7 @@ components: summary: Provide a notification for a change in status of the instantiated application description: Instantiating an application is an asyncronous task. After the - application has been started, the server will return a callback + application has been started, the server will return a callback response at the specified URL. operationId: EdgeApplicationManagementCallback parameters: From faa7613ab3d60d615a04ca99bdd0d69dffacc2cb Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Thu, 29 May 2025 13:13:30 -0600 Subject: [PATCH 3/8] Update callback to return full object --- .../Edge-Application-Management.yaml | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/code/API_definitions/Edge-Application-Management.yaml b/code/API_definitions/Edge-Application-Management.yaml index da95e1b9..57641c60 100644 --- a/code/API_definitions/Edge-Application-Management.yaml +++ b/code/API_definitions/Edge-Application-Management.yaml @@ -437,8 +437,8 @@ paths: '503': $ref: '#/components/responses/503' callbacks: - onAppStatusChange: - $ref: '#/components/callbacks/onAppStatusChange' + onAppInstanceStatusChange: + $ref: '#/components/callbacks/onAppInstanceStatusChange' get: security: - openId: @@ -688,7 +688,7 @@ components: # Events/Callbacks # ######################################################################### callbacks: - onAppStatusChange: + onAppInstanceStatusChange: '{$request.body.notificationSink.sink}': post: tags: @@ -709,7 +709,9 @@ components: content: application/json: schema: - $ref: '#/components/schemas/AppCallback' + type: array + items: + $ref: '#/components/schemas/AppInstanceInfo' responses: '202': description: Your server implementation should return this HTTP @@ -1004,20 +1006,6 @@ components: pattern: ^[A-Za-z][A-Za-z0-9_]{7,63}$ description: Human readable name of the Application Provider. - AppCallback: - type: object - required: - - status - - appInstanceId - properties: - status: - type: string - enum: [Running, Failed] - description: Status of the application instance - (Running, Failed) - appInstanceId: - $ref: '#/components/schemas/AppInstanceId' - ClusterInfo: description: Kubernetes cluster information required: From 8f1b2448bb1865339429fef9348debb7ffb6ce25 Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Tue, 23 Sep 2025 15:04:51 -0600 Subject: [PATCH 4/8] Align towards commonalities and add deployment callback --- .../Edge-Application-Management.yaml | 71 ++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/code/API_definitions/Edge-Application-Management.yaml b/code/API_definitions/Edge-Application-Management.yaml index 19a894f8..677c57fe 100644 --- a/code/API_definitions/Edge-Application-Management.yaml +++ b/code/API_definitions/Edge-Application-Management.yaml @@ -636,6 +636,9 @@ paths: $ref: '#/components/responses/501' '503': $ref: '#/components/responses/503' + callbacks: + onAppInstanceStatusChange: + $ref: '#/components/callbacks/onAppDeploymentStatusChange' get: security: - openId: @@ -1031,13 +1034,66 @@ components: items: $ref: '#/components/schemas/AppInstanceInfo' responses: - '202': + '204': + description: Your server implementation should return this HTTP + status code if the data was received successfully + content: {} + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '410': + $ref: '#/components/responses/410' + '429': + $ref: '#/components/responses/429' + + onAppDeploymentStatusChange: + '{$request.body.notificationSink.sink}': + post: + tags: + - App Deployment CALLBACK Operation + summary: Provide a notification for a change in status + of the deployed application + description: Deploying an application is an asyncronous task. After the + application has been started, the server will return a callback response + at the specified URL. + operationId: EdgeApplicationManagementDeploymentCallback + parameters: + - $ref: '#/components/parameters/x-correlator' + security: + - notificationsBearerAuth: [] + requestBody: + description: Body containing the status of the Application Deployment + required: true + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/AppDeploymentInfo' + responses: + '204': description: Your server implementation should return this HTTP status code if the data was received successfully content: {} headers: x-correlator: $ref: '#/components/headers/x-correlator' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '410': + $ref: '#/components/responses/410' + '429': + $ref: '#/components/responses/429' schemas: AccessEndpoint: @@ -2081,6 +2137,19 @@ components: status: 410 code: GONE message: "The resource has been permanently removed" + '429': + description: Too Many Requests + headers: + X-Correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorInfo" + example: + status: 429 + code: QUOTA_EXCEEDED + message: "Quota exceeded: ..." '500': description: Internal Server Error headers: From d8030199a65b7bf688348e2a7386ee847154a531 Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Tue, 23 Sep 2025 15:26:48 -0600 Subject: [PATCH 5/8] Align callbacks as a subscription to follow commonalities --- .../Edge-Application-Management.yaml | 341 +++++++++++++++++- 1 file changed, 336 insertions(+), 5 deletions(-) diff --git a/code/API_definitions/Edge-Application-Management.yaml b/code/API_definitions/Edge-Application-Management.yaml index 677c57fe..3461efbf 100644 --- a/code/API_definitions/Edge-Application-Management.yaml +++ b/code/API_definitions/Edge-Application-Management.yaml @@ -408,8 +408,8 @@ paths: $ref: '#/components/schemas/EdgeCloudZoneId' kubernetesClusterRef: $ref: '#/components/schemas/KubernetesClusterRef' - notificationSink: - $ref: '#/components/schemas/NotificationSink' + subscriptionRequest: + $ref: '#/components/schemas/SubscriptionRequest' required: true responses: '202': @@ -600,6 +600,8 @@ paths: type: array items: $ref: '#/components/schemas/KubernetesClusterRef' + subscriptionRequest: + $ref: '#/components/schemas/SubscriptionRequest' required: true responses: '202': @@ -1005,9 +1007,6 @@ components: schema: type: string format: uuid - ######################################################################### - # Events/Callbacks # - ######################################################################### callbacks: onAppInstanceStatusChange: '{$request.body.notificationSink.sink}': @@ -1096,6 +1095,338 @@ components: $ref: '#/components/responses/429' schemas: + Protocol: + type: string + enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] + description: Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + + SubscriptionId: + type: string + description: The unique identifier of the subscription in the scope of the subscription manager. When this information is contained within an event notification, this concept SHALL be referred as `subscriptionId` as per [Commonalities Event Notification Model](/documentation/API-design-guidelines.md#122-event-notification). + example: qs15-h556-rt89-1298 + + Subscription: + description: Represents a event-type subscription. + type: object + required: + - sink + - protocol + - config + - types + - id + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: The address to which events shall be delivered using the selected protocol. + example: "https://endpoint.example.com/sink" + types: + description: | + Camara Event types eligible to be delivered by this subscription. + Note: the maximum number of event types per subscription will be decided at API project level + type: array + minItems: 1 + maxItems: 1 + items: + $ref: "#/components/schemas/SubscriptionEventType" + config: + $ref: '#/components/schemas/SubscriptionConfig' + id: + $ref: '#/components/schemas/SubscriptionId' + startsAt: + type: string + format: date-time + description: | + Date when the event subscription will begin/began + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + expiresAt: + type: string + format: date-time + description: | + Date when the event subscription will expire. Only provided when `subscriptionExpireTime` is indicated by API client or Telco Operator has specific policy about that. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + status: + type: string + description: |- + Current status of the subscription - Management of Subscription State engine is not mandatory for now. Note not all statuses may be considered to be implemented. Details: + - `ACTIVATION_REQUESTED`: Subscription creation (POST) is triggered but subscription creation process is not finished yet. + - `ACTIVE`: Subscription creation process is completed. Subscription is fully operative. + - `INACTIVE`: Subscription is temporarily inactive, but its workflow logic is not deleted. + - `EXPIRED`: Subscription is ended (no longer active). This status applies when subscription is ended due to `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. + - `DELETED`: Subscription is ended as deleted (no longer active). This status applies when subscription information is kept (i.e. subscription workflow is no longer active but its meta-information is kept). + enum: + - ACTIVATION_REQUESTED + - ACTIVE + - EXPIRED + - INACTIVE + - DELETED + discriminator: + propertyName: protocol + mapping: + HTTP: '#/components/schemas/HTTPSubscriptionResponse' + MQTT3: '#/components/schemas/MQTTSubscriptionResponse' + MQTT5: '#/components/schemas/MQTTSubscriptionResponse' + AMQP: '#/components/schemas/AMQPSubscriptionResponse' + NATS: '#/components/schemas/NATSSubscriptionResponse' + KAFKA: '#/components/schemas/ApacheKafkaSubscriptionResponse' + + SubscriptionRequest: + description: The request for creating a event-type event subscription + type: object + required: + - sink + - protocol + - config + - types + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: The address to which events shall be delivered using the selected protocol. + example: "https://endpoint.example.com/sink" + sinkCredential: + $ref: "#/components/schemas/SinkCredential" + types: + description: | + Camara Event types eligible to be delivered by this subscription. + Note: the maximum number of event types per subscription will be decided at API project level + type: array + minItems: 1 + maxItems: 1 + items: + $ref: "#/components/schemas/SubscriptionEventType" + config: + $ref: "#/components/schemas/SubscriptionConfig" + discriminator: + propertyName: protocol + mapping: + HTTP: "#/components/schemas/HTTPSubscriptionRequest" + MQTT3: "#/components/schemas/MQTTSubscriptionRequest" + MQTT5: "#/components/schemas/MQTTSubscriptionRequest" + AMQP: "#/components/schemas/AMQPSubscriptionRequest" + NATS: "#/components/schemas/NATSSubscriptionRequest" + KAFKA: "#/components/schemas/ApacheKafkaSubscriptionRequest" + + SubscriptionConfig: + description: | + Implementation-specific configuration parameters needed by the subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`, `subscriptionMaxEvents`, `initialEvent` + Specific event type attributes must be defined in `subscriptionDetail` + Note: if a request is performed for several event type, all subscribed event will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + description: The detail of the requested event subscription. + type: object + subscriptionExpireTime: + type: string + format: date-time + example: 2023-01-17T13:18:23.682Z + description: The subscription expiration time (in date-time format) requested by the API consumer. It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. Up to API project decision to keep it. + subscriptionMaxEvents: + type: integer + description: Identifies the maximum number of event reports to be generated (>=1) requested by the API consumer - Once this number is reached, the subscription ends. Up to API project decision to keep it. + minimum: 1 + example: 5 + initialEvent: + type: boolean + description: | + Set to `true` by API consumer if consumer wants to get an event as soon as the subscription is created and current situation reflects event request. + Example: Consumer request Roaming event. If consumer sets initialEvent to true and device is in roaming situation, an event is triggered + Up to API project decision to keep it. + + SubscriptionEventType: + type: string + description: | + event-type that could be subscribed through this subscription. Several event-type could be defined. + enum: + - org.camaraproject.Edge-Application-Management.v0.onAppInstanceStatusChange + - org.camaraproject.Edge-Application-Management.v0.onDeploymentStatusChange + + SinkCredential: + description: A sink credential provides authentication or authorization information necessary to enable delivery of events to a target. + type: object + properties: + credentialType: + type: string + enum: + - PLAIN + - ACCESSTOKEN + - REFRESHTOKEN + description: | + The type of the credential. + Note: Type of the credential - MUST be set to ACCESSTOKEN for now + discriminator: + propertyName: credentialType + mapping: + PLAIN: "#/components/schemas/PlainCredential" + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" + required: + - credentialType + + HTTPSubscriptionRequest: + allOf: + - $ref: "#/components/schemas/SubscriptionRequest" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/HTTPSettings" + + HTTPSubscriptionResponse: + allOf: + - $ref: "#/components/schemas/Subscription" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/HTTPSettings" + + HTTPSettings: + type: object + properties: + headers: + type: object + description: |- + A set of key/value pairs that is copied into the HTTP request as custom headers. + NOTE: Use/Applicability of this concept has not been discussed in Commonalities under the scope of Meta Release v0.4. When required by an API project as an option to meet a UC/Requirement, please generate an issue for Commonalities discussion about it. + additionalProperties: + type: string + method: + type: string + description: The HTTP method to use for sending the message. + enum: + - POST + + MQTTSubscriptionRequest: + allOf: + - $ref: "#/components/schemas/SubscriptionRequest" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/MQTTSettings" + + MQTTSubscriptionResponse: + allOf: + - $ref: "#/components/schemas/Subscription" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/MQTTSettings" + + MQTTSettings: + type: object + properties: + topicName: + type: string + qos: + type: integer + format: int32 + retain: + type: boolean + expiry: + type: integer + format: int32 + userProperties: + type: object + required: + - topicName + + AMQPSubscriptionRequest: + allOf: + - $ref: "#/components/schemas/SubscriptionRequest" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/AMQPSettings" + + AMQPSubscriptionResponse: + allOf: + - $ref: "#/components/schemas/Subscription" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/AMQPSettings" + + AMQPSettings: + type: object + properties: + address: + type: string + linkName: + type: string + senderSettlementMode: + type: string + enum: ["settled", "unsettled"] + linkProperties: + type: object + additionalProperties: + type: string + + ApacheKafkaSubscriptionRequest: + allOf: + - $ref: "#/components/schemas/SubscriptionRequest" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/ApacheKafkaSettings" + + ApacheKafkaSubscriptionResponse: + allOf: + - $ref: "#/components/schemas/Subscription" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/ApacheKafkaSettings" + + ApacheKafkaSettings: + type: object + properties: + topicName: + type: string + partitionKeyExtractor: + type: string + clientId: + type: string + ackMode: + type: integer + required: + - topicName + + NATSSubscriptionRequest: + allOf: + - $ref: "#/components/schemas/SubscriptionRequest" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/NATSSettings" + + NATSSubscriptionResponse: + allOf: + - $ref: "#/components/schemas/Subscription" + - type: object + properties: + protocolSettings: + $ref: "#/components/schemas/NATSSettings" + + NATSSettings: + type: object + properties: + subject: + type: string + required: + - subject + AccessEndpoint: type: object description: | From 09be1ffc819bc6314549427e9a3f540bb6aaa805 Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Tue, 23 Sep 2025 15:33:21 -0600 Subject: [PATCH 6/8] Remove unused notificationSink --- .../Edge-Application-Management.yaml | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/code/API_definitions/Edge-Application-Management.yaml b/code/API_definitions/Edge-Application-Management.yaml index 3461efbf..422a5b1b 100644 --- a/code/API_definitions/Edge-Application-Management.yaml +++ b/code/API_definitions/Edge-Application-Management.yaml @@ -1946,44 +1946,6 @@ components: - vfio-pci - interface - NotificationSink: - description: "" - type: object - required: - - sink - properties: - sink: - description: 'https callback address where the notification - must be POST-ed' - type: string - format: uri - sinkCredentials: - description: Sink credential provides authorization information - necessary to enable delivery of events to a target - type: object - properties: - credentialtype: - type: string - description: Type of the credential - MUST be set to - ACCESSTOKEN for now - enum: - - "ACCESSTOKEN" - accessToken: - type: string - description: Access Token granting access to the POST - operation to create notification - accessTokenExpireUtc: - type: string - format: date-time - description: An absolute UTC instant at which the access - token shall be considered expired. - accessTokenType: - type: string - description: Type of access token - MUST be set to bearer - for now - enum: - - "bearer" - AdditionalStorage: description: Additional storage for the application. type: array From 3713abe1d5ef03bbcf7ed4602408393f95997ac9 Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Tue, 4 Nov 2025 11:17:41 -0700 Subject: [PATCH 7/8] Remove messaging protocols --- .../Edge-Application-Management.yaml | 387 +++++------------- 1 file changed, 100 insertions(+), 287 deletions(-) diff --git a/code/API_definitions/Edge-Application-Management.yaml b/code/API_definitions/Edge-Application-Management.yaml index 422a5b1b..1de7f0ac 100644 --- a/code/API_definitions/Edge-Application-Management.yaml +++ b/code/API_definitions/Edge-Application-Management.yaml @@ -639,7 +639,7 @@ paths: '503': $ref: '#/components/responses/503' callbacks: - onAppInstanceStatusChange: + onAppDeploymentStatusChange: $ref: '#/components/callbacks/onAppDeploymentStatusChange' get: security: @@ -1007,36 +1007,34 @@ components: schema: type: string format: uuid + callbacks: onAppInstanceStatusChange: - '{$request.body.notificationSink.sink}': + '{$request.body#/subscriptionRequest/sink}': post: tags: - App Instance CALLBACK Operation - summary: Provide a notification for a change in status - of the instantiated application - description: Instantiating an application is an asyncronous task. After the - application has been started, the server will return a callback response - at the specified URL. + summary: Provide a notification for a change in status of the instantiated application + description: | + Instantiating an application is an asynchronous task. After the application status changes, + the server will return a callback response at the specified URL. + + **WARNING**: This callback endpoint must be exposed on the listener side as `POST {$request.body#/subscriptionRequest/sink}` operationId: EdgeApplicationManagementCallback parameters: - $ref: '#/components/parameters/x-correlator' security: - notificationsBearerAuth: [] requestBody: - description: Body containing the status of the Application + description: Event notification with the status of the Application Instance required: true content: - application/json: + application/cloudevents+json: schema: - type: array - items: - $ref: '#/components/schemas/AppInstanceInfo' + $ref: '#/components/schemas/CloudEvent' responses: '204': - description: Your server implementation should return this HTTP - status code if the data was received successfully - content: {} + description: Successful notification - No Content headers: x-correlator: $ref: '#/components/headers/x-correlator' @@ -1052,34 +1050,31 @@ components: $ref: '#/components/responses/429' onAppDeploymentStatusChange: - '{$request.body.notificationSink.sink}': + '{$request.body#/subscriptionRequest/sink}': post: tags: - App Deployment CALLBACK Operation - summary: Provide a notification for a change in status - of the deployed application - description: Deploying an application is an asyncronous task. After the - application has been started, the server will return a callback response - at the specified URL. + summary: Provide a notification for a change in status of the deployed application + description: | + Deploying an application is an asynchronous task. After the application deployment status changes, + the server will return a callback response at the specified URL. + + **WARNING**: This callback endpoint must be exposed on the listener side as `POST {$request.body#/subscriptionRequest/sink}` operationId: EdgeApplicationManagementDeploymentCallback parameters: - $ref: '#/components/parameters/x-correlator' security: - notificationsBearerAuth: [] requestBody: - description: Body containing the status of the Application Deployment + description: Event notification with the status of the Application Deployment required: true content: - application/json: + application/cloudevents+json: schema: - type: array - items: - $ref: '#/components/schemas/AppDeploymentInfo' + $ref: '#/components/schemas/CloudEvent' responses: '204': - description: Your server implementation should return this HTTP - status code if the data was received successfully - content: {} + description: Successful notification - No Content headers: x-correlator: $ref: '#/components/headers/x-correlator' @@ -1095,98 +1090,80 @@ components: $ref: '#/components/responses/429' schemas: - Protocol: - type: string - enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] - description: Identifier of a delivery protocol. Only HTTP is allowed for now - example: "HTTP" - - SubscriptionId: - type: string - description: The unique identifier of the subscription in the scope of the subscription manager. When this information is contained within an event notification, this concept SHALL be referred as `subscriptionId` as per [Commonalities Event Notification Model](/documentation/API-design-guidelines.md#122-event-notification). - example: qs15-h556-rt89-1298 - - Subscription: - description: Represents a event-type subscription. + CloudEvent: + description: Cloud Event notification following CloudEvents 1.0 specification type: object required: - - sink - - protocol - - config - - types - id + - source + - type + - specversion + - time properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - pattern: ^https:\/\/.+$ - description: The address to which events shall be delivered using the selected protocol. - example: "https://endpoint.example.com/sink" - types: - description: | - Camara Event types eligible to be delivered by this subscription. - Note: the maximum number of event types per subscription will be decided at API project level - type: array - minItems: 1 - maxItems: 1 - items: - $ref: "#/components/schemas/SubscriptionEventType" - config: - $ref: '#/components/schemas/SubscriptionConfig' id: - $ref: '#/components/schemas/SubscriptionId' - startsAt: type: string - format: date-time - description: | - Date when the event subscription will begin/began - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - expiresAt: + description: Identifier of this event, that must be unique in the source context + example: "123e4567-e89b-12d3-a456-426614174000" + source: type: string - format: date-time - description: | - Date when the event subscription will expire. Only provided when `subscriptionExpireTime` is indicated by API client or Telco Operator has specific policy about that. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - status: + format: uri + description: Identifies the context in which an event happened + example: "https://edge-cloud-provider.example.com" + type: + $ref: '#/components/schemas/SubscriptionEventType' + specversion: type: string - description: |- - Current status of the subscription - Management of Subscription State engine is not mandatory for now. Note not all statuses may be considered to be implemented. Details: - - `ACTIVATION_REQUESTED`: Subscription creation (POST) is triggered but subscription creation process is not finished yet. - - `ACTIVE`: Subscription creation process is completed. Subscription is fully operative. - - `INACTIVE`: Subscription is temporarily inactive, but its workflow logic is not deleted. - - `EXPIRED`: Subscription is ended (no longer active). This status applies when subscription is ended due to `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. - - `DELETED`: Subscription is ended as deleted (no longer active). This status applies when subscription information is kept (i.e. subscription workflow is no longer active but its meta-information is kept). enum: - - ACTIVATION_REQUESTED - - ACTIVE - - EXPIRED - - INACTIVE - - DELETED - discriminator: - propertyName: protocol - mapping: - HTTP: '#/components/schemas/HTTPSubscriptionResponse' - MQTT3: '#/components/schemas/MQTTSubscriptionResponse' - MQTT5: '#/components/schemas/MQTTSubscriptionResponse' - AMQP: '#/components/schemas/AMQPSubscriptionResponse' - NATS: '#/components/schemas/NATSSubscriptionResponse' - KAFKA: '#/components/schemas/ApacheKafkaSubscriptionResponse' + - "1.0" + description: Version of the CloudEvents specification (must be 1.0) + datacontenttype: + type: string + enum: + - application/json + description: Media-type of the event payload encoding (must be application/json for CAMARA APIs) + time: + type: string + format: date-time + description: Timestamp of when the occurrence happened (RFC 3339) + example: "2023-01-17T13:18:23.682Z" + data: + type: object + description: Event notification details payload + properties: + appInstanceId: + type: string + description: Application instance identifier (for instance-based events) + appDeploymentId: + type: string + description: Application deployment identifier (for deployment-based events) + status: + type: string + description: Current status of the application instance or deployment + terminationReason: + type: string + enum: + - SUBSCRIPTION_EXPIRED + - MAX_EVENTS_REACHED + - ACCESS_TOKEN_EXPIRED + description: Reason for subscription termination (for subscription-ended events) + + SubscriptionEventType: + type: string + description: | + Event-type that could be subscribed through this subscription. Several event-type could be defined. + enum: + - org.camaraproject.edge-application-management.v0.app-instance-status-change + - org.camaraproject.edge-application-management.v0.app-deployment-status-change + - org.camaraproject.edge-application-management.v0.subscription-ended SubscriptionRequest: - description: The request for creating a event-type event subscription + description: The request for creating an event-type event subscription (implicit subscription, HTTP only) type: object required: - sink - - protocol - - config - types + - config properties: - protocol: - $ref: "#/components/schemas/Protocol" sink: type: string format: uri @@ -1206,15 +1183,6 @@ components: $ref: "#/components/schemas/SubscriptionEventType" config: $ref: "#/components/schemas/SubscriptionConfig" - discriminator: - propertyName: protocol - mapping: - HTTP: "#/components/schemas/HTTPSubscriptionRequest" - MQTT3: "#/components/schemas/MQTTSubscriptionRequest" - MQTT5: "#/components/schemas/MQTTSubscriptionRequest" - AMQP: "#/components/schemas/AMQPSubscriptionRequest" - NATS: "#/components/schemas/NATSSubscriptionRequest" - KAFKA: "#/components/schemas/ApacheKafkaSubscriptionRequest" SubscriptionConfig: description: | @@ -1233,199 +1201,44 @@ components: type: string format: date-time example: 2023-01-17T13:18:23.682Z - description: The subscription expiration time (in date-time format) requested by the API consumer. It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. Up to API project decision to keep it. + description: The subscription expiration time (in date-time format) requested by the API consumer. It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. subscriptionMaxEvents: type: integer - description: Identifies the maximum number of event reports to be generated (>=1) requested by the API consumer - Once this number is reached, the subscription ends. Up to API project decision to keep it. + description: Identifies the maximum number of event reports to be generated (>=1) requested by the API consumer - Once this number is reached, the subscription ends. minimum: 1 example: 5 initialEvent: type: boolean description: | Set to `true` by API consumer if consumer wants to get an event as soon as the subscription is created and current situation reflects event request. - Example: Consumer request Roaming event. If consumer sets initialEvent to true and device is in roaming situation, an event is triggered - Up to API project decision to keep it. - - SubscriptionEventType: - type: string - description: | - event-type that could be subscribed through this subscription. Several event-type could be defined. - enum: - - org.camaraproject.Edge-Application-Management.v0.onAppInstanceStatusChange - - org.camaraproject.Edge-Application-Management.v0.onDeploymentStatusChange + Example: If initialEvent is set to true and application is in a specific status, an event is triggered. SinkCredential: description: A sink credential provides authentication or authorization information necessary to enable delivery of events to a target. type: object - properties: - credentialType: - type: string - enum: - - PLAIN - - ACCESSTOKEN - - REFRESHTOKEN - description: | - The type of the credential. - Note: Type of the credential - MUST be set to ACCESSTOKEN for now - discriminator: - propertyName: credentialType - mapping: - PLAIN: "#/components/schemas/PlainCredential" - ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" - REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" required: - credentialType - - HTTPSubscriptionRequest: - allOf: - - $ref: "#/components/schemas/SubscriptionRequest" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/HTTPSettings" - - HTTPSubscriptionResponse: - allOf: - - $ref: "#/components/schemas/Subscription" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/HTTPSettings" - - HTTPSettings: - type: object + - accessToken + - accessTokenExpiresUtc + - accessTokenType properties: - headers: - type: object - description: |- - A set of key/value pairs that is copied into the HTTP request as custom headers. - NOTE: Use/Applicability of this concept has not been discussed in Commonalities under the scope of Meta Release v0.4. When required by an API project as an option to meet a UC/Requirement, please generate an issue for Commonalities discussion about it. - additionalProperties: - type: string - method: + credentialType: type: string - description: The HTTP method to use for sending the message. enum: - - POST - - MQTTSubscriptionRequest: - allOf: - - $ref: "#/components/schemas/SubscriptionRequest" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/MQTTSettings" - - MQTTSubscriptionResponse: - allOf: - - $ref: "#/components/schemas/Subscription" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/MQTTSettings" - - MQTTSettings: - type: object - properties: - topicName: - type: string - qos: - type: integer - format: int32 - retain: - type: boolean - expiry: - type: integer - format: int32 - userProperties: - type: object - required: - - topicName - - AMQPSubscriptionRequest: - allOf: - - $ref: "#/components/schemas/SubscriptionRequest" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/AMQPSettings" - - AMQPSubscriptionResponse: - allOf: - - $ref: "#/components/schemas/Subscription" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/AMQPSettings" - - AMQPSettings: - type: object - properties: - address: - type: string - linkName: - type: string - senderSettlementMode: - type: string - enum: ["settled", "unsettled"] - linkProperties: - type: object - additionalProperties: - type: string - - ApacheKafkaSubscriptionRequest: - allOf: - - $ref: "#/components/schemas/SubscriptionRequest" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/ApacheKafkaSettings" - - ApacheKafkaSubscriptionResponse: - allOf: - - $ref: "#/components/schemas/Subscription" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/ApacheKafkaSettings" - - ApacheKafkaSettings: - type: object - properties: - topicName: - type: string - partitionKeyExtractor: + - ACCESSTOKEN + description: Type of the credential - MUST be set to ACCESSTOKEN for now + accessToken: type: string - clientId: + description: Access Token granting access to the POST operation to create notification + accessTokenExpiresUtc: type: string - ackMode: - type: integer - required: - - topicName - - NATSSubscriptionRequest: - allOf: - - $ref: "#/components/schemas/SubscriptionRequest" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/NATSSettings" - - NATSSubscriptionResponse: - allOf: - - $ref: "#/components/schemas/Subscription" - - type: object - properties: - protocolSettings: - $ref: "#/components/schemas/NATSSettings" - - NATSSettings: - type: object - properties: - subject: + format: date-time + description: An absolute UTC instant at which the access token shall be considered expired. Token expiration SHOULD occur after the expiration of the application instance or deployment, allowing the client to be notified of any changes during its existence. If the token expires while the resource is still active, the client will stop receiving notifications. + accessTokenType: type: string - required: - - subject + enum: + - bearer + description: Type of access token - MUST be set to bearer for now AccessEndpoint: type: object From a6ec5ea35cb5a5e941d0f8f12d80ba4930f9ac88 Mon Sep 17 00:00:00 2001 From: Travis Hepworth Date: Wed, 10 Dec 2025 09:49:45 -0700 Subject: [PATCH 8/8] Update cloudEvent --- .../edge-application-management.yaml | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/code/API_definitions/edge-application-management.yaml b/code/API_definitions/edge-application-management.yaml index 1ec6e7f3..63b225b1 100644 --- a/code/API_definitions/edge-application-management.yaml +++ b/code/API_definitions/edge-application-management.yaml @@ -1068,7 +1068,9 @@ components: content: application/cloudevents+json: schema: - $ref: '#/components/schemas/CloudEvent' + type: array + items: + $ref: '#/components/schemas/CloudEvent' responses: '204': description: Successful notification - No Content @@ -1096,6 +1098,7 @@ components: - type - specversion - time + - accessPoints properties: id: type: string @@ -1134,8 +1137,8 @@ components: type: string description: Application deployment identifier (for deployment-based events) status: - type: string - description: Current status of the application instance or deployment + $ref: '#/components/schemas/CloudEventStatus' + description: New status of the application instance or deployment terminationReason: type: string enum: @@ -1143,6 +1146,18 @@ components: - MAX_EVENTS_REACHED - ACCESS_TOKEN_EXPIRED description: Reason for subscription termination (for subscription-ended events) + accessPoints: + $ref: '#/components/schemas/AccessEndpoint' + + CloudEventStatus: + description: | + Status of the application instance or deployment + enum: + - DEPLOYING + - RUNNING + - FAILED + - TERMINATING + - TERMINATED SubscriptionEventType: type: string @@ -1158,8 +1173,7 @@ components: type: object required: - sink - - types - - config + - sinkCredential properties: sink: type: string