webapi-eca/js/server.js

159 lines
4.8 KiB
JavaScript
Raw Normal View History

/*
2013-11-18 21:53:09 +00:00
* Rules Server
* ============
* >This is the main module that is used to run the whole server:
* >
* > node server [log_type http_port]
* >
* >Valid `log_type`'s are:
* >
* >- `0`: standard I/O output (default)
* >- `1`: log file (server.log)
* >- `2`: silent
* >
* >`http_port` can be set to use another port, than defined in the
* >[config](config.html) file, to listen to, e.g. used by the test suite.
* >
* >---
2013-11-18 21:53:09 +00:00
*/
'use strict';
// Grab all required modules
var path = require('path'),
log = require('./logging'),
conf = require('./config'),
http_listener = require('./http_listener'),
mm = require('./module_manager'),
db = require('./db_interface'),
engine = require('./engine'),
semaphore = 0,
args = {},
2013-11-18 21:53:09 +00:00
procCmds = {},
// Prepare the admin commands that are issued via HTTP requests.
adminCmds = {
'loadrules': mm.loadRulesFromFS,
'loadaction': mm.loadActionModuleFromFS,
'loadactions': mm.loadActionModulesFromFS,
'loadevent': mm.loadEventModuleFromFS,
'loadevents': mm.loadEventModulesFromFS,
'loadusers': http_listener.loadUsers,
'shutdown': shutDown
};
2013-11-18 21:53:09 +00:00
/*
* Error handling of the express port listener requires special attention,
* thus we have to catch the process error, which is issued if
* the port is already in use.
*/
process.on('uncaughtException', function(err) {
switch(err.errno) {
case 'EADDRINUSE':
err.addInfo = 'http_port already in use, shutting down!';
log.error('RS', err);
shutDown();
break;
default: log.error(err);
}
});
2013-11-18 21:53:09 +00:00
/**
* ## Initialize the Server
2013-11-18 21:53:09 +00:00
* This function is invoked right after the module is loaded and starts the server.
*/
function init() {
log.print('RS', 'STARTING SERVER');
2013-11-18 21:53:09 +00:00
// Check whether the config file is ready, which is required to start the server.
if(!conf.isReady()) {
log.error('RS', 'Config file not ready!');
process.exit();
2013-11-18 21:53:09 +00:00
}
// Fetch the `log_type` argument and post a log about which log type is used.
if(process.argv.length > 2) {
2013-11-18 21:53:09 +00:00
args.logType = parseInt(process.argv[2]) || 0;
if(args.logType === 0) log.print('RS', 'Log type set to standard I/O output');
else if(args.logType === 1) log.print('RS', 'Log type set to file output');
else if(args.logType === 2) log.print('RS', 'Log type set to silent');
else log.print('RS', 'Unknown log type, using standard I/O');
log(args);
2013-11-18 21:53:09 +00:00
} else log.print('RS', 'No log method passed, using standard I/O');
2013-11-14 14:06:10 +00:00
2013-11-18 21:53:09 +00:00
// Fetch the `http_port` argument
if(process.argv.length > 3) args.http_port = parseInt(process.argv[3]);
else log.print('RS', 'No HTTP port passed, using standard port from config file');
db(args);
// We only proceed with the initialization if the DB is ready
2013-11-19 12:51:30 +00:00
db.isConnected(function(err, result) {
if(!err) {
// Initialize all required modules with the args object.
log.print('RS', 'Initialzing engine');
engine(args);
log.print('RS', 'Initialzing http listener');
http_listener(args);
log.print('RS', 'Initialzing module manager');
mm(args);
log.print('RS', 'Initialzing DB');
// Distribute handlers between modules to link the application.
log.print('RS', 'Passing handlers to engine');
engine.addDBLinkAndLoadActionsAndRules(db);
log.print('RS', 'Passing handlers to http listener');
http_listener.addHandlers(db, handleAdminCommands, engine.pushEvent);
log.print('RS', 'Passing handlers to module manager');
mm.addHandlers(db, engine.loadActionModule, engine.addRule);
}
2013-11-19 12:51:30 +00:00
});
}
2013-11-14 14:06:10 +00:00
2013-11-18 21:53:09 +00:00
/**
* admin commands handler receives all command arguments and an answerHandler
* object that eases response handling to the HTTP request issuer.
2013-11-18 21:53:09 +00:00
*/
function handleAdminCommands(args, answHandler) {
if(args && args.cmd) {
2013-11-18 21:53:09 +00:00
var func = adminCmds[args.cmd];
if(typeof func == 'function') func(args, answHandler);
} else log.print('RS', 'No command in request');
setTimeout(function(ah) {
return function() {
2013-11-19 17:13:38 +00:00
if(!ah.isAnswered()) ah.answerError('Not handeled...');
};
2013-11-19 17:13:38 +00:00
}(answHandler), 2000);
}
2013-11-18 21:53:09 +00:00
/**
* Shuts down the server.
* @param {Object} args
* @param {Object} answHandler
*/
function shutDown(args, answHandler) {
if(answHandler) answHandler.answerSuccess('Goodbye!');
log.print('RS', 'Received shut down command!');
2013-11-18 21:53:09 +00:00
if(engine) engine.shutDown();
if(http_listener) http_listener.shutDown();
}
2013-11-18 21:53:09 +00:00
/*
* ### Process Commands
*
* When the server is run as a child process, this function handles messages
* from the parent process (e.g. the testing suite)
*/
process.on('message', function(cmd) {
if(typeof procCmds[cmd] === 'function') procCmds[cmd]();
else console.error('err with command');
});
2013-11-18 21:53:09 +00:00
/**
* The die command redirects to the shutDown function.
2013-11-14 14:06:10 +00:00
*/
2013-11-18 21:53:09 +00:00
procCmds.die = shutDown;
/*
* *Start initialization*
*/
init();