Nidulus Platform - Documentation

The "oh, so advanced" guide to get started mass producing APIs with Nidulus


Welcome, we assume you just downloaded your Nidulus server for the first time and panic over not knowing what to do now. Take a deep breath and let us get to work.


Unpack your download


unzip nidulus_x_x_x.zip (where x_x_x is the version of your download). 

Start nidulus


cd nidulus; ./nidulus 

Web interface


The web client you downloaded will have its web interface running on port 7999. Point your browser to http://<your Nidulus client ip>:7999/ to get to the login page. Login with admin/password123


Initial configuration


After logging on, you will be directed to the server page. There are no servers pre-populated, so you will have to add one. Click the "Add Server" button and enter the IP/URL of the machine where you started the nidulus server on. No port must be added, just IP/URL.

The certificate that is asked for will have been created when you started up your Nidulus server, in the home folder of the user you started it with: ~/client.crt

Once done, you will have finished setting up graphical monitoring/management of your server in your web client.



When configuring the localhost instance (through the cogwheel menu on the server card), you will have two options:

Adding/setting your activation key
Changing security key


Activation key is your license key (if you purchased/were given one).

The security key, which must be 16 characters long, is randomized for every new machine you start a Nidulus server on but can be changed into any 16 character sequence. If you wish to communicate between two Nidulus machines (service network scaling), you need to update the security key to be same on both machines to avoid getting an unauthorized reply. No other configuration is needed as every API and service automatically find each other on the network.


If you accidentally "delete" a server in the web client, nothing will happen to the server. You will just stop monitoring it from the web client and can add it back later on. Everything you deployed on it will continue to run, it just won't show up in your web client.


What do I do now?


Now you can go to the "Process List" on your newly added server and add new APIs, deploy features (the devtools package you downloaded) and schedule timed triggers of your features, as needed.

It really isn't harder than this to build advanced APIs, and shouldn't be.

We added an in-app help-center with explanations of each part if you wonder about something while in the app. You can find it in the upper-right corner of the web app, in the cogwheel menu. You can also change the password for the admin account from there.

Firewall Configuration


Nidulus opens up an internal communication port not just for each API and each service, but one per instance of each API or service. They will always try to claim port 8000, or next available port above 8000.

Example: You create one new API on port 4444. You run this API in 4 instances, and you have 2 services each running 2 instances each.

Firewall setup: You will have to configure your firewall to allow traffic on TCP port 4444, obviously, but also on TCP/UDP ports 8000-8008 for the internal communication to work, or your API will not communicate with your services.

You MUST also allow traffic on UDP port 12345, this is used for the discovery broadcasting/multicasting.

This is valid even when the API and its services reside on the same machine, as they do not communicate on interface 127.0.0.1 (localhost) but on the external interface of the server. The traffic in and out from these communication ports is encrypted.

Network Scaling


What do we mean with network scaling, anyways? We are talking about when the time comes where the solution you built is upholding such high traffic that you need more hardware, but you do not want to take the system down for even a second.


As Nidulus processes automatically know about each other on the local network, all you need to cluster/scale is deploy Nidulus on another machine on the same network. Set the "Security key" on both machines to be identical, and deploy all your services on both machines. You just offloaded the traffic from machine one, to machine two and will now have two machines working together to process your requests.


How this actually works? The APIS in Nidulus will always forward messages to the processes in a round-robin fashion, so every instance on the network will get to process one message each, before it starts over on the first instance. Only required configuration is that the Nidulus instance on all machines that communicate MUST have the same "Security key" as the API machine has.

Backup


Nidulus is very easy to backup. Every deploy and configuration, as well as all logs and statistics, will be saved to ~/.nidulus of the user HOME folder that started Nidulus application. Taking a regular copy of this folder allows you to restore the state at any point by moving the folder to any Linux machine and starting up Nidulus on the machine.

Logging


Nidulus has three different log directories.

~/.nidulus/logs/ contains the logs for the nidulus application it self.

~/.nidulus/user_deploy/apis/<APIname>/logs/ exist for all of the APIs you created and will contain API specific errors.

~/.nidulus/user_deploy/services/<ServiceName>/logs/ exist for all of the features/services you deployed and will contain service specific errors, and your own logging that you write in your code using the logger object. This folder is the same that is downloadable through the management API and the web client GUI in zipped format.


All of these log folders maintain rotating log files. current.log is the file being written to currently. log1.log, log2.log and log3.log are the previous three files that have been written. Nidulus rotates current.log to become log1.log when reaching a filesize of 50Mb. Max size of any log directory is therefor 200Mb.

When log level is set for a specific service, either through management API or the web client GUI, no logging of lower log level will be written to the log files and taking up space.

A good procedure for a production environment is therefor to keep the service log level at the default "Error" level. Only logs of level "Error" and "Critical" will be written, while "Info", "Debug" and "Warning" are left out.

Management API


Nidulus official API documentation. Each Nidulus installation contains its own RESTful API server on port 7734 to manage that particular Nidulus server. The management API allows you to do anything the web client GUI does.


Before running any of the Node.js code examples, make sure you have executed "npm install request" and "npm install util" in the folder you run the scripts from.

Make sure you have the correct client certificate for the machine you are accessing, or any request will fail.


System features

/system/activation/set

Description: Sets the activation code for this machine. Re-using activation code for multiple machines will result in your APIs and Services on both to automatically be disabled/stopped. The machine MUST be allowed (check firewall configurations) to access the activation server at https://nidulus.io:6854

Method: POST

POST Data: { license: <String> }

Returns: { status: "success", message: "updated" }

Returns: { status: "fail", message: <String> }

Example cURL:

 curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "license": "my-activation-code" }' https://192.168.1.58:7734/system/activation/set 

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/activation/set';
let data = { license: 'my-activation code' };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/activation/get

Description: Get the current activation code used for this machine

Method: GET

Returns:{ status: "success", message: { license: <String>, allowed_apis: <Integer>, allowed_services: <Integer> } }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/activation/get

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/activation/get';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/seckey/set

Description: Set the security key for clustered service communication. Key MUST be 16 characters long and MUST be same as any other machines seckey you wish to communicate with. If no services/apis from other machines shall be allowed to call the services on this machine, and apis/services on this machine are not allowed to access services on other machines, set a unique key

Method: POST

POST Data:{ key: <String> }

Returns:{ status: "success", message: "updated" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "key": "supersecret__key" }' https://192.168.1.58:7734/system/seckey/set

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/seckey/set';
let data = { key: 'supersecret__key' };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/seckey/get

Description: Get the current security key for clustered service communication

Method: GET

Returns:{ status: "success", message: { key: <String> } }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/seckey/get

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/seckey/get';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/info

Description: Get information about the system (CPU, MEM, Disk space)

Method: GET

Returns:{ status: "success", message: { cpuUsage: <String>, memfree: <String>, memtotal: <String>, diskfree: <String>, disktotal: <String> } }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/info

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/info';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/stats/:type

Description: Get hourly statistics of type 'inbound', 'outboud', 'errors' for last 3 days

Method: GET

Returns if requested type is 'inbound' or 'outbound': { status: "success", message: { hours: <String[]>, values: <Integer[]> }}

Returns if requested type is 'errors': { status: "success", message: { hours: <String[]>, values: <Integer[]>, services: <String[]> }}

Returns: { status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/stats/errors

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/stats/errors';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

System API processes

/system/process/list/apis

Description: List information about APIs deployed on this machine

Method: GET

Returns:
{ status: "success", message: {
  apis: [
    { name: <String>, port: <Integer>, instances: <Integer>, monit: { memory: <String>, cpu: <String> }, online: <Integer>, offline: <Integer> }
  ]
}}
                                

Returns:

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/process/list/apis

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/process/list/apis';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

System service processes

/system/process/list/services

Description: List information about services deployed on this machine

Method: GET

Returns:
{ status: "success", message: {
  services: [
    { name: <String>, instances: <Integer>, loglevel: <String>, memoryLevel: <Integer>, monit: { memory: <String>, cpu: <String> }, online: <Integer>, offline: <Integer> }
  ]
}}
                                

Returns:

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/process/list/services

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/process/list/services';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/process/stop/:name

Description: Stop a user-process on this machine (Service or API)

Method: GET

Returns: { status: "success", message: "ok" }

Returns: { status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/process/stop/myService

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/process/stop/myService';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/process/start/:name

Description: Start a user-process on this machine (Service or API)

Method: GET

Returns:{ status: "success", message: "ok" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/process/start/myService

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/process/start/myService';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/system/process/restart/:name

Description: Restart a user-process on this machine (Service or API)

Method: GET

Returns:{ status: "success", message: "ok" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/system/process/restart/myService

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/system/process/restart/myService';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

API Configuration

/api/create

Description: Create a new API. Number of instances should not be higher than physical cores dedicated to the virtual machine

Method: POST

POST Data:{ name: <String>, port: <Integer>, instances: <Integer> }

Returns:{ status: "success", message: "Api created" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "name": "myApi", "port": 3434, "instances": 12 }' https://192.168.1.58:7734/api/create

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/create';
let data = { name: 'myApi', port: 3434, instances: 12 };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/api/update/:name/:port

Description: Update an existing API, change port

Method: GET

Returns:{ status: "success", message: "Api updated" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/api/update/myApi/4567

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/update/myApi/4567';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/api/scale/:name/:instances

Description: Scale an existing API, increase/decrease instances. Number of instances should not be higher than physical cores dedicated to the virtual machine

Method: GET

Returns:{ status: "success", message: "Api scaled" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/api/scale/myApi/16

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/scale/myApi/16';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/api/delete/:name

Description: Delete an existing API

Method: GET

Returns:{ status: "success", message: "Api deleted" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/api/delete/myApi

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/delete/myApi';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/api/cert/add

Description: Upload a certificate to an existing API. Must be a base64 encoded zip file containing (in the root of the zip, no subfolders) CA, Server key, Server Cert. Files must be named like the API: myApi.ca, myApi.key, myApi.crt. See Node.js example

Method: POST

POST Data:{ api: <String>, cert: <b64Encoded String>, enforceClientCert: <Boolean> }

Returns:{ status: "success", message: "Cert added" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "api": "myApi", "cert": "XXXXXXXXXXXX", "enforceClientCert": true }' https://192.168.1.58:7734/api/cert/add

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/cert/add';

// myCerificates.zip contains 3x files, no subfolders. Files are named myApi.ca, myApi.key, myApi.crt, like the API they are created to be used with.
// enforceClientCert, if set to true, will deny any access where a correct client-cert is not included. Like this Management API does.

let certZip = fs.readFileSync('./myCerificates.zip');
let b64certZip = new Buffer(certZip).toString('base64');

let data = { api: 'myApi', cert: b64certZip, enforceClientCert: true };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

API Endpoints

/api/endpoint/add

Description: Add a new endpoint to an existing API. datalimit is specified in kilobytes, and timeout in milliseconds. Same path can exist on same API, as long as the method is different (GET/POST/PUT/PATCH/DELETE)

Method: POST

POST Data:{ api: <String>, path: <String>, method: <String>, timeout: <Integer>, datalimit: <Integer>, target_service: <String> }

Returns:{ status: "success", message: "Endpoint added" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "api": "myApi", "path": "/recepies/list/:type", "method": "GET", "timeout": 10000, "datalimit": 10, "target_service": "listRecepies" }' https://192.168.1.58:7734/api/endpoint/add

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/endpoint/add';

let data = { api: 'myApi', path: '/recepies/list/:type', method: 'GET', timeout: 10000, datalimit: 10, target_service: 'listRecepies' };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/api/endpoint/delete

Description: Delete an endpoint from an existing API

Method: POST

POST Data:{ api: <String>, path: <String>, method: <String> }

Returns:{ status: "success", message: "Endpoint deleted" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "api": "myApi", "path": "/recepies/list/:type", "method": "GET" }' https://192.168.1.58:7734/api/endpoint/delete

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/endpoint/delete';

let data = { api: 'myApi', path: '/recepies/list/:type', method: 'GET' };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/api/endpoint/update

Description: Update an endpoint for an existing API

Method: POST

POST Data:{ api: <String>, path: <String>, method: <String>, new_method: <String>, timeout: <Integer>, datalimit: <Integer>, target_service: <String> }

Returns:{ status: "success", message: "Endpoint updated" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "api": "myApi", "path": "/recepies/list/:type", "method": "GET", "new_method": "POST", timeout": 20000, "datalimit": 20, "target_service": "getRecepies" }' https://192.168.1.58:7734/api/endpoint/update

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/endpoint/update';

let data = { api: 'myApi', path: '/recepies/list/:type', method: 'GET', new_method: 'POST', timeout: 20000, datalimit: 20, target_service: 'getRecepies' };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/api/endpoint/list/:api

Description: List all endpoints for an existing API

Method: GET

Returns:{ status: "success", message: [ { api: <String>, path: <String>, method: <String>, timeout: <Integer>, datalimit: <Integer>, target_service: <String> } ] }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/api/endpoint/list/myApi

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/api/endpoint/list/myApi';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                            

Service Configuration

/service/deploy

Description: Deploy a new service. Must be a base64 encoded zip file containing the service folder. See Node.js example. Number of instances should not be higher than physical cores dedicated to the virtual machine

Method: POST

POST Data:{servicename: <String>, file: <b64Encoded String>, instances: <Integer>}

Returns:{ status: "success", message: "Service deployed" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d @myService.json https://192.168.1.58:7734/service/deploy

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/service/deploy';

// We are using the .json file created when we built our service using the build.js in service package

let data = fs.readFileSync('./myService.json').toString();

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/service/update

Description: Update a service. Must be a base64 encoded zip file containing the service folder. See Node.js example.

Method: POST

POST Data:{servicename: <String>, file: <b64Encoded String>}

Returns:{ status: "success", message: "Service updated" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d @myService.json https://192.168.1.58:7734/service/update

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/service/update';

// We are using the .json file created when we built our service using the build.js in service package

let data = fs.readFileSync('./myService.json').toString();

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/service/scale/:name/:instances

Description: Scale an existing service, increase/decrease instances. Number of instances should not be higher than physical cores dedicated to the virtual machine

Method: GET

Returns:{ status: "success", message: "Service scaled" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/service/scale/myService/4

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/service/scale/myService/4';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/service/setloglevel/:name/:level

Description: Update loglevel for an existing service (default is 'error')

Method: GET

Returns:{ status: "success", message: "Log level set" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/service/setloglevel/myService/debug

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/service/setloglevel/myService/debug';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/service/setmemorylevel/:name/:level

Description: Update max old memory for a service process (default is 128Mb)

Method: GET

Returns:{ status: "success", message: "<serviceName>: memory updated" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/service/setmemorylevel/myService/256

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/service/setmemorylevel/myService/256';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/service/delete/:name

Description: Delete an existing service

Method: GET

Returns:{ status: "success", message: "Service deleted" }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/service/delete/myService

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/service/delete/myService';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/service/logs/:name

Description: Download logs for an existing service, as a base64 encoded zip

Method: GET

Returns:{ status: "success", message: { filename: <String>, file: <b64Encoded String> } }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/service/logs/myService

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/service/logs/myService';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

Scheduled jobs

/timer/create

Description: Create a timed trigger for a service. The time is specified in crontab format

Method: POST

POST Data:{ target_service: <String>, time: <String> }

Returns:{ status: "success", message: "Timer added" ] }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X POST -H "Content-Type: application/json" -k --key ./myClientCert.crt --cert ./myClientCert.crt -d '{ "target_service": "myService", "time": "*/5 * * * *" }' https://192.168.1.58:7734/timer/create

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/timer/create';

// Trigger myService every fifth minute. When triggered, all in-data will be empty (headers, params, body). Service must handle this.
let data = { target_service: 'myService', time: '*/5 * * * *' };

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'POST',
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/timer/list

Description: List all timers on this machine

Method: GET

Returns:{ status: "success", message: [ { target_service: <String>, time: <String> } ] }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/timer/list

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/timer/list';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}
                                

/timer/delete/:service

Description: Delete timer for a service

Method: GET

Returns:{ status: "success", message: "Timer deleted" ] }

Returns:{ status: "fail", message: <String> }

Example cURL:

curl -X GET -k --key ./myClientCert.crt --cert ./myClientCert.crt https://192.168.1.58:7734/timer/delete/myService

Example Node.js:

const util = require('util');
const fs = require('fs');
const request = require('request');
const https = require('https');

let agent = new https.Agent({ rejectUnauthorized: false });

let address = '192.168.1.58';
let port = 7734;
let path = '/timer/delete/myService';

let url = util.format('https://%s:%d%s', address, port, path);

let options = {
    url: url,
    key: fs.readFileSync('./myClientCert.crt'),
    cert: fs.readFileSync('./myClientCert.crt'),
    agent: agent,
    method: 'GET'
}

try {
    request(options, function(error, response, body) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.parse(body));
        }
    });
} catch (err) {
    console.log(err);
}