const EventEmitter = require('events');
const Basedata = require('../../../models/basedata');
/**
* Class for REST API communication
* @class plugins/inbound/api
* @namespace plugins/inbound/api
* @memberof plugins/inbound/api
*/
class restapi extends EventEmitter {
/**
* Constructor
*
* Sets up everything, starts service REST API
*/
constructor() {
super();
global.plgManager.logger.info('-------- PLUGIN RESTAPI -----------');
this.katsysProcess = null;
this.registerForEvents();
this.serviceProcId = null;
this.loadConfig((success) => {
if (success) {
// set plugin as configured
this.initializePlugin((initsuccess) => {
global.plgManager.logger.debug('PLUGIN | RESTAPI | initialized Plugin: ' + initsuccess);
if (initsuccess) {
this.isConfigured = true;
this.prepareService();
this.wireServiceCommunication();
this.configService();
this.startService();
}
})
}
})
this.basedata = new Basedata(global.plgManager.logger);
}
/**
* Registration of Events at the plugin manager (hook in to events provided by the plugin manager)
*/
registerForEvents() {
global.plgManager.logger.info('PLUGIN | RESTAPI | Registering events');
global.plgManager.on('event_pluginConfig_refreshed', (namespace) => {
if (namespace === 'restapi') {
// plugins config has changed --> refresh
this.loadConfig((success) => {
if (success) {
global.plgManager.logger.info('PLUGIN | RESTAPI | successfully reloaded plugin configuration');
this.restartService();
} else {
global.plgManager.logger.error('PLUGIN | RESTAPI | could not reload plugin config!');
}
});
}
})
}
/**
* Plugin-specific implementation
*/
newFeedback(feedbackInfo) {
global.plgManager.logger.info('PLUGIN | RESTAPI | Recieved new Feedback from REST API');
global.plgManager.event_new_feedback_received(feedbackInfo.operationUUID, feedbackInfo.basedataUUID, feedbackInfo.stateId);
}
/**
* Loads configuration for RESDT API Service
* @memberof plugins/inbound/katsys
*/
loadConfig(callback) {
global.plgManager.loadConfigFromStore('restapi', (configRows) => {
if (configRows !== null) {
this.config = configRows[0];
this.config = JSON.parse(this.config.configstore);
callback(true);
} else {
callback(false);
}
global.plgManager.logger.info('PLUGIN | RESTAPI | Configuration loaded from core database');
})
}
/**
* returns config parameter for given fieldname
* @param {string} fieldname
* @memberof plugins/inbound/api
*/
getConfigValue(fieldname) {
var retVal = null;
this.config.fields.forEach((field) => {
if (field.fieldname === fieldname) {
retVal = field.value;
}
});
return retVal;
}
/**
* reconfigures divera plugin with new config settings
* @param {function} callback success, true or false
* @memberof plugins/inbound/api
*/
initializePlugin(callback) {
// LAU
this.serviceConfig = {
httpPort: this.getConfigValue('httpPort'),
httpsPort: this.getConfigValue('httpsPort'),
runOnHTTPS: this.getConfigValue('runOnHTTPS'),
runOnHTTP: this.getConfigValue('runOnHTTP'),
loglevel: 'debug'
}
if ((typeof this.serviceConfig.httpPort !== 'undefined') && (typeof this.serviceConfig.runOnHTTP !== 'undefined') || (typeof this.serviceConfig.httpsPort !== 'undefined') && (typeof this.serviceConfig.runOnHTTPS !== 'undefined')) {
global.plgManager.logger.info('PLUGIN | RESTAPI | Properly inititlized settings');
callback(true);
} else {
global.plgManager.logger.error('PLUGIN | RESTAPI | could not initialize settings');
callback(false);
}
}
/**
* Wires messages from service to event model of plugin
* All Messages in service need to be wired here to be recognised in plugin
* @memberof plugins/inbound/api
*/
wireServiceCommunication() {
this.serviceProcess.on('message', function (msg) {
var payload = [];
try {
payload = JSON.parse(msg);
} catch (err) {
payload = [];
}
if (typeof payload.logmessage != 'undefined') {
msg = payload.logmessage;
}
console.log('PLUGIN | RESTAPI | SERVICE | ' + msg);
var payload = null;
try {
payload = JSON.parse(msg);
} catch (err) {
payload = err.message;
}
if (typeof payload.feedbackState != 'undefined') {
var basedataUUID = payload.feedbackState.basedataUUID;
var operationUUID = payload.feedbackState.operationUUID;
var feedbackState = payload.feedbackState.feedbackState;
global.plgManager.event_new_feedback_received(operationUUID, basedataUUID, feedbackState);
global.plgManager.logger.info('PLUGIN | RESTAPI | SERVICE | Sending new Feedback to PluginManager');
} else if (typeof payload.newDeviceRegistered != 'undefined') {
var basedataId = payload.newDeviceRegistered.basedataId;
var deviceName = payload.newDeviceRegistered.deviceName;
var deviceModel = payload.newDeviceRegistered.deviceModel;
var devicePlatform = payload.newDeviceRegistered.devicePlatform;
var deviceOsVersion = payload.newDeviceRegistered.deviceOsVersion;
var deviceUUID = payload.newDeviceRegistered.deviceUUID;
this.basedata.getBaseDataForId(basedataId, (basedataRows) => {
if (basedataRows != null){
basedataRows.forEach((entry)=> {
var message = "Es wurde ein neues Gerät \'"+ deviceName +"\' ("+devicePlatform+") von " + entry.lastname + " " + entry.firstname + " hinzugefügt";
global.plgManager.event_new_admin_notification(message);
global.plgManager.logger.info('PLUGIN | RESTAPI | SERVICE | Sending admin notification for new device to PluginManager');
})
}
});
} else if (typeof payload.logmessage != 'undefined') {
global.plgManager.logger.info('PLUGIN | RESTAPI | SERVICE | ' + payload.logmessage);
} else if (typeof payload.error != 'undefined') {
// child has sent an error
// try restarting the whole service
global.plgManager.event_new_admin_notification('RESTAPI Service meldet einen Fehler');
this.restartService();
}
if (typeof payload.logmessage != 'undefined') {
global.plgManager.logger.info('PLUGIN | RESTAPI | SERVICE | ' + payload.logmessage);
} else if (typeof payload.event != 'undefined') {
// service send structured data
if (payload.event.event === 'event_new_feedback') {
var message = payload.event.feedback;
console.log('PLUGIN | RESTAPI | SERVICE | NEW FEEDBACK');
global.plgManager.logger.info('PLUGIN | RESTAPI | SERVICE | NEW FEEDBACK');
//this.event_new_feedback_received()
} else if (payload.event.event === 'error') {
console.log('PLUGIN | RESTAPI | SERVICE | ERROR');
global.plgManager.logger.info('PLUGIN | RESTAPI | SERVICE | ERROR ' + JSON.stringify(payload.event.error));
global.plgManager.event_new_admin_notification('REST API Fehler: ' + JSON.stringify(payload.event.error));
this.restartService();
}
} else {
global.plgManager.logger.info('PLUGIN | RESTAPI | SERVICE | UNSOLICITED MESSAGE: ' + msg);
}
}.bind(this));
}
/**
* Creates the service as a seperate node-process (fork)
* sets the serviceProcId of the forked process
* @memberof plugins/inbound/api
*/
prepareService() {
global.plgManager.logger.info('PLUGIN | RESTAPI | Starting Service');
const { fork } = require('child_process');
this.serviceProcess = fork(__dirname + '/app.js');
this.serviceProcId = this.serviceProcess.pid;
this.serviceProcess.title = 'ALARMiator Plugin - REST API';
global.plgManager.logger.info('PLUGIN | RESTAPI | Service started with pid ' + this.serviceProcId);
this.serviceProcess.on('exit', function (code) {
this.serviceProcess = null;
console.log("RESTAPI Service EXITED " + code);
});
}
/**
* Sends the service configuration to the process
*/
configService() {
this.serviceProcess.send({ config: this.serviceConfig });
}
/**
* tells the service to connect
*/
startService() {
this.serviceProcess.send({ start: 1 });
}
/**
* restarts the Service
*/
restartService() {
global.plgManager.logger.info('PLUGIN | RESTAPI | restart Service...');
if (this.serviceProcess !== null) {
global.plgManager.logger.info('PLUGIN | RESTAPI | Killing Service...');
this.serviceProcess.kill("SIGHUP");
}
this.initializePlugin((initsuccess) => {
global.plgManager.logger.debug('PLUGIN | RESTAPI | initialized Plugin: ' + initsuccess);
if (initsuccess) {
this.isConfigured = true;
this.prepareService();
this.wireServiceCommunication();
this.configService();
this.startService();
}
})
}
}
module.exports = restapi;