NetApp Pub/Sub Client Library

Introduction

NetApp Pub/Sub client library is a JavaScript AMQP protocol wrapper. It provides easy-to-do API to establish a connection with ONTAP cluster and to receive messages from ONTAP Pub/Sub server.

Dependency

This tool is strongly based on rhea. Check rhea to improve this client library or build your own client library if you think there are missing features you need.

Installation

This tool is currently only available on GitHub. Please clone this repository and use it as a git submodule or a local sub project. Then use the command npm install to install all the essential dependencies to run this tool.

Hello World

const Connection = require('../src/connection.js')
const Credential = require('../src/credentials.js')
const receiverEvents = require('../src/events.js').receiverEvents
const connectionEvents = require('../src/events.js').connectionEvents

// TODO: Use your own username and password
const credentialObj = new Credential(
  (username = 'admin'),
  (password = 'secret is shush')
)

// TODO: Use your own host
const connection = new Connection(
  (host = '123.456.789.000'),
  (credentials = credentialObj),
  (clientId = 'yc_client')
)

connection.on(connectionEvents.open, (context) => {
  console.log('Connection established')
})

const testReceiver = connection.openReceiver('re1', 'ontap.test')

// When a connection is obtained
testReceiver.on(receiverEvents.receiverOpen, function (context) {
  // Notify the user
  console.log('test receiver connected')
})

testReceiver.on(receiverEvents.message, function (context) {
  // Display it
  console.log('hello from the cluster')
  console.log(context.message.body)
})

API

Credentials

This class holds the data of a user's credentials. It currently only supports the simple authentication method (username + password)

Credentials class expects two input parameters:

  1. username: name of the target ONTAP cluster
  2. password: password of the target ONTAP password

username and password are supposed to be the same as the ones used to authenticate the ONTAP cluster.

Example:

const Credential = require('credentials.js')

const credentialObj = new Credential(
  (username = 'admin'),
  (password = 'allegheny123!')
)

Connection

Connection object contains all the APIs to manage the connection between the ONTAP cluster server and the client library. below is a list of input parameters to create a Connection object.

  1. host: The address or hostname of the ONTAP systems to connect to
  2. credentials: A user Credentials object used to authenticate the connection
  3. clientId: A textual name to differentiate between multiple clients
  4. path (default: '/ontapmsg'): The path on the host that the websocket connection will use
  5. secure (default: true): Establish a secured websocket connection if set as true
  6. reconnect (default: true): if true (by default), the client will automatically attempt to reconnect if disconnected
  7. linkTimeout (default:60000): The amount of time (in milliseconds) that allows link to remain when connection is inactive
  8. initialReconnectDelay (default: 10000): The amount of time the client should wait before attempting to reconnect
  9. maxReconnectDelay (default: 10000): The maximum amount of time that the client should wait to reconnect
  10. reconnectLimit (default: 10): The amount of times the client is allowed to attempt to reconnect
  11. rejectUnauthorizedHost (default: 10): Refuse unauthorized host to connect

Below is the list of methods under the Connection object:

connect

connect() establishes a connection with ONTAP server. It or its sibling API awaitableConnect is supposed to be called before any other APIs.

connect() doesn't expect any input parameters.

openReceiver

Create a new event receiver on an ONTAP Pub/Sub topic in an asynchronous and non-awaitable fashion.

openReceiver returns a Receiver object.

Below is the list of input parameters that openReceiver method accepts:

  1. name: unique name of this receiver to distinguish it from other receivers
  2. topic: topic on the server side that the receiver subscribes to
  3. filter (default: null): The specification by which messages are filtered
  4. dynamic (default: false): Request that a node is automatically created by the remote peer
  5. expiryPolicy (default: never): Set the starting point for the expiration clock
  6. durable (default: 2): Determines what state of the receiver is retained durably
  7. target (default: null): The target to which messages are sent
  8. autoaccept (default: true): Whether automatic receptance of messages that aren't otherwise released, rejected, or modified
  9. autosettle (default: true): Whether messages should be automatically settled once the remote peer settles them \ Return a Receiver object.\

Example:

const testReceiver = myConnection.openReceive('re1', 'ontap.test')

Filter feature is a SQL like query string that restricts the set of messages delivered

Example:

connection.openReceiver('error_receiver', 'ontap.ems',"severity ='error'")
connection.openReceiver('alert_notice_receiver', 'ontap.ems', "severity IN ('alert','notice')")

In this example, we open two receivers on the same connection. The error_receiver only listens to the ontap.ems topic where severity is 'error'. While the second receiver also listens to the ontap.ems topic,it only triggers when the severity is alert or notice.

openReceivers

Open a series of receivers in an asynchronous and non-awaitable fashion.

This method expects an array of objects constitute parameters accepted by openReceiver.

name and topic values are mandatory.

openReceivers returns an array of Receiver objects.

Example:

myConnection.openReceivers([
  { name: 'receiver_one', topic: 'ontap.ems' },
  {
    name: 'alert_notice_receiver',
    topic: 'ontap.ems',
    filter: "severity IN ('alert','notice')"
  }
])

getReceivers

Return an object of Receiver objects on the connection regardless of the state of Receiver (like open/closed).

const error_receiver = connection.getReceivers().error_receiver

close

close the connection between the ONTAP server and the client library.

awaitableConnect

A promise-based connect method. It keeps running until the call returns resolve or error.

awaitableConnect method doesn't expect any input parameters.

awaitableOpenReceiver

A promise-based openReceiver method.

Below is the list a list of input parameters that awaitableOpenReceiver expects:

  1. name: unique name of this receiver to distinguish it from other receivers
  2. topic: topic on server side that the receiver subscribes to
  3. filter (default: null): The specification by which messages are filtered
  4. dynamic (default: false): Request that a node is automatically created by the remote peer
  5. expiryPolicy (default: 'never'): Set the starting point for the expiration clock
  6. durable (default: 2): Determines what state of the receiver is retained durably
  7. target (default: null): The target to which messages are sent
  8. autoaccept (default: true): Whether automatic receptance of messages that aren't otherwise released, rejected, or modified
  9. autosettle (default: true): Whether messages should be automatically settled once the remote peer settles them
  10. timeout (default: 30): the time session of attempting openReceiver. Kill the Promise if timeout

awaitableClose

A promise-based close method.

It expects no input parameters.

Event Listeners of Connection (not a method)

You can add event listeners on the connection Object to monitor or handle certain connection-level events.

connection object supports three event listeners:

  • on: Listen to a specific event and call a callback function while event triggers
  • off: Remove, at most, one instance of a listener from the listener array.
  • once: Listen to a specific event and call a callback function while event triggers. Only work for one time

Event listeners accept two input parameters:

  1. connectionEvent
  2. callbackFunction

connection event is an event triggered by an event listener. This event listener only acts after this event is encountered. callback function is a callback function that the event listener calls after being activated.

Below are the events on the Connection object:

  • open
  • close
  • error
  • protocolError
  • disconnected
  • settled

Example:

const connection = new Connection(
  (host = '123.456.789.000'),
  (credentials = credentialObj),
  (clientId = 'my_client')
)

connection.on(connectionEvents.open, (context) => {console.log('Connection established')})

Receiver

Receiver is an object associated with a specific ONTAP Pub/Sub topic. It receives messages from the ONTAP and handle it.

Receiver object should be created by methods in Connection object like openReceiver.

Without special purposes, users are not expected to create Receiver objects by themselves.

Methods under Receiver object are listed below:

  • close: close the receiver
  • detach: detach the receiver but not close it
  • addCredit: add credit to designate how many more messages are desired to be received
  • credit: return the current amount of credit issued
  • isConnected: return the status of the receiver

Event Listers of Receiver (not a method)

  • on: Listen to a specific event and call a callback function while event triggers
  • off: Remove, at most, one instance of a listener from the listener array
  • once: Listen to a specific event and call a callback function while event triggers. Only work for one time

Event listeners accept two input parameters:

  1. connectionEvent
  2. callbackFunction

Here is the list of events on Receiver object

  • message: when receive message from ONTAP Pub/Sub
  • receiverOpen: raised when the receiver opens
  • receiverDrained: raised when the receiver is drained
  • receiverFlow: raised when a flow is received for receiver
  • receiverError: raised when the remote peer closes the receiver with an error. A receiverClose event will always follow this event, so it only needs to be implemented if there are specific actions to be taken on a close with an error as opposed to a close. The error is available as an error property on the receiver.
  • receiverClose: raised when the remote peer indicates the link is closed (i.e. detached in AMQP parlance)
  • settled: raised when remote settled the message

Example:

const testReceiver = connection.openReceiver('re1', 'ontap.test')

// When a connection is obtained
testReceiver.on(receiverEvents.receiverOpen, function (context) {
  // Notify the user
  console.log('test receiver connected')
})

testReceiver.on(receiverEvents.message, function (context) {
  // Display it
  console.log(context.message.body)
})

Example

See the demo folder to check examples.

Future Work

Below is a list of future work on this tool:

  • bug fixing
  • defect improving