Support pull messaging model
##Status
-
Proposed -
Under review -
Approved -
Retired
Context and scope
Currently Notification service in OSDU supports a push messaging model where the server pro-actively sends messages to subscribing clients but not a pull model where client's are in control of retrieving messages from the server.
This ADR proposes to enable clients to choose whether to pull messages or receive them via push from the notification service when registering for messages.
The registration service could be extended to support an extra API to allow clients to register for pull messages. The user then chooses whether to use this API or the existing register API for push messages
/pullsubscription:
post:
tags:
- Subscription
summary: Create a subscription
description: "Create a subscription. Required roles: 'users.datalake.editors' or
'users.datalake.admins'"
operationId: Create a subscription
parameters:
- $ref: "#/components/parameters/data-partition-id"
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/pullSubscription"
responses:
"201":
description: Created
content:
application/json:
schema:
$ref: "#/components/schemas/pullSubscriptionCreateResult"
components:
parameters:
pullSubscription:
type: object
required:
- schema
properties:
name:
type: string
pattern: ^[A-Za-z0-9- ]{2,50}
example: test-subscription
description:
type: string
pattern: ^[A-Za-z0-9. ]{0,255}
example: test description
topic:
type: string
example: data-changed-v1
pullSubscriptionCreatedResult:
type: object
required:
- schema
properties:
id:
type: string
example: dGVzdC1uYW1l
name:
type: string
pattern: ^[A-Za-z0-9- ]{2,50}
example: test-subscription
description:
type: string
pattern: ^[A-Za-z0-9. ]{0,255}
example: test description
topic:
type: string
example: data-changed-v1
createdBy:
type: string
example: test@myapp.com
createdOnEpoch:
$ref: "#/components/schemas/createdOnEpoch"
The response of the API then tells the client their unique subscription ID. The client uses this to pull messages. The notification service would need to be extended to have an exposed API which clients would call with their subscription ID.
/pullsubscription/{id}:
get:
tags:
- Subscription
summary: Get messages for subscription
description: "Gets an array of messages for the given subscription id if any. Required roles: 'users.datalake.editors' or
'users.datalake.admins'"
operationId: Create a subscription
parameters:
- name: id
in: path
required: true
schema:
type: string
pattern: ^[A-Za-z0-9-]{2,128}
- $ref: "#/components/parameters/data-partition-id"
responses:
"200":
description: OK
content:
application/json:
schema:
type: array
The GET and DELETE subscription registration API would work with an ID that was either from a pull or push subscription
Trade-offs
The main benefit of pull over push is in scenarios where the client want's to control the request rate at which it receives messages from the server. This may be in scenarios where the server pushes to aggressively for the client to handle causing potential, errors or even crashes on the client side. Also if the client can retrieve messages at a higher rate than the server can pushes then in a pull model the client can potentially increase the rate at which it can retrieve and process messages.
Another potential benefit is with security. In the push model the client must expose a public endpoint for the server to push messages to. In OSDU we secure this with a given client credential to generate a jwt token or secret to generate a HMAC signature on the HTTPS requests pushed. This forces the client to expose a public endpoint and have a secret rotation strategy in place. This is negated in the pull model where the client users the common authorization scheme when calling any of the OSDU APIs to pull messages putting no extra burden on the client to maintain a secure system. We also ask clients to expose an extra endpoint to test registrations for notifications putting more burden on the client to setup maintain and secure.