ballerina/websub

Overview

This module provides APIs for WebSub Subscriber Service.

WebSub is a common mechanism for communication between publishers of any kind of Web content and their subscribers, based on HTTP webhooks. Subscription requests are relayed through hubs, which validate and verify the request. Hubs then distribute new and updated content to subscribers when it becomes available. WebSub was previously known as PubSubHubbub.

WebSub Subscriber is an implementation that discovers the hub and topic URL of a given resource URL, subscribes to updates at the hub, and accepts content distribution requests from the hub.

Basic flow with WebSub

  1. 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.

  2. 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.

  1. 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.

  1. The publisher notifies the hub of the updates to the topic and the content to deliver is identified.

  2. The hub delivers the identified content to the subscribers of the topic.

Subscribing

  • The WebSub Subscriber provides the mechanism to subscribe in a hub to a given topic URL.
1@websub:SubscriberServiceConfig {
2 target: ["<HUB_URL>", "<TOPIC_URL>"],
3 leaseSeconds: 36000
4}
5service /subscriber on new websub:Listener(9090) {
6 remote function onSubscriptionValidationDenied(websub:SubscriptionDeniedError msg) returns websub:Acknowledgement? {
7 // implement subscription validation denied logic here
8 return websub:ACKNOWLEDGEMENT;
9 }
10
11 remote function onSubscriptionVerification(websub:SubscriptionVerification msg)
12 returns websub:SubscriptionVerificationSuccess|websub:SubscriptionVerificationError {
13 // implement subscription intent verification logic here
14 return websub:SUBSCRIPTION_VERIFICATION_SUCCESS;
15 }
16
17 remote function onEventNotification(websub:ContentDistributionMessage event)
18 returns websub:Acknowledgement|websub:SubscriptionDeletedError? {
19 // implement on event notification logic here
20 return websub:ACKNOWLEDGEMENT;
21 }
22}

Resource Discovery

  • The WebSub Subscriber also provides the mechanism to discover the hub and topic URL resources dynamically via the provided resource URL and initiates the subscription.
1@websub:SubscriberServiceConfig {
2 target: "RESOURCE_URL",
3 leaseSeconds: 36000
4}
5service /subscriber on new websub:Listener(9090) {
6 remote function onEventNotification(websub:ContentDistributionMessage event)
7 returns websub:Acknowledgement|websub:SubscriptionDeletedError? {
8 // implement on event notification logic here
9 return websub:ACKNOWLEDGEMENT;
10 }
11
12 // other remote methods are optional to be implemented
13}

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.
1@websub:SubscriberServiceConfig {
2 target: "RESOURCE_URL",
3 leaseSeconds: 36000
4}
5service on new websub:Listener(9090) {
6 remote function onEventNotification(websub:ContentDistributionMessage event)
7 returns websub:Acknowledgement|websub:SubscriptionDeletedError? {
8 // implement on event notification logic here
9 return websub:ACKNOWLEDGEMENT;
10 }
11
12 // other remote methods are optional to be implemented
13}

Running Subscriber Service 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 9090 to the public network via HTTPS. For information, see the ngrok documentation).
1ngrok http -bind-tls=true 9090
  • Extract the public URL provided by nGrok and provide it as the callback URL for the subscriber service.
1@websub:SubscriberServiceConfig {
2 target: "RESOURCE_URL",
3 leaseSeconds: 36000,
4 callback: "<NGROK_PUBLIC_URL>",
5 appendServiceUrl: true
6}
7service on new websub:Listener(9090) {
8 remote function onEventNotification(websub:ContentDistributionMessage event)
9 returns websub:Acknowledgement|websub:SubscriptionDeletedError? {
10 // implement on event notification logic here
11 return websub:ACKNOWLEDGEMENT;
12 }
13
14 // other remote methods are optional to be implemented
15}

Returning Errors from Remote Methods

  • Remote functions in websub:SubscriberService can return error type.
1@websub:SubscriberServiceConfig {
2 target: "RESOURCE_URL",
3 leaseSeconds: 36000,
4 callback: "<NGROK_PUBLIC_URL>",
5 appendServiceUrl: true
6}
7service on new websub:Listener(9090) {
8 remote function onEventNotification(websub:ContentDistributionMessage event)
9 returns websub:Acknowledgement|websub:SubscriptionDeletedError|error? {
10 boolean isValidRequest = check validateRequest(event);
11 if isValidRequest {
12 // implement on event notification logic here
13 return websub:ACKNOWLEDGEMENT;
14 }
15
16 }
17
18 // other remote methods are optional to be implemented
19}
20
21function validateRequest(websub:ContentDistributionMessage event) returns boolean|error {
22 // validation logic
23}
  • For each remote method error return has a different meaning. Following table depicts the meaning inferred from error returned from all available remote methods.
MethodInterpreted meaning for Error Return
onSubscriptionValidationDeniedSuccessfull acknowledgement
onSubscriptionVerificationSubscription verification failure
onEventNotificationSuccessfull acknowledgement

Listeners

[1]

Listener

Represents a Subscriber Service listener endpoint.

Clients

[2]

DiscoveryService

Represents resource-discovery service which identify the hub and topic from resource-URL.

SubscriptionClient

The HTTP based client for WebSub subscription and unsubscription.

Functions

[2]

getHeader

Returns the value of the specified header.

getHeaders

Gets all the header values to which the specified header key maps to.

Object Types

[1]

SubscriberService

The WebSub service type

Records

[8]

Acknowledgement

Record representing the subscription-denial/content-distribution acknowledgement.

ContentDistributionMessage

Record representing the content-distribution request.

ListenerConfiguration

Provides a set of configurations for configure the underlying HTTP listener of the WebSub listener.

SubscriberServiceConfiguration

Configuration for a WebSubSubscriber service.

SubscriptionChangeRequest

Record representing a WebSub subscription change request-body.

SubscriptionChangeResponse

Record representing subscription/unsubscription details if a subscription/unsubscription request is successful.

SubscriptionVerification

Record representing the subscription / unsubscription intent verification request-body.

SubscriptionVerificationSuccess

Record representing the subscription / unsubscription intent verification success.

Annotations

[1]

SubscriberServiceConfig

WebSub Subscriber Configuration for the service, indicating subscription related parameters.

Variables

[4]

ACKNOWLEDGEMENT

Common Responses to be used in the subscriber-service implementation.

SUBSCRIPTION_VERIFICATION_SUCCESS
SUBSCRIPTION_VERIFICATION_ERROR
SUBSCRIPTION_DELETED_ERROR

Errors

[8]

Error

Represents a webSub distinct error.

ListenerError

Represents a listener errors.

ResourceDiscoveryFailedError

Represents a resource-discovery failed error.

ServiceExecutionError

Represents a websub service execution error.

SubscriptionDeletedError

Represents the subscription-delete action from the subscriber.

SubscriptionDeniedError

Represents a subscription-denied error.

SubscriptionInitiationError

Represents a subscription-initiation failed error.

SubscriptionVerificationError

Represents a subscription-verificatation error.