@sensaru/nodejs-c1-module
v1.0.10
Published
Easily connect Node.js microservices to Sensaru's cloud
Downloads
29
Readme
nodejs-c1-module
nodejs-c1-module
is a Node.js binding to connect a microservice written in Node.js to the Sensaru cloud. It supports
- invoking RPC methods within the Sensaru cloud,
- invoking REST requests within the Sensaru cloud,
- reception of live events from other microservices,
- reception of RPC method calls from other microservices or users and
- reception of REST calls from other microservices or users.
Installation
You can install nodejs-c1-module
using npm
:
npm i @sensaru/nodejs-c1-module
Alternatively clone this repository and execute:
node-gyp rebuild
or
npm link @sensaru/nodejs-c1-module
Security
The backend module does typically not provide an external IP endpoint. All requests come from C1 Core. This is why there is no need to handle authentication within the backend module. Some authorization is also handled within C1 Core. But some checks cannot be done within C1 Core and must mandatorilly be implemented within the backend module. See https://dev-doc.sensaru.com/authorization/ for more details and for instructions, what needs to be done.
Usage
First we need load the module:
const c1m = require('@sensaru/nodejs-c1-module');
Constructing the c1 object
Then we can create the c1 object. The constructor accepts 7 arguments and has the following signature:
C1(
object options,
function connected,
function disconnected,
function log,
function event,
function rpcRequest,
function restRequest
);
The constructor takes 7 parameters:
| Parameter | Type | Description |
|----------------|------------|-------------------------------------------------------------------------------------------|
| options
| object
| Settings passed to the constructor. |
| connected
| function
| Callback method that is called when a connection to C1 Core was successfully established. |
| disconnected
| function
| Callback method that is called when the connection to C1 Core is lost. |
| log
| function
| Callback method that is called when the module wants to log something. |
| event
| function
| Callback method that is called on incoming event packets from the event broker. |
| rpcRequest
| function
| Callback method that is called on incoming RPC requests. |
| restRequest
| function
| Callback method that is called on incoming REST requests. |
The options
object
The options
object has the following properties:
| Property | Type | Description |
|----------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| coreHosts
| string
| Comma-separated list of seed servers, the module initially connects to. For the production system the property should be set to "n0r0c0.core.sensaru.net, n1r0c0.core.sensaru.net, n2r0c0.core.sensaru.net"
(space is ignored). |
| corePort
| number
| Port the core servers listen on. For the production system this is 4000
. |
| nodeName
| string
| The name of the Kubernetes node the module runs on. Should be filled by an environment variable. This setting is mandatory and must be set correctly. It is required to optimize routing within the cluster. |
| moduleName
| object
| An object containing the localized names of the module. E.g. {"en-US": "My module", "de-DE": "Mein Modul", "de": "Mein Modul"}
. |
| moduleDescription
| object
| An object containing the localized descriptions of the module. Can be left empty for now. |
| moduleUiMenu
| object
| The backend module can register menu entries for its associated frontend within C1 Core. |
| moduleUiCategory
| string
| The category the menu entries should be displayed in. |
| aclInfo
| object
| Registers the list of available RPC methods and the required access level in C1 Core. |
| moduleEventSubscriptions
| array
| List of event topics to subscribe to. |
| widgetInfo
| object
| Information about widgets the backend's frontend module provides. |
| coreProcessingThreads
| number
| Number of processing threads to start. This is the number of requests that can be processed in parallel. |
| caFile
| string
| Path the C1 Core endpoint's CA certificate. |
| clientCertFile
| string
| Path the client certificate used to authenticate the module to C1 Core. |
| clientKeyFile
| string
| Path the client key file used to authenticate the module to C1 Core. |
| debugOutput
| string
| Send debug output to the log callback method. Should only be enabled for debugging as this causes a relevant load. |
| allowBusinessPartnerUserAccess
| bool
| When set to false
, business partner users are denied access. |
| allowEndUserAccess
| bool
| When set to false
, end users are denied access. |
| allowEdgeClientAccess
| bool
| When set to false
, edge clients are denied access. |
| systemProviderModule
| bool
| When set to true
, only system provider users or modules with at least system provider level are granted access. |
Callback method connected()
The callback method has the following signature:
undefined connected(string host, number port)
| Parameter | Type | Description |
|-----------|----------|---------------------------------------------|
| host
| string
| The hostname or IP address of the endpoint. |
| port
| number
| The port number of the endpoint. |
Callback method disconnected()
The callback method has the following signature:
undefined disconnected()
Callback method log()
The callback method has the following signature:
undefined log(number logLevel, string message)
| Parameter | Type | Description |
|------------|----------|------------------------------------------------------------------------------------|
| logLevel
| number
| 1
=> critical
, 2
=> error
, 3
=> warning
, 4
=> info
, 5
=> debug
|
| message
| string
| The log message. |
Callback method event()
The callback method has the following signature:
undefined event(string topic, object payload)
| Parameter | Type | Description |
|-----------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| topic
| string
| The event's topic. |
| payload
| object
| The event's payload. It is extended by the property verifiedMetadata
containing security relevant information (see https://dev-doc.sensaru.com/authorization/). |
Callback method rpcRequest()
The callback method has the following signature:
any rpcRequest(string methodName, array parameters, object resultingPrincipal, object acl, number requestId)
| Parameter | Type | Description |
|----------------------|----------|--------------------------------------------------------------------------------------------------|
| methodName
| string
| The RPC method's name that is called. |
| parameters
| array
| The parameters passed to the RPC method. |
| resultingPrincipal
| object
| The principal accessing the RPC method (see https://dev-doc.sensaru.com/authorization/). |
| acl
| object
| The ACL of the entity accessing the RPC method (see https://dev-doc.sensaru.com/authorization/). |
| requestId
| number
| The ID of the request. Pass this to rpcResponse()
when used in an async function. |
Return value
A value of any type can optionally be returned by the method. The value will be sent to the caller of the RPC method. When used in an async function, the return value is ignored. In this case, calling rpcResponse(number requestId, any response)
sends the response to the sender.
Callback method restRequest()
The callback method has the following signature:
object restRequest(string method, string path, object query, object headers, any data, object resultingPrincipal, object acl, number requestId)
| Parameter | Type | Description |
|----------------------|----------|--------------------------------------------------------------------------------------------------|
| method
| string
| The HTTP method of the REST request. |
| path
| string
| The path. |
| query
| object
| The query parameters. |
| headers
| object
| HTTP headers of the original request. |
| data
| any
| Optional data passed with the REST request (e. g. for POST or PUT requests). |
| resultingPrincipal
| object
| The principal accessing the RPC method (see https://dev-doc.sensaru.com/authorization/). |
| acl
| object
| The ACL of the entity accessing the RPC method (see https://dev-doc.sensaru.com/authorization/). |
| requestId
| number
| The ID of the request. Pass this to restResponse()
when used in an async function. |
Return value
A value must always be returned by this method. The returned value must be an object with the following structure:
{
"data": <arbitrary_data>,
"headers": [
"Content-Type: application/json",
"My-Header-Field: my-value"
]
}
| Property | Type | Description |
|-----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------|
| data
| any
| Can be of any type (e.g. JSON or binary data). |
| headers
| array
| Optional. An array of strings that will be returned as response headers. When Content-Type
is not set, it defaults to application/json
. |
When used in an async function, the return value is ignored. In this case you must call restResponse(number requestId, any response)
.
Exposed methods
start()
Must be called once after the object has been constructed to initialize the connection.
The method has the following signature:
undefined start()
The method has no parameters and does not have a return value.
stop()
Must be called once before the module shuts down. It gracefully disconnects the module from C1 Core.
The method has the following signature:
undefined stop()
The method has no parameters and does not have a return value.
connected()
Can be called to check if the module is connected currently.
The method has the following signature:
bool connected()
The method has no parameters and returns true
when the module is connected. When the module is not connected false
is returned.
invoke()
invoke()
can be called to send raw RPC method requests to C1 Core. Behind the scenes invoke()
is used for all
requests to C1 Core.
The method has the following signature:
async any invoke(string methodName, array parameters)
The method takes the RPC method's name and its parameters as arguments and returns the return value of the RPC method call.
moduleMethod()
This is a shortcut method to simplify calls to the RPC method moduleMethod
.
The method has the following signature:
async any moduleMethod(string moduleId, string methodName, array parameters, number qos, object userId)
| Parameter | Type | Description |
|--------------|----------|--------------------------------------------------------------------------------------------|
| moduleId
| string
| The ID of the module to execute the RPC call in (e. g. c1-device-management). |
| methodName
| string
| The name of the RPC method to call. |
| parameters
| array
| parameters passed to the RPC method. |
| qos
| number
| 0
to disable QoS, 1
for at least once delivery. |
| userId
| object
| For some RPC methods the ID of the accessing user is required. This ID can be passed here. |
The method returns null
on success. The result of the RPC method call is not returned. It is returned asynchronously
by a call to the RPC method moduleMethodResponse()
. This call must be handled
in the callback method rpcRequest()
.
restRequest()
Using this method you can execute REST requests on other modules within the Sensaru cloud.
The method has the following signature:
async any restRequest(string method, string path, string businessPartnerId, any data)
| Parameter | Type | Description |
|---------------------|----------|-------------------------------------------------------|
| method
| string
| The HTTP method to use. |
| path
| string
| The HTTP path including query parameters. |
| businessPartnerId
| string
| The mandatory ID of the calling business partner. |
| data
| any
| Optional data to pass e. g. for POST or PUT requests. |
The method returns the unmodified content of the returned HTTP packet.
Example
'use strict'
const c1m = require('@sensaru/nodejs-c1-module');
const settings = {
coreHosts: "n0r0c0.core.sensaru.net, n1r0c0.core.sensaru.net, n2r0c0.core.sensaru.net",
corePort: 4000,
nodeName: "n2r0c0",
moduleName: {"en-US": "node-js-c1-module-test"},
moduleDescription: {},
moduleUiMenu: {},
moduleUiCategory: "",
moduleAppUiUrl: "",
moduleAppUiCategory: "",
aclInfo: {version: 1, rpcMethods: {ping: "read"}},
moduleEventSubscriptions: [/* "c1-home/+/+/-/-/+/telemetry/#" */],
widgetInfo: {},
coreProcessingThreads: 50,
caFile: "/etc/nodejs-c1-module-test/core-ca-cert.pem",
clientCertFile: "/etc/nodejs-c1-module-test/core-client-tls.crt",
clientKeyFile: "/etc/nodejs-c1-module-test/core-client-tls.key",
allowBusinessPartnerUserAccess: true,
allowEndUserAccess: false,
allowEdgeClientAccess: false,
systemProviderModule: false,
debugOutput: false
}
function connected(host, port) {
console.log("Connected", host, port);
}
function disconnected() {
console.log("Disconnected")
}
function log(logLevel, message) {
console.log(message);
}
function event(topic, payload) {
console.log(topic, payload);
}
function rpcRequest(methodName, parameters, resultingPrincipal, acl) {
console.log(methodName, parameters, resultingPrincipal, acl);
return null;
}
function restRequest(method, path, headers, data, resultingPrincipal, acl) {
console.log(method, path, headers, data, resultingPrincipal, acl);
return {"success": true, "hello": "Sensaru"};
}
const c1 = new c1m.C1(settings, connected, disconnected, log, event, rpcRequest, restRequest);
c1.start();
setInterval(function () {
const result = c1.restRequest("GET", "assets?limit=1000", "00b8692a-7789-484f-9916-0a41b4af5444");
console.log("Result", result, result.result.assets);
}, 5000);
setTimeout(function () {
c1.stop();
console.log("Done");
}, 300000);