From 8c115aa71d5127fc715327364a0da97065d296aa Mon Sep 17 00:00:00 2001 From: Dominic Bosch Date: Wed, 20 Nov 2013 15:41:41 +0100 Subject: [PATCH] What a wonderful detour over docco, only to recognize that it was always possible to auto generate documentation. ... if one would just define the correct folder... at least deep knowledge about docco now, plus that it doesn't use glob (leaves it a user task...) while groc does use glob to resolve file paths, yay! --- LICENSE.js | 25 ------- LICENSE.md | 22 ++++++ README.md | 11 ++- coffee/config.coffee | 73 +++++++++++++++++++ coffee/server.coffee | 113 +++++++++++++++++------------ create_doc.js | 39 ++++++++-- js-coffee/config.js | 167 +++++++++++++++++++++++++------------------ js-coffee/server.js | 94 ++++++++++++++---------- js/config.js | 1 - js/server.js | 101 ++++++++++++++------------ package.json | 3 + 11 files changed, 413 insertions(+), 236 deletions(-) delete mode 100644 LICENSE.js create mode 100644 LICENSE.md create mode 100644 coffee/config.coffee diff --git a/LICENSE.js b/LICENSE.js deleted file mode 100644 index 0ff9e3e..0000000 --- a/LICENSE.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * LICENSE - * ======= - * Copyright (c) 2013 by Dominic Bosch and The - * Regents of the University of Basel. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE UNIVERSITY OF BASEL BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF - * BASEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF BASEL SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF BASEL HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Authors: Dominic Bosch - * - */ \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..ab46d53 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,22 @@ +LICENSE +======= +Copyright (c) 2013 by Dominic Bosch and The +Regents of the University of Basel. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without written agreement is +hereby granted, provided that the above copyright notice and the following +two paragraphs appear in all copies of this software. + +IN NO EVENT SHALL THE UNIVERSITY OF BASEL BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT +OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF +BASEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF BASEL SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF BASEL HAS NO OBLIGATION TO +PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Authors: Dominic Bosch diff --git a/README.md b/README.md index cdddfb3..75766ad 100644 --- a/README.md +++ b/README.md @@ -17,25 +17,24 @@ Prerequisites: - node.js & npm (find it [here](http://nodejs.org/)) - *(optional) coffee, if you want to compile from coffee sources:* - sudo npm -g install coffee-script + sudo npm -g install coffee-script Clone project: - git clone https://github.com/dominicbosch/webapi-eca.git + git clone https://github.com/dominicbosch/webapi-eca.git Download and install dependencies: cd webapi-eca npm install -Get your [redis](http://redis.io/) instance up and running (and find the port for the config file below) or create your own `db_interface.js`. +Get your [redis](http://redis.io/) instance up and running (and find the port for the config file below) or create your own `js/db_interface.js`. -Create the configuration file: +Edit the configuration file: - mkdir config vi config/config.json -Insert your settings, for example: +Apply your settings, for example: { "http_port": 8125, diff --git a/coffee/config.coffee b/coffee/config.coffee new file mode 100644 index 0000000..c6e9166 --- /dev/null +++ b/coffee/config.coffee @@ -0,0 +1,73 @@ +'use strict' + +path = require 'path' +log = require './logging' +fs = require 'fs' +config = null + + +### +Calling the module as a function will make it look for the `relPath` property in the +args object and then try to load a config file from that relative path. +@param {Object} args +### +exports = module.exports = (args) -> + args = args ? {} + log args + if typeof args.relPath is 'string' + loadConfigFiles args.relPath + module.exports + +### +@Function loadConfigFile + +Tries to load a configuration file from the path relative to this module's parent folder. +@param {String} relPath +### +loadConfigFile = (relPath) -> + try + ### We read the config file synchronously from the file system and try to parse it ### + config = JSON.parse fs.readFileSync path.resolve __dirname, '..', relPath + if config and config.http_port and config.db_port and + config.crypto_key and config.session_secret + log.print 'CF', 'config file loaded successfully' + else + log.error 'CF', new Error("""Missing property in config file, requires: + - http_port + - db_port + - crypto_key + - session_secret""") + catch e + e.addInfo = 'no config ready' + log.error 'CF', e + +loadConfigFile path.join('config', 'config.json') + +### Answer true if the config file is ready, else false ### +exports.isReady = -> config? + +### +Fetch a property from the configuration +@param {String} prop +### +fetchProp = (prop) -> config?[prop] + +### +Get the HTTP port +### +exports.getHttpPort = -> fetchProp 'http_port' + +### +Get the DB port +### +exports.getDBPort = -> fetchProp 'db_port' + +### +Get the crypto key +### +exports.getCryptoKey = -> fetchProp 'crypto_key' + +### +Get the session secret +### +exports.getSessionSecret = -> fetchProp 'session_secret' diff --git a/coffee/server.coffee b/coffee/server.coffee index 6c21144..282f575 100644 --- a/coffee/server.coffee +++ b/coffee/server.coffee @@ -2,23 +2,25 @@ ### 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. +>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. +> +>--- ### 'use strict' - +### Grab all required modules ### path = require 'path' log = require './logging' conf = require './config' @@ -28,8 +30,9 @@ http_listener = require './http_listener' mm = require './module_manager' args = {} procCmds = {} -### Prepare the admin commands that are issued via HTTP requests. ### -adminCmds = { + +### Prepare the admin commands that are issued via HTTP requests. ### +adminCmds = 'loadrules': mm.loadRulesFromFS, 'loadaction': mm.loadActionModuleFromFS, 'loadactions': mm.loadActionModulesFromFS, @@ -37,7 +40,7 @@ adminCmds = { 'loadevents': mm.loadEventModulesFromFS, 'loadusers': http_listener.loadUsers, 'shutdown': shutDown -}; + ### Error handling of the express port listener requires special attention, @@ -53,7 +56,6 @@ process.on 'uncaughtException', (err) -> else log.error err null - ### ## Initialize the Server This function is invoked right after the module is loaded and starts the server. @@ -61,11 +63,13 @@ This function is invoked right after the module is loaded and starts the server. init = -> log.print 'RS', 'STARTING SERVER' + + ### 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 + process.exit() - ### Fetch the `log_type` argument and post a log about which log type is used. ### + ### Fetch the `log_type` argument and post a log about which log type is used.### if process.argv.length > 2 args.logType = parseInt(process.argv[2]) || 0 switch args.logType @@ -73,48 +77,63 @@ init = -> when 1 then log.print 'RS', 'Log type set to file output' when 2 then log.print 'RS', 'Log type set to silent' else log.print 'RS', 'Unknown log type, using standard I/O' - log(args); + log args else log.print 'RS', 'No log method argument provided, using standard I/O' ### Fetch the `http_port` argument ### - if process.argv.length > 3 then args.http_port = parseInt(process.argv[3]); + if process.argv.length > 3 then args.http_port = parseInt process.argv[3] else log.print 'RS', 'No HTTP port passed, using standard port from config file' - ### Initialize all required modules with the args object. ### db args - db.isConnected((err, result) -> if !err then continueInit()) + ### We only proceed with the initialization if the DB is ready ### + db.isConnected (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' -continueInit = -> - 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 - null + ### 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 ### admin commands handler receives all command arguments and an answerHandler object that eases response handling to the HTTP request issuer. ### - handleAdminCommands = (args, answHandler) -> - if args and args.cmd then adminCmds[args.cmd]?(args, answHandler) - else log.print 'RS', 'No command in request' - fAnsw = (ah) -> -> - if not ah.isAnswered() then answHandler.answerError 'Not handled...' + if args and args.cmd + adminCmds[args.cmd]? args, answHandler + else + log.print 'RS', 'No command in request' + + ### + The fAnsw function receives an answerHandler object as an argument when called + and returns an anonymous function + ### + fAnsw = (ah) -> + ### + The anonymous function checks whether the answerHandler was already used to + issue an answer, if no answer was provided we answer with an error message + ### + () -> + if not ah.isAnswered() + ah.answerError 'Not handled...' + + ### + Delayed function call of the anonymous function that checks the answer handler + ### setTimeout fAnsw(answHandler), 2000 - null ### Shuts down the server. @@ -133,11 +152,13 @@ shutDown = (args, answHandler) -> 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', (cmd) -> procCmds[cmd]?() ### The die command redirects to the shutDown function. ### + procCmds.die = shutDown ### diff --git a/create_doc.js b/create_doc.js index 21815a0..c6df08f 100644 --- a/create_doc.js +++ b/create_doc.js @@ -1,13 +1,44 @@ + +/* + * # docco Documentation + * Create the documentation to be displayed through the webserver. + */ +// var glob = require("glob"), + // docco = require('docco'), + // opt = ["", "", "--output", "webpages/doc"], + // files = [ + // "README.md", + // "LICENSE.md", + // "create_doc.js", + // "coffee/*.coffee", + // "mod_actions/**/*.js", + // "mod_events/**/*.js" + // ]; +// +// var semaphore = files.length; +// for(var i = 0; i < files.length; i++) { + // glob(files[i], null, function (er, files) { + // if(!er) { + // opt = opt.concat(files); + // } else { + // console.error(er); + // } + // if(--semaphore === 0) { + // docco.run(opt); + // } + // }); +// } + /* * # groc Documentation * Create the documentation to be displayed through the webserver. - */ + */ +// require('groc').CLI( [ "README.md", - "TODO.js", - "LICENSE.js", - "js-coffee/*", + "LICENSE.md", + "coffee/*.coffee", "mod_actions/**/*.js", "mod_events/**/*.js", "-o./webpages/doc" diff --git a/js-coffee/config.js b/js-coffee/config.js index 7e1f138..1957edb 100644 --- a/js-coffee/config.js +++ b/js-coffee/config.js @@ -1,80 +1,111 @@ -'use strict'; +// Generated by CoffeeScript 1.6.3 +(function() { + 'use strict'; + var config, exports, fetchProp, fs, loadConfigFile, log, path; -var path = require('path'), - log = require('./logging'), - config; + path = require('path'); -exports = module.exports = function(args) { - args = args || {}; - log(args); - if(typeof args.relPath === 'string') loadConfigFile(args.relPath); - //TODO check all modules whether they can be loaded without calling the module.exports with args - return module.exports; -}; + log = require('./logging'); -loadConfigFile(path.join('config', 'config.json')); + fs = require('fs'); -function loadConfigFile(relPath) { - try { - config = JSON.parse(require('fs').readFileSync(path.resolve(__dirname, '..', relPath))); - if(config && config.http_port && config.db_port - && config.crypto_key && config.session_secret) { - log.print('CF', 'config file loaded successfully!'); - } else { - log.error('CF', new Error('Missing property in config file, requires:\n' - + ' - http_port\n' - + ' - db_port\n' - + ' - crypto_key\n' - + ' - session_secret')); + config = null; + + /* + Calling the module as a function will make it look for the `relPath` property in the + args object and then try to load a config file from that relative path. + @param {Object} args + */ + + + exports = module.exports = function(args) { + args = args != null ? args : {}; + log(args); + if (typeof args.relPath === 'string') { + loadConfigFiles(args.relPath); } - } catch (e) { - e.addInfo = 'no config ready'; - log.error('CF', e); - } -} + return module.exports; + }; -/** - * Answer true if the config file is ready, else false - */ -exports.isReady = function() { - if(config) return true; - else return false; -}; + /* + @Function loadConfigFile + + Tries to load a configuration file from the path relative to this module's parent folder. + @param {String} relPath + */ -/** - * Fetch a property from the configuration - * @param {String} prop - */ -function fetchProp(prop) { - if(config) return config[prop]; -} -/** - * Get the HTTP port - */ -exports.getHttpPort = function() { - return fetchProp('http_port'); -}; + loadConfigFile = function(relPath) { + var e; + try { + /* We read the config file synchronously from the file system and try to parse it*/ -/** - * Get the DB port - */ -exports.getDBPort = function() { - return fetchProp('db_port'); -}; + config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', relPath))); + if (config && config.http_port && config.db_port && config.crypto_key && config.session_secret) { + return log.print('CF', 'config file loaded successfully'); + } else { + return log.error('CF', new Error("Missing property in config file, requires:\n- http_port\n- db_port\n- crypto_key\n- session_secret")); + } + } catch (_error) { + e = _error; + e.addInfo = 'no config ready'; + return log.error('CF', e); + } + }; -/** - * Get the crypto key - */ -exports.getCryptoKey = function() { - return fetchProp('crypto_key'); -}; + loadConfigFile(path.join('config', 'config.json')); -/** - * Get the session secret - */ -exports.getSessionSecret = function() { - return fetchProp('session_secret'); -}; + /* Answer true if the config file is ready, else false*/ - \ No newline at end of file + + exports.isReady = function() { + return config != null; + }; + + /* + Fetch a property from the configuration + @param {String} prop + */ + + + fetchProp = function(prop) { + return config != null ? config[prop] : void 0; + }; + + /* + Get the HTTP port + */ + + + exports.getHttpPort = function() { + return fetchProp('http_port'); + }; + + /* + Get the DB port + */ + + + exports.getDBPort = function() { + return fetchProp('db_port'); + }; + + /* + Get the crypto key + */ + + + exports.getCryptoKey = function() { + return fetchProp('crypto_key'); + }; + + /* + Get the session secret + */ + + + exports.getSessionSecret = function() { + return fetchProp('session_secret'); + }; + +}).call(this); diff --git a/js-coffee/server.js b/js-coffee/server.js index 8682606..ea31f4e 100644 --- a/js-coffee/server.js +++ b/js-coffee/server.js @@ -2,24 +2,28 @@ /* 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. +>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. +> +>--- */ (function() { 'use strict'; - var adminCmds, args, conf, continueInit, db, engine, handleAdminCommands, http_listener, init, log, mm, path, procCmds, shutDown; + /* Grab all required modules*/ + + var adminCmds, args, conf, db, engine, handleAdminCommands, http_listener, init, log, mm, path, procCmds, shutDown; path = require('path'); @@ -80,9 +84,11 @@ Valid `log_type`'s are: init = function() { log.print('RS', 'STARTING SERVER'); + /* 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; + process.exit(); } /* Fetch the `log_type` argument and post a log about which log type is used.*/ @@ -112,35 +118,32 @@ Valid `log_type`'s are: } else { log.print('RS', 'No HTTP port passed, using standard port from config file'); } - /* Initialize all required modules with the args object.*/ - db(args); + /* We only proceed with the initialization if the DB is ready*/ + return db.isConnected(function(err, result) { if (!err) { - return continueInit(); + /* 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'); + return mm.addHandlers(db, engine.loadActionModule, engine.addRule); } }); }; - continueInit = function() { - 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); - return null; - }; - /* admin commands handler receives all command arguments and an answerHandler object that eases response handling to the HTTP request issuer. @@ -156,15 +159,28 @@ Valid `log_type`'s are: } else { log.print('RS', 'No command in request'); } + /* + The fAnsw function receives an answerHandler object as an argument when called + and returns an anonymous function + */ + fAnsw = function(ah) { + /* + The anonymous function checks whether the answerHandler was already used to + issue an answer, if no answer was provided we answer with an error message + */ + return function() { if (!ah.isAnswered()) { - return answHandler.answerError('Not handled...'); + return ah.answerError('Not handled...'); } }; }; - setTimeout(fAnsw(answHandler), 2000); - return null; + /* + Delayed function call of the anonymous function that checks the answer handler + */ + + return setTimeout(fAnsw(answHandler), 2000); }; /* diff --git a/js/config.js b/js/config.js index 7e1f138..8ba3402 100644 --- a/js/config.js +++ b/js/config.js @@ -8,7 +8,6 @@ exports = module.exports = function(args) { args = args || {}; log(args); if(typeof args.relPath === 'string') loadConfigFile(args.relPath); - //TODO check all modules whether they can be loaded without calling the module.exports with args return module.exports; }; diff --git a/js/server.js b/js/server.js index f545f6b..0bf4d15 100644 --- a/js/server.js +++ b/js/server.js @@ -1,27 +1,44 @@ /* * 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. + * >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. + * > + * >--- */ '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 = {}, procCmds = {}, - adminCmds, http_listener, mm, db, engine; + // 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 + }; /* * Error handling of the express port listener requires special attention, @@ -40,15 +57,15 @@ process.on('uncaughtException', function(err) { }); /** - * ### Initialize the Server + * ## Initialize the Server * This function is invoked right after the module is loaded and starts the server. */ function init() { log.print('RS', 'STARTING SERVER'); // Check whether the config file is ready, which is required to start the server. - if(!require('./config').isReady()) { + if(!conf.isReady()) { log.error('RS', 'Config file not ready!'); - return; + process.exit(); } // Fetch the `log_type` argument and post a log about which log type is used. @@ -65,41 +82,31 @@ function init() { 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'); - // Initialize all required modules with the args object. - db = require('./db_interface')(args); + db(args); + // We only proceed with the initialization if the DB is ready db.isConnected(function(err, result) { - if(!err) continueInit(); + 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); + } }); } -function continueInit() { - log.print('RS', 'Initialzing engine'); - engine = require('./engine')(args); - log.print('RS', 'Initialzing http listener'); - http_listener = require('./http_listener')(args); - log.print('RS', 'Initialzing module manager'); - mm = require('./module_manager')(args); - log.print('RS', 'Initialzing DB'); - - // Load 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 - }; - - // 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); -} /** * admin commands handler receives all command arguments and an answerHandler diff --git a/package.json b/package.json index 6e03f62..cef5541 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ }, "dependencies": { "connect-redis": "1.4.6", + "docco": "0.6.2", "express": "3.4.0", + "glob" :"3.2.7", "groc": "0.6.1", "needle": "0.6.1", "nodeunit": "0.8.2", @@ -19,6 +21,7 @@ }, "__comment": { "dependencies": { + "groc": "0.6.1", "diff": "1.0.5", "socket.io": "0.9.16", "contextify": "0.1.6"