Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update DG with use of callbacks & cloudEvents #56

Merged
merged 22 commits into from
Sep 29, 2023
Merged
Changes from 18 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ebf03be
Update API-design-guidelines for Notification
bigludo7 Sep 1, 2023
d727cdd
Update API-design-guidelines.md
bigludo7 Sep 1, 2023
4646e9f
Update documentation/API-design-guidelines.md
bigludo7 Sep 5, 2023
4c304f7
Update documentation/API-design-guidelines.md
bigludo7 Sep 5, 2023
df1e263
Update documentation/API-design-guidelines.md
bigludo7 Sep 5, 2023
6874b7c
Update API-design-guidelines.md
bigludo7 Sep 7, 2023
346c141
Update API-design-guidelines.md
bigludo7 Sep 7, 2023
ec101d5
Update documentation/API-design-guidelines.md
bigludo7 Sep 14, 2023
83f1aa0
Update documentation/API-design-guidelines.md
bigludo7 Sep 14, 2023
e76bfea
Update documentation/API-design-guidelines.md
bigludo7 Sep 14, 2023
a8b23ce
Update documentation/API-design-guidelines.md
bigludo7 Sep 14, 2023
ed266a3
Update API-design-guidelines.md
bigludo7 Sep 14, 2023
089d267
Update API-design-guidelines.md
bigludo7 Sep 17, 2023
0169c8f
Update API-design-guidelines.md
bigludo7 Sep 17, 2023
f2df79c
Shifted event type to kebab-case
bigludo7 Sep 19, 2023
8e0071c
Update documentation/API-design-guidelines.md
bigludo7 Sep 21, 2023
592f8a0
Update documentation/API-design-guidelines.md
bigludo7 Sep 21, 2023
73f57b7
Update API-design-guidelines.md
bigludo7 Sep 21, 2023
4008d5f
Update API-design-guidelines.md
bigludo7 Sep 21, 2023
cc6b1a8
Update documentation/API-design-guidelines.md
bigludo7 Sep 25, 2023
4050b6d
Update API-design-guidelines.md
bigludo7 Sep 26, 2023
9cc3448
Update API-design-guidelines.md
bigludo7 Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 100 additions & 58 deletions documentation/API-design-guidelines.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small format adjustments would be appropriate in line:
216 - 218 : change "- - " to "--" or " -"
and typos in lines
70 - "comunicate"
120 - "analyse"
211 - "terminolgy"
217 - "mulitple"
288 - "senstive"
324 - "Unathourized"
405 - "recommendended"
412 - "Referer"
592 - "aAdded"
634 - "ellaborate" and "exisiing" and "errores"
709 - "returnss"
720 - "ascp" - i only know asc for sorting
1010 - "erros"
1050 - "desctiption"
1186 - "Anycase"
1324 - "explicited" (explicitly ?)
1335 - "accross" and "exemple"
1354 - "subscrition"
Thx

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This document captures guidelines for the API design in CAMARA project. These gu
- [2.5 Reduce telco-specific terminology in API definitions](#25-reduce-telco-specific-terminology-in-api-definitions)
- [3. API Definition](#3-api-definition)
- [3.1 API REST](#31-api-rest)
- [**POST or GET for transferring sensitive or complex data**](#post-or-get-for-transferring-sensitive-or-complex-data)
- [3.2 HTTP Response Codes](#32-http-response-codes)
- [3.3 Query Parameters Use](#33-query-parameters-use)
- [3.4 Path Parameters Use](#34-path-parameters-use)
Expand Down Expand Up @@ -43,10 +44,23 @@ This document captures guidelines for the API design in CAMARA project. These gu
- [11.3 Request Parameters](#113-request-parameters)
- [11.4 Response Structure](#114-response-structure)
- [11.5 Data Definitions](#115-data-definitions)
- [11.5.1 Usage of discriminator](#1151-usage-of-discriminator)
- [11.6 OAuth Definition](#116-oauth-definition)
- [12. Subscription, Notification \& Event](#12-subscription-notification--event)
- [12.1 Subscription](#121-subscription)
- [Instance-based (implicit) subscription](#instance-based-implicit-subscription)
- [Instance-based (implicit) subscription example](#instance-based-implicit-subscription-example)
- [Resource-based (explicit) subscription](#resource-based-explicit-subscription)
- [Error definition for resource-based (explicit) subscription](#error-definition-for-resource-based-explicit-subscription)
- [Termination for resource-based (explicit) subscription](#termination-for-resource-based-explicit-subscription)
- [Resource-based (explicit) example](#resource-based-explicit-example)
- [12.2 Event notification](#122-event-notification)
- [Event notification definition](#event-notification-definition)
- [Error definition for event notification](#error-definition-for-event-notification)
- [Correlation Management](#correlation-management)
- [Security Considerations](#security-considerations)
- [Abuse Protection](#abuse-protection)
- [Notification examples](#notification-examples)


## Common Vocabulary and Acronyms
Expand Down Expand Up @@ -1138,23 +1152,23 @@ Managed event types are explicitly defined in CAMARA API OAS.
### 12.1 Subscription

We distinguish 2 types of subscriptions:
- Instance-based subscription (indirect creation)
- Resource-based subscription (direct creation)
- Instance-based subscription (implicit creation)
- Resource-based subscription (explicit creation)

**Instance-based subscription**
#### Instance-based (implicit) subscription
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are Instance-based subscriptions (explicit) and Resource-based subscriptions (implicit) outside the scope of our project or scenario doesn't exist?

Copy link
Collaborator Author

@bigludo7 bigludo7 Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sachinvodafone Sorry i did not understand your question - may I ask you to elaborate? Thanks

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @bigludo7 , Just to clarify, I understand that an 'instance-based' subscription is associated with a specific event or instance of resource creation, whereas an 'implicit subscription' suggests that the subscription is established indirectly or automatically due to some other action or event.

Similarly, we also have two other distinct subscription types: 'resource-based' and 'explicit' subscriptions. In this context, we could potentially have four combinations:

  • 'Instance-based subscriptions (explicit),'
  • 'Instance-based subscriptions (implicit),'
  • 'Resource-based subscriptions (explicit),'
  • and 'Resource-based subscriptions (implicit).'

However, our documentation currently only covers two of these combinations:

  • 'Instance-based subscription (implicit creation)'
  • 'Resource-based subscription (explicit creation)'

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sachinvodafone Got it ! thanks for the clarification
Instance-based and implicit are same thing, and resource-based and explicit are same; As suggested by @murthygorty I have introduced this vocabulary to explain the 2 patterns. I feel sorry it creates confusion. I could update it in next release if other people thinks that it adds more confusion than clarification.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sachinvodafone : If adding the above said description is not a blocking issue for you, could you please approve this PR as you were active in this review and kindly open a new issue for improving this documentation? Would that work for you?


An instance-based subscription is a subscription indirectly created, additionally to another resource creation. For example for a Payment request (in Carrier Billing API), in the `POST/payments`, the API consumer could request to get event notification about **this** Payment request processing update. The subscription is not an autonomous entity and its lifecycle is linked to the managed entity (the Payment resource in this case). The subscription terminates with the managed entity.

Providing this capability is optional for any CAMARA API depending on UC requirements.

If this capability is present in CAMARA API, following attributes **must** be used in the POST request, within a `webhook` object, for the managed entity:
If this capability is present in CAMARA API, `webhook` object attribute **must** be used in the POST request. The `webhook` object contains following attributes :

| attribute name | type | attribute description | cardinality |
| ----- | ----- | ----- | ----- |
| notificationUrl | string | https callback address where the notification must be POST-ed | mandatory |
| notificationAuthToken | string | OAuth2 token to be used by the callback API endpoint. It MUST be indicated within HTTP Authorization header e.g. Authorization: Bearer $notificationAuthToken | optional |

_example:_
##### Instance-based (implicit) subscription example

```json
{
Expand All @@ -1171,9 +1185,10 @@ Recommended format conventions regarding ```notificationAuthToken``` attribute,
- It has to be restricted in length, a string between [20-256] characters.
- It is HIGHLY recommended to have random-based pattern (e.g. UUIDv4 or another one. Anycase it is an implementation topic not design one)

**Resource-based subscription**

A resource-based subscription is a event subscription managed as a resource. An API endpoint is provided to request subscription creation. As this event subscription is managed as an API resource, it is identified and operations to search, retrieve and delete it must be provided.
#### Resource-based (explicit) subscription

A resource-based subscription is a event subscription managed as a resource. This subscription is explicit. An API endpoint is provided to request subscription creation. As this event subscription is managed as an API resource, it is identified and operations to search, retrieve and delete it must be provided.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A resource-based subscription is a event subscription managed as a resource. This subscription is explicit. An API endpoint is provided to request subscription creation. As this event subscription is managed as an API resource, it is identified and operations to search, retrieve and delete it must be provided.
A resource-based subscription is an event subscription managed as a resource. This subscription is explicit. An API endpoint is provided to request subscription creation. As this event subscription is managed as an API resource, it is identified and operations to search, retrieve and delete it must be provided.


Note: It is perfectly valid for a CAMARA API to have several event types managed. The subscription endpoint will be unique but 'eventType' attribute is used to distinguish distinct events subscribed.

Expand Down Expand Up @@ -1211,14 +1226,14 @@ The `webhook` object definition:
| notificationUrl | string | https callback address where the event notification must be POST-ed | mandatory |
| notificationAuthToken | string | OAuth2 token to be used by the callback API endpoint. It MUST be indicated within HTTP Authorization header e.g. Authorization: Bearer $notificationAuthToken | optional |

The `subscriptionDetail` must have at least an eventType attribute:
The `subscriptionDetail` must have at least a type attribute:

| name | type | attribute description | cardinality |
| ----- | ----- | ----- | ----- |
| eventType | string | Type of event subscribed. This attribute must be present in the `POST` request. It is open to API working group to allow providing a list of event type based on specific UC. `eventType` must follow UPPER_SNAKE_CASE format. | mandatory |
| type | string | Type of event subscribed. This attribute **must** be present in the `POST` request. It is required to provide a enum for these attribute. `type` must follow following format: `org.camaraproject.<api-name>.<event-name>` like `org.camaraproject.device-status.roaming-off`| mandatory |


_Error definition for subscription_
##### Error definition for resource-based (explicit) subscription

Error definition described in this guideline applies for subscriptions.

Expand All @@ -1228,7 +1243,7 @@ Following Error code must be present:
* for `GET/{subscriptionId}`: 400, 401, 403, 404, 500, 503
* for `DELETE`: 400, 401, 403, 404, 500, 503
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DELETE /{subscriptionId}


_Termination for resource-based subscription_
##### Termination for resource-based (explicit) subscription

3 scenarios subscription termination are possible (business conditions may apply):

Expand All @@ -1243,7 +1258,7 @@ _Termination rules regarding subscriptionExpireTime usage_
* When the `subscriptionExpireTime` is not provided, client side has to trigger a `DELETE` operation to terminate it.


_Subscription example_
##### Resource-based (explicit) example
In this example, we illustrate a request for a device roaming status event subscription. Requester did not provide anticipated expiration time for the subscription. In the response, server accepts this request and sets an event subscription end one year later. This is an illustration and each implementation is free to provide - or not - a subscription planned expiration date.

Request:
Expand All @@ -1266,7 +1281,7 @@ curl -X 'POST' \
"ipv4Addr": "192.168.0.1"
},
"uePort": 5060,
"eventType": "ROAMING_STATUS"
"type": "org.camaraproject.device-status.roaming-status"
}
}
```
Expand All @@ -1287,61 +1302,86 @@ response:
"ipv4Addr": "192.168.0.1"
},
"uePort": 5060,
"eventType": "ROAMING_STATUS"
"type": "org.camaraproject.device-status.roaming-status"
},
"eventSubscriptionId": "456g899g",
"startsAt": "2023-03-17T16:02:41.314Z",
"expiresAt" : "2024-03-17T00:00:00.000Z"
}
```

Note: If the API provides both patterns (indirect and resource-based), and the API customer requests both (instance based + subscription), the 2 requests should be handled independently & autonomously. Depending on server implementation, it is acceptable, when the event occurrs, that one or two notifications are sent to listener.
Note: If the API provides both patterns (indirect and resource-based), and the API customer requests both (instance based + subscription), the 2 requests should be handled independently & autonomously. Depending on server implementation, it is acceptable, when the event occurs, that one or two notifications are sent to listener.


### 12.2 Event notification

#### Event notification definition

The event notification endpoint is used by the API server to notify the API consumer that an event occured.

Note: The notification is the message posted on listener side. We describe the notification message in the CAMARA OAS but it could confusing because this endpoint should be implemented on the business API consumer side. This notice should be explicited mentioned in all CAMARA API documentation featuring notifications.
CAMARA event notification leverages **[CloudEvents](https://cloudevents.io/)** as it is a vendor-neutral specification for defining the format of event data. A generic neutral CloudEvent notification swagger is available in commonalities/artifact directory (notification-as-cloud-event.yaml).

Note: The notification is the message posted on listener side. We describe the notification(s) in the CAMARA API using the `callbacks`. From API consumer it could confusing because this endpoint must be implemented on the business API consumer side. This notice should be explicited mentioned in all CAMARA API documentation featuring notifications.

Only Operation POST is provided for `eventNotifications` and the expected response code is `204`.
Only Operation POST is provided for `eventNotifications` and the expected response code is `204`.
The url for this `POST` operation must be specified in the swagger as `{$request.body#/webhook/notificationUrl}`.

For consistence among CAMARA APIs the uniform `eventNotifications` model must be used:
For consistency across CAMARA APIs the uniform CloudEvents model must be used with following rules:

| name | type | attribute description | cardinality |
| ----- | ----- | ----- | ----- |
| eventSubscriptionId | string | subscription identifier - could be valued for Resource-based subscription | optional |
| event | object | event structure - see next table | mandatory |
| id | string | identifier of this event, that must be unique in the source context. | mandatory |
| source | string - URI | identifies the context in which an event happened in the specific Provider Implementation. Often this will include information such as the type of the event source, the organization publishing the event or the process that produced the event. The exact syntax and semantics behind the data encoded in the URI is defined by the event producer. | mandatory |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to CloudEvents specs

An absolute URI is RECOMMENDED

Should we provide more specific recommendations on syntax of source attribute?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have the same feeling, a suggestion aligned with the model proposed for type:

identifies the context in which an event happened in the specific Provider Implementation. Often this will include information such as the type of the event source, the organization publishing the event or the process that produced the event. The exact syntax and semantics behind the data encoded in the URI is defined by the event producer. For consistency accross CAMARA APIs we mandate following pattern: org.camara.api.name of the API (for example org.camara.api.device-status)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I have the doubt whether we should "change" "camara" wording by "$ob_name" as the source of the event is a Telco Operator. This would also apply for type

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please discard my previous comment regarding the format, as it would not be compliant to CloudEvents specs.

As commented by Rafał, the recommendation is an absolute URI. If we are ok to go for this recommendation at least it needs to be indicated in the guidelines for any Operator to follow that format.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to CloudEvents specs

An absolute URI is RECOMMENDED

Should we provide more specific recommendations on syntax of source attribute?

Yes would be good to provide some recommendation or at least refer to examples provided here https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1

| type | string | a value describing the type of event related to the originating occurrence. For consistency accross API we mandate following pattern: `org.camaraproject.<api-name>.<event-name>` (for exemple org.camaraproject.device-status.roaming-status ) | mandatory |
| specversion | string | version of the specification to which this event conforms - must be "1.0" | mandatory |
| datacontenttype | string | media-type that describes the event payload encoding, must be `application/json` for CAMARA APIs| optional |
| subject | string | describes the subject of the event - Not used in CAMARA notification. | optional |
| time | string datetime| Timestamp of when the occurrence happened. If the time of the occurrence cannot be determined then this attribute MAY be set to some other time (such as the current time) by the CloudEvents producer, however all producers for the same `source` MUST be consistent in this respect. In other words, either they all use the actual time of the occurrence or they all use the same algorithm to determine the value used. (must adhere on CAMARA datetime recommendation based on RFC 3339) | mandatory (*) |
| data | object| event notification details payload described in each CAMARA API and referenced by its `type` | optional |

Following table defines event attribute object structure:
(*) Note: Attribute `time` is tagged as optional in CloudEvents specification but from CAMARA perspective we mandate to value this attributes.

`data` structure is dependant to each API:

| name | type | attribute description | cardinality |
| ----- | ----- | ----- | ----- |
| eventId | string - uuid | Identifier of the event from the server where the event was reported | optional |
| eventType | string | Type of event as defined in each CAMARA API. The event type are written in UPPER_SNAKE_CASE| mandatory |
| eventTime | string - datetime | Date time when the event occurred | mandatory |
| eventDetail | object | Event details structure depending on the eventType | mandatory |
| eventSubscriptionId | string | The event subscription identifier - must be valued for Resource-based subscription | optional |
| ... | ... | Specific attribute(s) related to the notification event | ... |


Note: For operational and troubleshooting purposes it is relevant to accommodate use of `X-Correlator` header attribute. API listener implementations have to be ready to support and receive this data.

Specific eventType "SUBSCRIPTION_ENDS" is defined to inform listener about subscrition termination. It is used when the subscription expire time (required by the requester) has been reached or if the API server has to stop sending notification prematurely. For this specific event, the `eventDetail` must feature `terminationReason` attribute.
Specific event notification type "subscription-ends" is defined to inform listener about subscrition termination. It is used when the subscription expire time (required by the requester) has been reached or if the API server has to stop sending notification prematurely. For this specific event, the `data` must feature `terminationReason` attribute.

_Error definition for event notification_
#### Error definition for event notification

Error definition are described in this guideline applies for event notification.

Following Error code must be present:
* for `POST`: 400, 401, 403, 500, 503

_Managing correlation between resource-based event souscription and event notification_
#### Correlation Management
To manage correlation between the subscription management and the event notification (as these are 2 distinct operations):
- use `eventSubscriptionId` attribute (in body) - this identifier is provided in event subscription and could be valued in each event notification.
- use `eventSubscriptionId` attribute (in `data` structure in the body) - this identifier is provided in event subscription and could be valued in each event notification.

Note: There is no normative enforcement to use any of these patterns and they could be used on agreement between API consumer & provider.

#### Security Considerations

As notification may carry sensitive information, privacy and security constraints has to be considered. CloudEvents specification provides some guidance there: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#privacy-and-security

#### Abuse Protection

Any system that allows registration of and delivery of notifications to arbitrary HTTP endpoints can potentially be abused such that someone maliciously or inadvertently registers the address of a system that does not expect such requests and for which the registering party is not authorized to perform such a registration.

In order to protect the sender, CloudEvents specification provides some guidance there: https://github.com/cloudevents/spec/blob/main/cloudevents/http-webhook.md#4-abuse-protection

bigludo7 marked this conversation as resolved.
Show resolved Hide resolved
note: There is no normative enforcement to use any of these patterns and they could be used on agreement between API consumer & provider.
Event Producers shall choose based on their internal security guidelines to implement measures based on the above guidance to ensure abuse protection. For e.g. An event producer might ask the subscriber to pre-register the notification URL at the time of app onboarding. If this registered notification URL doesn't match later with the notification URL in the request, the event producer can choose to reject the request with the relevant error code.

_Examples_

Example for Roaming status - Request:
#### Notification examples

Example for Roaming status event notification - Request:

```
curl -X 'POST' \
Expand All @@ -1353,20 +1393,21 @@ curl -X 'POST' \
```
```json
{
"eventSubscriptionId": "456g899g",
"event": {
"eventType": "ROAMING_STATUS",
"eventTime": "2023-01-19T13:18:23.682Z",
"eventDetail": {
"ueId": {
"ipv4Addr": "192.168.0.1"
},
"uePort": 5060,
"roaming": true,
"countryCode": 208,
"countryName": "FR"
}
}
"id": 123654,
"source": "https://notificationSendServer12.supertelco.com",
"type": "org.camaraproject.device-status.roaming-status",
"specversion": "1.0",
"datacontenttype": "application/json",
"data": {
"eventSubscriptionId": "456g899g",
"device": {
"phoneNumber": 123456789
},
"roaming": true,
"countryCode": 208,
"countryName": "FR"
},
"time": "2023-01-17T13:18:23.682Z"
}
```

Expand All @@ -1389,18 +1430,19 @@ curl -X 'POST' \
```
```json
{
"eventSubscriptionId": "456g899g",
"event": {
"eventType": "SUBSCRIPTION_ENDS",
"eventTime": "2023-01-24T13:18:23.682Z",
"eventDetail": {
"ueId": {
"ipv4Addr": "192.168.0.1"
},
"uePort": 5060,
"terminationReason": "Service terminates for lack of consent"
}
}
"id": 123658,
"source": "https://notificationSendServer12.supertelco.com",
"type": "org.camara.api.device-status.subcription-ends",
"specversion": "1.0",
"datacontenttype": "application/json",
"data": {
"eventSubscriptionId": "456g899g",
"device": {
"phoneNumber": 123456789
},
"terminationReason": "SUBSCRIPTION_EXPIRED"
},
"time": "2023-01-19T13:18:23.682Z"
}
```
bigludo7 marked this conversation as resolved.
Show resolved Hide resolved

Expand Down