Module websub
ballerina/websub Ballerina library
Overview
This module provides APIs for a WebSub Subscriber Service, an implementation of the WebSub Subscriber role that discovers a resource's hub and topic, subscribes to updates, and accepts content distribution requests.
Key Features
- WebSub Subscriber Service for subscribing to and receiving content updates
- Automatic hub and topic URL discovery for a given resource URL
Basic flow with WebSub
-
The subscriber discovers (from the publisher) the topic it needs to subscribe to and the hub(s) that deliver notifications on the updates of the topic.
-
The subscriber sends a subscription request to one or more discovered hub(s) specifying the discovered topic along with the other subscription parameters such as:
- The callback URL to which the content is expected to be delivered.
- (Optional) The lease period (in seconds) the subscriber wants the subscription to stay active.
- (Optional) A secret to use for the authenticated content distribution.
-
The hub sends an intent verification request to the specified callback URL. If the response indicates the verification (by echoing a challenge specified in the request) by the subscriber, the subscription is added for the topic at the hub.
-
The publisher notifies the hub of the updates to the topic and the content to deliver is identified.
-
The hub delivers the identified content to the subscribers of the topic.
Subscribe to a hub
- The WebSub Subscriber provides the mechanism to subscribe in a
hubto a giventopic URL.
@websub:SubscriberServiceConfig { target: ["<HUB_URL>", "<TOPIC_URL>"], leaseSeconds: 36000 } service /subscriber on new websub:Listener(9090) { remote function onSubscriptionValidationDenied(websub:SubscriptionDeniedError msg) returns websub:Acknowledgement? { // implement subscription validation denied logic here return websub:ACKNOWLEDGEMENT; } remote function onSubscriptionVerification(websub:SubscriptionVerification msg) returns websub:SubscriptionVerificationSuccess|websub:SubscriptionVerificationError { // implement subscription intent verification logic here return websub:SUBSCRIPTION_VERIFICATION_SUCCESS; } remote function onUnsubscriptionVerification(websub:UnsubscriptionVerification msg) returns websub:UnsubscriptionVerificationSuccess|websub:UnsubscriptionVerificationError { // implement unsubscription intent verification logic here return websub:UNSUBSCRIPTION_VERIFICATION_SUCCESS; } remote function onEventNotification(websub:ContentDistributionMessage event) returns websub:Acknowledgement|websub:SubscriptionDeletedError? { // implement on event notification logic here return websub:ACKNOWLEDGEMENT; } }
Resource discovery
- The WebSub Subscriber also provides the mechanism to discover the
hubandtopic URLresources dynamically via the providedresource URLand initiates the subscription.
@websub:SubscriberServiceConfig { target: "RESOURCE_URL", leaseSeconds: 36000 } service /subscriber on new websub:Listener(9090) { remote function onEventNotification(websub:ContentDistributionMessage event) returns websub:Acknowledgement|websub:SubscriptionDeletedError? { // implement on event notification logic here return websub:ACKNOWLEDGEMENT; } // other remote methods are optional to be implemented }
Dynamic URI generation
- The service path for a WebSub Subscriber is optional. The WebSub Subscriber service has the capability to generate the service path dynamically.
@websub:SubscriberServiceConfig { target: "RESOURCE_URL", leaseSeconds: 36000 } service on new websub:Listener(9090) { remote function onEventNotification(websub:ContentDistributionMessage event) returns websub:Acknowledgement|websub:SubscriptionDeletedError? { // implement on event notification logic here return websub:ACKNOWLEDGEMENT; } // other remote methods are optional to be implemented }
Run a websub:SubscriberService locally
- ngrok is a TCP Tunneling software, which is used to expose services running locally in the public network.
- If you want to run the subscriber service in your local machine, you could use ngrok to expose it to the public network.
- First, download and install ngrok.
- Run the following command to expose the local port
9090to the public network viaHTTPS. For information, see the ngrok documentation).
ngrok http -bind-tls=true 9090
- Extract the public URL provided by ngrok and provide it as the callback URL for the subscriber service.
@websub:SubscriberServiceConfig { target: "RESOURCE_URL", leaseSeconds: 36000, callback: "<NGROK_PUBLIC_URL>", appendServicePath: true } service on new websub:Listener(9090) { remote function onEventNotification(websub:ContentDistributionMessage event) returns websub:Acknowledgement|websub:SubscriptionDeletedError? { // implement on event notification logic here return websub:ACKNOWLEDGEMENT; } // other remote methods are optional to be implemented }
Unsubscribe from the hub
- The WebSub Subscriber has the capability to initiate unsubscription flow on Subscriber termination.
websub:ListenerConfiguration listenerConfigs = { gracefulShutdownPeriod: 15 }; @websub:SubscriberServiceConfig { target: ["https://sample.hub.com", "https://sample.topic1.com"], leaseSeconds: 36000, // By default this is set to `false`, hence subscriber on default mode would not initiate unsubscription flow unsubscribeOnShutdown: true } service /subscriber on new websub:Listener(9090, listenerConfigs) { isolated remote function onEventNotification(websub:ContentDistributionMessage event) returns websub:Acknowledgement { // implement logic here return websub:ACKNOWLEDGEMENT; } // other remote methods are optional to be implemented }
Return errors from remote methods
- Remote functions in
websub:SubscriberServicecan returnerrortype.
@websub:SubscriberServiceConfig { target: "RESOURCE_URL", leaseSeconds: 36000, callback: "<NGROK_PUBLIC_URL>", appendServicePath: true } service on new websub:Listener(9090) { remote function onEventNotification(websub:ContentDistributionMessage event) returns websub:Acknowledgement|websub:SubscriptionDeletedError|error? { boolean isValidRequest = check validateRequest(event); if isValidRequest { // implement on event notification logic here return websub:ACKNOWLEDGEMENT; } } // other remote methods are optional to be implemented } function validateRequest(websub:ContentDistributionMessage event) returns boolean|error { // validation logic }
- For each remote method
errorreturn has a different meaning. Following table depicts the meaning inferred fromerrorreturned from all available remote methods.
| Method | Interpreted meaning for Error Return |
|---|---|
| onSubscriptionValidationDenied | Successfull acknowledgement |
| onSubscriptionVerification | Subscription verification failure |
| onUnsubscriptionVerification | Unsubscription verification failure |
| onEventNotification | Successfull acknowledgement |