The CloudVision Connector is a simple JavaScript module using WebSockets that enables you to transmit data over an open connection with the CloudVision API server. The CloudVision Connector supports subscribing to data, which lets clients receive streaming updates as data changes in real-time.
with yarn:
yarn add cloudvision-connector
or npm:
npm install --save cloudvision-connector
Quick introduction into to how to connect to the API server
const parseDatasets = (err, datasets) => {...};
// Add a callback
connector.getDatasets(parseDatasets);
// datasets returned in `parseDatasets` is a list of dataset ids
datasets = [
'JPE15076475',
'JPE12111270',
'app-turbine',
'HSH14525062',
'CloudTracer',
];
You can also get datasets use getWithOptions
(see details below). This is done by calling
getWithOptions
with Connector.DEVICES_DATASET_ID
as the first parameter.
const parseDevices = (err, datasets) => {...};
const query = Connector.DEVICES_DATASET_ID;
connector.getWithOptions(query, handleResponse);
The CloudVision Connector allows you to query notifications for multiple paths on a dataset, as well as multiple paths within multiple datasets.
Returns all notifications that match the given query and options.
query
: an object in the shape of a query (see "Query")callback
: a function that is called when notifications are received (see "Notifications Callback")options
: an object in the shape of query options (see "Options")const query = [{
dataset: {
type: 'app',
name: 'analytics'
},
paths: [{
path_elements: ['events','activeEvents'],
}],
}, {
dataset: {
type: 'app',
name: 'analytics'
},
paths: [{
path_elements: ['tags','stats'],
}, {
path_elements: ['BugAlerts','bugs'],
}],
}];
const handleResponse = (err, res, status) => {...};
const options = {
start: 1504113817725,
end: 1504113917725,
};
// open the stream
const token = connector.getWithOptions(query, handleResponse), options;
In addition to getting data, you can use the same query to subscribe to any updates to the data as it changes.
Returns all notifications that match the given query and options, in addition to subscribing to updates. This will return notifications as new updates to the data requested come in.
query
: an object in the shape of a query (see "Query")callback
: a function that is called when notifications are received (see "Notifications Callback")options
: an object in the shape of query options (see "Options")const query = [{
dataset: {
type: 'app',
name: 'analytics'
},
paths: [{
path_elements: ['events','activeEvents'],
}],
}, {
dataset: {
type: 'app',
name: 'analytics'
},
paths: [{
path_elements: ['tags','stats'],
}, {
path_elements: ['BugAlerts','bugs'],
}],
}];
const handleResponse = (err, res, status) => {...};
// open the stream
const subscribptionsIdentifier = connector.subscribe(query, handleResponse);
This is the callback, which is called when notifications are received.
const handler = (err, res, status, token) => {...}
Arguments:
err
: either a string or null
. If null
then there is no error. If it is a string, then an error occurred.
res
: an object with the properties dataset
and notifications
. e.g.
res = {
dataset: "someDevice",
notifications: {
"['path', 'to', 'some', 'data']": [...],
"['path', 'to', 'another', 'data']": [...],
...
}
}
Each [...]
above is an array of notifications which each have a timestamp
, path
, collection of
updates
, and deletes
(see "Data Model" section for more information).
token
: The token id that was created for the request.A status object has an optional message
key containing a string describing the status, in addition
to a code
key with the code number.
Possible status codes: |Code|JS Constant|Description| |1001|EOF_CODE|Signals that this is the last notification for the request| |3001|ACTIVE_CODE|Signals that the stream (subscription), has been established|
There are a number of options you can supply to the query which limit it's scope. Options are passed as an object, where the key is the name of the option and the value is the value for that option.
The options are start
, end
and versions
. There are different combinations of options that are
valid, each of them is listed below.
Range query (returns one or more data points):
start
: the epoch timestamp in (milliseconds) of the first data point.end
: the epoch timestamp in (milliseconds) of the last data point.Point in time query (returns exactly one data point):
end
: the epoch timestamp in (milliseconds) of the data point.Limit query (returns versions
+ 1 number of data points):
end
: the epoch timestamp in (milliseconds) of the last data point.versions
: the number of versions of data (in the past) to request in addition to the data point for end
.A query is an array of objects with a dataset key and paths key.
The value of each dataset is an object with a type (the type of the dataset, which can be device or app) and name (the identifier for the dataset e.g. 'JPE13262133') key.
The value of the paths key is an array of objects with a path_elements (an array of the component parts of a path) key and an optional keys key. The value of keys is an object that defines the shape of how you want the data to be returned. Think of it like a map that points to certain fields in CloudVision api.
query = [{
dataset: {
type: <dataset type>,
name: <dataset>,
},
paths: [{
path_elements: <path 1>,
}, {
path_elements: <path 2>,
keys: {
[any_custom_key]: {
key: <key 1>,
}
}
}],
}];
const handleResponse = (err, res) => {...};
const query = [{
dataset: {
type: 'app'.
name: 'analytics',
},
paths: [{
path_elements: ['events', 'activeEvents'],
}, {
path_elements: ['Logs', 'var', 'log', 'messages'],
keys: {
logMessage: {
key: 'text',
}
}
}],
}];
const options = {
start: 1504113817725,
end: 1504113917725,
};
connector.getWithOptions(query, null, options, handleResponse);
More in depth information on how to query different data.
You can connect to the CloudVision API server with any kind of WebSocket. This connector uses the regular browser WebSocket, but it also allows you to pass in your own custom implementation of a standard WebSocket.
You can also connect via secure WebSockets (wss
), which uses the same SSL certificate as https
does.
If you are using wss, you will need to get the authentication cookie from the CVP auth service.
const authUrl = 'https://example.cloudvision.api-server/cvpservice/login/authenticate.do';
const userId = 'user';
const password = 'my-password';
function loggedIn() {
console.log('You are logged in');
}
function authFailure(message) {
console.log('Auth Failure:', message);
}
window
.fetch(authUrl, {
method: 'POST',
credentials: 'include',
body: JSON.stringify({ userId, password }),
})
.then((response) => {
// Handle JSON response
return response.json();
})
.then((jsonResp) => {
if (jsonResp.sessionId) {
// We got a session id, so we are now logged in
loggedIn();
} else if (jsonResp.errorMessage) {
// Handle authentication failure
authFailure(jsonResp.errorMessage);
}
})
.catch
// Error handling for failed request
();
Once you have completed this request successfully, you will have the authentication cookie which will be sent along with the request to open the WebSocket.
// Import module
import Connector from 'cloudvision-connector';
// Create the connection
const connector = new Connector();
// Start the connection
connector.run('ws://example.cloudvision.api-server/api/v3/wrpc/');
// Start the connection with a custom WebSocket
class CustomWS extends WebSocket {
...
};
const connectorWithCustomWS = new Connector(CustomWS);
connectorWithCustomWS.runWithWs('ws://example.cloudvision.api-server/api/v3/wrpc/');
// Start a secure authenticated connection. NOTE: the `wss` vs `ws`
connector.run('wss://example.cloudvision.api-server/api/v3/wrpc/');
The Connector.connection
function adds a status-accepting callback to a Connector
and returns an
unbinding function that may be used to remove the callback. The status passed to the callback is
either Connector.CONNECTED
, or Connector.DISCONNECTED
. Additionally, the WebSocket event (see
WebSocket documentation) is passed as the second argument.
Connector.CONNECTED
is emitted once the WebSocket connection has been established and the client
is authenticated. At this point requests can be sent and the server will start sending responses.
Connector.DISCONNECTED
is emitted when the WebSocket is hung up.
function statusCallback(status, wsEvent) {
switch (status) {
case Connector.CONNECTED:
// react to connected event
break;
case Connector.DISCONNECTED:
// react to disconnected event
break;
}
}
// Add callback
const unbindStatus = connector.connection(statusCallback);
...
// Remove callback when done
unbindStatus();
Multiple callbacks may be added to a given Connector
via Connector.connection
:
// This is es6 arrow function notation (shortcut for function() {} )
const callback1 = (status) => {...}
const callback2 = (status) => {...}
const unbind1 = connector.connection(callback1)
const unbind2 = connector.connection(callback2)
Callbacks will be called in the order in which they were added.
Data returned from the CloudVision APi is both JSON and NEAT (more strict MessagePack) encoded.
Additionally NEAT encoded values are base64 encoded for transport. The notification body is JSON
encoded, while key
and value
attributes of the notification are NEAT encoded. The parser inside
the cloudvision-connector library takes care of decoding and encoding notifications for you. Note
that when notifications are decoded they are decoded into an object keyed key the notification key.
Since keys can be non strings, the key is the base64 NEAT encoded value. The value of this object
contains both the decoded key
and value
.
NEAT is MessagePack with some alterations listed below:
All strings are binary encoded
Maps and Object keys are encoded in order of binary value of the key. This means { a: 'b', c: 'd' }
and { c: 'd', a: 'b' }
are encoded as the same NEAT value.
Support for pointer values via the Pointer
extention type
Support for wildcard values via the Wildcard
extention type
To try out the CloudVision Connector in your browser, simply run
npm install
at the root
and then
npm run build:try
in the packages/cloudvision-connector directory
Then open index.html in your browser. In the developer console CloudVision Connector will be available as window.CloudVisionConnector.
Create the connector: conn = new window.CloudVisionConnector()
Connect to an API server:
conn.run('ws://example.cloudvision.api-server/api/v3/wrpc/')
Run a query:
conn.getWithOptions(window.CloudVisionConnector.DEVICES_DATASET_ID , (err, res) => console.log(err, res))
Contributing pull requests are welcomed for this repository. Please note that all contributions require 100% code test cases and 100% code coverage, otherwise the pull request will be rejected.
The CloudVision Connector is MIT licensed.