Overview
The Inventory Sync Plugin API enables developers to create plugins that integrate with external device management software/platforms. This enables syncing of inventory from other device management platforms into the Reekoh device registry. This article aims to provide detailed information on the APIs available for Inventory Sync Plugins and how to build one.
Starting a Node.js Inventory Sync Plugin Project
To easily create a plugin project scaffolding for Inventory Sync plugins, Reekoh has provided a generator tool which can be used like:
cd path/to/your/project-folder
yo reekoh-node:inventory-sync
Building the Plugin
The file named app.js is where everything starts. To use the Inventory Sync Plugin API, one starts by creating a Inventory Sync instance as seen on the scaffolding's app.js file.
app.js
'use strict'
const reekoh = require('reekoh')
const plugin = new reekoh.plugins.InventorySync()
plugin
is now an instance of an Inventory Sync with the necessary properties, methods, and events for creating an Inventory Sync plugin. Details of the Inventory Sync instance' properties, methods and events are specified in the following sections.
Properties
Specified below are the properties of an Inventory Sync instance which are injected for use in your plugin.
- config {object} - The custom plugin configuration values as requested from and specified by the end user. For more about plugin configurations, please see the Packaging & Submission section.
Events
Specified below are the events that a Inventory Sync instance is able to emit based upon operations that are happening on the platform pipelines.
'ready'
This event is emitted when the Inventory Sync instance has fully initialised. This is usually the event where one listens to and puts the code to create the API client which connects & communicates to the external device management software/platform.
Sample Code
let client
plugin.on('ready', () => {
client = createClient(plugin.config.apiKey)
client.on('connected', () => {
plugin.log('Client is now connected to the service')
})
})
'sync'
This event is only available for Inventory Sync plugins that have "PULL" method of integration. Means that it pulls new or updated devices from the external device management software using a pre-defined frequency or schedule i.e. every 5 minutes. This is the event to listen to trigger the sync function that pulls down inventory data and register into Reekoh.
Sample Code
plugin.on('sync', () => {
let execDateTime = Date.now()
plugin.getState().then(state => {
client
.getNewOrUpdatedDevices(state.lastPullDateTime)
.then(devices => {
devices.forEach(device => {
plugin.log('Registering device')
plugin.log(device)
if (device.status !== 'deleted') {
plugin.syncDevice(device)
} else {
plugin.removeDevice(device.id)
}
})
plugin.setState({
lastPullDateTime: execDateTime
})
})
.catch(err => {
plugin.logException(err)
})
})
})
'adddevice'
This event is emitted when a new device is registered on the Reekoh device registry. If the external device management software exposes a Device Registration/Provisioning API, then this is the event to listen to for sending the device details.
Arguments
- device {object} - the newly registered device on the Reekoh platform. This object has the following properties:
- _id {string} - the Device' ID
- name {string} - the Device' Name
- metadata {object} - the Device' metadata.
Sample Code
plugin.on('adddevice', device => {
client
.registerDevice(device)
.then(() => {
plugin.log('Registered Device')
plugin.log(device)
})
.catch(err => {
plugin.logException(err)
})
})
'updatedevice'
This event is emitted when a registered device in Reekoh has been updated . If the external device management software exposes a Device Update API, then this is the event to listen to for sending the updated device details.
Arguments
- device {object} - the updated device on the Reekoh platform. This object has the following properties:
- _id {string} - the Device' ID
- name {string} - the Device' Name
- metadata {object} - the Device' metadata.
Sample Code
plugin.on('updatedevice', device => {
client
.updateDevice(device)
.then(() => {
plugin.log('Updated Device')
plugin.log(device)
})
.catch(err => {
plugin.logException(err)
})
})
'removedevice'
This event is emitted when a registered device in Reekoh has been deleted . If the external device management software exposes a Device Delete API, then this is the event to listen to for deleting the device on the other platform.
Arguments
- device {object} - the deleted device on the Reekoh platform. This object has the following properties:
- _id {string} - the Device' ID
- name {string} - the Device' Name
- metadata {object} - the Device' metadata.
Sample Code
plugin.on('removedevice', device => {
client
.deleteDevice(device._id)
.then(() => {
plugin.log('Removed Device')
plugin.log(device)
})
.catch(err => {
plugin.logException(err)
})
})
Methods
Specified below are Connector API methods that you can use for your plugin to relay information and initiate operations on the platform.
syncDevice(deviceInfo, [deviceGroup])
Invoke this method to sync/register/update a device into Reekoh's device registry.
Arguments
- deviceInfo {object} - The device to register. The only required properties are _id or id and name. All other properties will be added to the device' metadata. If the device is already existing, it will be updated. If the existing device has metadata, additional metadata will be appended from the deviceInfo.
- deviceGroup {string} - Optional The device group id where the device should belong to.
Returns
- Promise - which is fulfilled when the device has been submitted for registry.
Sample Code
plugin.on('sync', () => {
let execDateTime = Date.now()
plugin.getState().then(state => {
client
.getNewOrUpdatedDevices(state.lastPullDateTime)
.then(devices => {
devices.forEach(device => {
plugin.log('Registering device')
plugin.log(device)
if (device.status !== 'deleted') {
plugin.syncDevice(device)
} else {
plugin.removeDevice(device.id)
}
})
plugin.setState({
lastPullDateTime: execDateTime
})
})
.catch(err => {
plugin.logException(err)
})
})
})
removeDevice(deviceId)
Invoke this method to remove a device into Reekoh's device registry.
Arguments
- deviceId {string} - the ID of the device as registered on the platform.
Returns
- Promise - which is fulfilled when the device has been submitted for removal.
Sample Code
plugin.on('sync', () => {
let execDateTime = Date.now()
plugin.getState().then(state => {
client
.getNewOrUpdatedDevices(state.lastPullDateTime)
.then(devices => {
devices.forEach(device => {
plugin.log('Registering device')
plugin.log(device)
if (device.status !== 'deleted') {
plugin.syncDevice(device)
} else {
plugin.removeDevice(device.id)
}
})
plugin.setState({
lastPullDateTime: execDateTime
})
})
.catch(err => {
plugin.logException(err)
})
})
})
setState(state)
Invoke this method to set the plugin's state. State can be used to store additional information or metadata for the plugin. It can also be used as cache for any information that needs to be stored temporarily.
Arguments
- state {any} - state to be stored. Can be anything - object, array, string, number etc.
Returns
- Promise - which is fulfilled when the state has been submitted for storage.
Sample Code
plugin.on('sync', () => {
let execDateTime = Date.now()
plugin.getState().then(state => {
client
.getNewOrUpdatedDevices(state.lastPullDateTime)
.then(devices => {
devices.forEach(device => {
plugin.log('Registering device')
plugin.log(device)
if (device.status !== 'deleted') {
plugin.syncDevice(device)
} else {
plugin.removeDevice(device.id)
}
})
plugin.setState({
lastPullDateTime: execDateTime
})
})
.catch(err => {
plugin.logException(err)
})
})
})
getState()
Invoke this method to retrieve the contents of the plugin state.
Returns
- Promise (state {any}) - resolves or returns the contents of the plugin's state.
Sample Code
plugin.on('sync', () => {
let execDateTime = Date.now()
plugin.getState().then(state => {
client
.getNewOrUpdatedDevices(state.lastPullDateTime)
.then(devices => {
devices.forEach(device => {
plugin.log('Registering device')
plugin.log(device)
if (device.status !== 'deleted') {
plugin.syncDevice(device)
} else {
plugin.removeDevice(device.id)
}
})
plugin.setState({
lastPullDateTime: execDateTime
})
})
.catch(err => {
plugin.logException(err)
})
})
})
log(logData)
Invoke this function to log any information. Can be useful for debugging. Logs are found under the Logs module or in each plugin instance in the Pipeline Studio.
Arguments
- logData {string | object} - The information to be logged.
Returns
- Promise - fulfilled when the log data has been submitted to the platform for recording.
Sample Code
plugin.on('sync', () => {
let execDateTime = Date.now()
plugin.getState().then(state => {
client
.getNewOrUpdatedDevices(state.lastPullDateTime)
.then(devices => {
devices.forEach(device => {
plugin.log('Registering device')
plugin.log(device)
if (device.status !== 'deleted') {
plugin.syncDevice(device)
} else {
plugin.removeDevice(device.id)
}
})
plugin.setState({
lastPullDateTime: execDateTime
})
})
.catch(err => {
plugin.logException(err)
})
})
})
logException(err)
Invoke this function to log errors/exceptions. Can be useful for debugging. Error/exception logs are found under the Logs module or in each plugin instance in the Pipeline Studio.
Arguments
- err {error} - The error to be logged.
Returns
- Promise - fulfilled when the error data has been submitted to the platform for recording.
Sample Code
plugin.on('sync', () => {
let execDateTime = Date.now()
plugin.getState().then(state => {
client
.getNewOrUpdatedDevices(state.lastPullDateTime)
.then(devices => {
devices.forEach(device => {
plugin.log('Registering device')
plugin.log(device)
if (device.status !== 'deleted') {
plugin.syncDevice(device)
} else {
plugin.removeDevice(device.id)
}
})
plugin.setState({
lastPullDateTime: execDateTime
})
})
.catch(err => {
plugin.logException(err)
})
})
})
Reference Implementations
Listed below are some reference implementations of the Inventory Sync Plugin API.
These are just some of the Inventory Sync Plugins developed and open-sourced by Reekoh. You may visit our Gitlab Page for more information. Contributions are most welcome.
Comments
0 comments
Please sign in to leave a comment.