From f35aa5a285ff709e41d6bf50c70bdb6c93b3cbcd Mon Sep 17 00:00:00 2001 From: Dominic Bosch Date: Mon, 24 Feb 2014 13:20:25 +0100 Subject: [PATCH] Finally a running version again, event pollers aren't dealt with yet though --- coffee/components-manager.coffee | 157 +--------- coffee/dynamic-modules.coffee | 11 +- coffee/request-handler.coffee | 2 +- coffee/webapi-eca.coffee | 12 +- js-coffee/components-manager.js | 24 +- js-coffee/dynamic-modules.js | 7 +- js-coffee/engine.js | 279 +++++++++--------- js-coffee/event-poller.js | 4 +- js-coffee/request-handler.js | 2 +- js-coffee/webapi-eca.js | 18 +- webpages/handlers/coffee/error.coffee | 8 + webpages/handlers/coffee/forge_event.coffee | 5 +- webpages/handlers/coffee/forge_rule.coffee | 7 +- webpages/handlers/js/error.js | 14 + webpages/handlers/js/forge_event.js | 7 +- webpages/handlers/js/forge_rule.js | 7 +- webpages/handlers/templates/error.html | 0 .../templates/forge_action_invoker.html | 3 +- 18 files changed, 233 insertions(+), 334 deletions(-) create mode 100644 webpages/handlers/coffee/error.coffee create mode 100644 webpages/handlers/js/error.js create mode 100644 webpages/handlers/templates/error.html diff --git a/coffee/components-manager.coffee b/coffee/components-manager.coffee index d03a490..e70b6d3 100644 --- a/coffee/components-manager.coffee +++ b/coffee/components-manager.coffee @@ -40,8 +40,8 @@ exports = module.exports = ( args ) => exports.addListener = ( evt, eh ) => @ee.addListener evt, eh - #TODO as soon as an event handler is added it needs to receive the - #full list of existing and activated rules + db.getRules ( err, obj ) => + @ee.emit 'init', rule for id, rule of obj # cb ( obj ) where obj should contain at least the HTTP response code and a message @@ -153,7 +153,6 @@ commandFunctions = forge_rule: ( user, obj, cb ) => obj.event = JSON.parse obj.event - console.log obj db.getRule obj.id, ( err, objRule ) => if objRule isnt null answ = @@ -165,159 +164,15 @@ commandFunctions = message: 'Rule stored and activated!' rule = id: obj.id + # users: [ user.username ] # This should be fetched from the db in each listener event: "#{ obj.event.module } -> #{ obj.event.function }" conditions: JSON.parse obj.conditions actions: JSON.parse obj.actions - console.log rule - modules = JSON.parse obj.event.action_params - console.log 'store rule' + modules = JSON.parse obj.action_params db.storeRule rule.id, JSON.stringify rule - console.log 'link rule' db.linkRule rule.id, user.username - console.log 'activate rule' db.activateRule rule.id, user.username - console.log 'store event params' db.storeEventUserParams obj.event.module, user.username, obj.event_params - console.log 'store action params' - db.storeActionUserParams id, user.username, params for id, params of modules - #TODO implement ID approach, check for existing - - @ee.emit 'newRule', rule + db.storeActionUserParams id, user.username, JSON.stringify params for id, params of modules + @ee.emit 'newRule', JSON.stringify rule cb answ - -# exports.loadModule = function(directory, name, callback) { -# try { -# fs.readFile(path.resolve(__dirname, '..', directory, name, name + '.js'), 'utf8', function (err, data) { -# if (err) { -# log.error('LM', 'Loading module file!'); -# return; -# } -# var mod = exports.requireFromString(data, name, directory); -# if(mod && fs.existsSync(path.resolve(__dirname, '..', directory, name, 'credentials.json'))) { -# fs.readFile(path.resolve(__dirname, '..', directory, name, 'credentials.json'), 'utf8', function (err, auth) { -# if (err) { -# log.error('LM', 'Loading credentials file for "' + name + '"!'); -# callback(name, data, mod, null); -# return; -# } -# if(mod.loadCredentials) mod.loadCredentials(JSON.parse(auth)); -# callback(name, data, mod, auth); -# }); -# } else { -# // Hand back the name, the string contents and the compiled module -# callback(name, data, mod, null); -# } -# }); -# } catch(err) { -# log.error('LM', 'Failed loading module "' + name + '"'); -# } -# }; - -# exports.loadModules = function(directory, callback) { -# fs.readdir(path.resolve(__dirname, '..', directory), function (err, list) { -# if (err) { -# log.error('LM', 'loading modules directory: ' + err); -# return; -# } -# log.info('LM', 'Loading ' + list.length + ' modules from "' + directory + '"'); -# list.forEach(function (file) { -# fs.stat(path.resolve(__dirname, '..', directory, file), function (err, stat) { -# if (stat && stat.isDirectory()) { -# exports.loadModule(directory, file, callback); -# } -# }); -# }); -# }); -# }; - - -# exports.storeEventModule = function (objUser, obj, answHandler) { -# try { -# // TODO in the future we might want to link the modules close to the user -# // and allow for e.g. private modules -# // we need a child process to run this code and kill it after invocation -# var m = exports.requireFromString(obj.data, obj.id); -# obj.methods = Object.keys(m); -# answHandler.answerSuccess('Thank you for the event module!'); -# db.storeEventModule(obj.id, obj); -# } catch (err) { -# answHandler.answerError(err.message); -# console.error(err); -# } -# }; - -# exports.getAllEventModules = function ( objUser, obj, answHandler ) { -# db.getEventModules(function(err, obj) { -# if(err) answHandler.answerError('Failed fetching event modules: ' + err.message); -# else answHandler.answerSuccess(obj); -# }); -# }; - -# exports.storeActionModule = function (objUser, obj, answHandler) { -# var m = exports.requireFromString(obj.data, obj.id); -# obj.methods = Object.keys(m); -# answHandler.answerSuccess('Thank you for the action module!'); -# db.storeActionModule(obj.id, obj); -# }; - -# exports.getAllActionModules = function ( objUser, obj, answHandler ) { -# db.getActionModules(function(err, obj) { -# if(err) answHandler.answerError('Failed fetching action modules: ' + err.message); -# else answHandler.answerSuccess(obj); -# }); -# }; - -# exports.storeRule = function (objUser, obj, answHandler) { -# //TODO fix, twice same logic -# var cbEventModule = function (lstParams) { -# return function(err, data) { -# if(err) { -# err.addInfo = 'fetching event module'; -# log.error('MM', err); -# } -# if(!err && data) { -# if(data.params) { -# lstParams.eventmodules[data.id] = data.params; -# } -# } -# if(--semaphore === 0) answHandler.answerSuccess(lstParams); -# }; -# }; -# var cbActionModule = function (lstParams) { -# return function(err, data) { -# if(err) { -# err.addInfo = 'fetching action module'; -# log.error('MM', err); -# } -# if(!err && data) { -# if(data.params) { -# lstParams.actionmodules[data.id] = data.params; -# } -# } -# if(--semaphore === 0) answHandler.answerSuccess(lstParams); -# }; -# }; - -# var semaphore = 1; -# var lst = { -# eventmodules: {}, -# actionmodules: {} -# }; -# try { -# var objRule = JSON.parse(obj.data); -# for(var i = 0; i < objRule.actions.length; i++) { -# semaphore++; -# db.getActionModule(objRule.actions[i].module.split('->')[0], cbActionModule(lst)); -# } -# db.getEventModule(objRule.event.split('->')[0], cbEventModule(lst)); -# db.storeRule(objRule.id, objUser.username, obj.data); -# ee.emit('newRule', objRule); -# // for( var i = 0; i < eventHandlers.length; i++ ) { -# // eventHandlers[i]( objRule ); -# // } -# } catch(err) { -# answHandler.answerError(err.message); -# log.error('MM', err); -# } - -# }; diff --git a/coffee/dynamic-modules.coffee b/coffee/dynamic-modules.coffee index c60afe6..95f302e 100644 --- a/coffee/dynamic-modules.coffee +++ b/coffee/dynamic-modules.coffee @@ -41,7 +41,8 @@ exports.compileString = ( src, id, params, lang ) => answ = code: 200 message: 'Successfully compiled' - src = "'use strict;'\n" + src + + # src = "'use strict;'\n" + src if lang is '0' try src = cs.compile src @@ -49,13 +50,13 @@ exports.compileString = ( src, id, params, lang ) => answ.code = 400 answ.message = 'Compilation of CoffeeScript failed at line ' + err.location.first_line - #FIXME not log but debug module is required to provide information to the user sandbox = id: id params: params needle: needle - log: @log + log: console.log + # console: console #TODO remove! exports: {} #TODO child_process to run module! #Define max runtime per loop as 10 seconds, after that the child will be killed @@ -64,8 +65,10 @@ exports.compileString = ( src, id, params, lang ) => try vm.runInNewContext src, sandbox, id + '.vm' catch err + console.log err answ.code = 400 answ.message = 'Loading Module failed: ' + err.message ret = answ: answ - module: sandbox.exports \ No newline at end of file + module: sandbox.exports + ret \ No newline at end of file diff --git a/coffee/request-handler.coffee b/coffee/request-handler.coffee index 1f2fa5c..93479a1 100644 --- a/coffee/request-handler.coffee +++ b/coffee/request-handler.coffee @@ -67,7 +67,7 @@ exports.handleEvent = ( req, resp ) -> body += data req.on 'end', -> if req.session and req.session.user - obj = qs.parse body + obj = JSON.parse body # If required event properties are present we process the event # if obj and obj.event timestamp = ( new Date ).toISOString() diff --git a/coffee/webapi-eca.coffee b/coffee/webapi-eca.coffee index cfefab2..d322652 100644 --- a/coffee/webapi-eca.coffee +++ b/coffee/webapi-eca.coffee @@ -159,10 +159,18 @@ init = => # from engine and event poller @log.info 'RS | Initialzing module manager' cm args + cm.addListener 'init', ( evt ) -> + poller.send + event: 'init' + data:evt cm.addListener 'newRule', ( evt ) -> - poller.send evt + poller.send + event: 'newRule' + data:evt + cm.addListener 'init', ( evt ) -> + engine.internalEvent 'init', evt cm.addListener 'newRule', ( evt ) -> - engine.internalEvent evt + engine.internalEvent 'newRule', evt @log.info 'RS | Initialzing http listener' # The request handler passes certain requests to the module manager diff --git a/js-coffee/components-manager.js b/js-coffee/components-manager.js index 32ef44d..7f02cbd 100644 --- a/js-coffee/components-manager.js +++ b/js-coffee/components-manager.js @@ -43,7 +43,16 @@ Components Manager }; exports.addListener = function(evt, eh) { - return _this.ee.addListener(evt, eh); + _this.ee.addListener(evt, eh); + return db.getRules(function(err, obj) { + var id, rule, _results; + _results = []; + for (id in obj) { + rule = obj[id]; + _results.push(_this.ee.emit('init', rule)); + } + return _results; + }); }; exports.processRequest = function(user, obj, cb) { @@ -202,7 +211,6 @@ Components Manager }, forge_rule: function(user, obj, cb) { obj.event = JSON.parse(obj.event); - console.log(obj); return db.getRule(obj.id, function(err, objRule) { var answ, id, modules, params, rule; if (objRule !== null) { @@ -221,22 +229,16 @@ Components Manager conditions: JSON.parse(obj.conditions), actions: JSON.parse(obj.actions) }; - console.log(rule); - modules = JSON.parse(obj.event.action_params); - console.log('store rule'); + modules = JSON.parse(obj.action_params); db.storeRule(rule.id, JSON.stringify(rule)); - console.log('link rule'); db.linkRule(rule.id, user.username); - console.log('activate rule'); db.activateRule(rule.id, user.username); - console.log('store event params'); db.storeEventUserParams(obj.event.module, user.username, obj.event_params); - console.log('store action params'); for (id in modules) { params = modules[id]; - db.storeActionUserParams(id, user.username, params); + db.storeActionUserParams(id, user.username, JSON.stringify(params)); } - _this.ee.emit('newRule', rule); + _this.ee.emit('newRule', JSON.stringify(rule)); } return cb(answ); }); diff --git a/js-coffee/dynamic-modules.js b/js-coffee/dynamic-modules.js index 6cfa83b..27876fc 100644 --- a/js-coffee/dynamic-modules.js +++ b/js-coffee/dynamic-modules.js @@ -51,7 +51,6 @@ Dynamic Modules code: 200, message: 'Successfully compiled' }; - src = "'use strict;'\n" + src; if (lang === '0') { try { src = cs.compile(src); @@ -65,20 +64,22 @@ Dynamic Modules id: id, params: params, needle: needle, - log: _this.log, + log: console.log, exports: {} }; try { vm.runInNewContext(src, sandbox, id + '.vm'); } catch (_error) { err = _error; + console.log(err); answ.code = 400; answ.message = 'Loading Module failed: ' + err.message; } - return ret = { + ret = { answ: answ, module: sandbox.exports }; + return ret; }; }).call(this); diff --git a/js-coffee/engine.js b/js-coffee/engine.js index ad699d0..68d0a00 100644 --- a/js-coffee/engine.js +++ b/js-coffee/engine.js @@ -1,110 +1,66 @@ 'use strict'; var path = require('path'), - // qEvents = new (require('./queue')).Queue(), //TODO export queue into redis regex = /\$X\.[\w\.\[\]]*/g, // find properties of $X listRules = {}, listActionModules = {}, isRunning = true, - mm, poller, db, log; + dynmod = require('./dynamic-modules'), + db = require('./persistence'), log; exports = module.exports = function( args ) { log = args.logger; - mm = require('./components-manager')(args); + db( args); + dynmod(args); + pollQueue(); return module.exports; }; -exports.internalEvent = function( evt ) { - console.log('engine got internal event'); - console.log(evt); -} -/* - * Initialize the rules engine which initializes the module loader. - * @param {Object} db_link the link to the db, see [db\_interface](db_interface.html) - * @param {String} db_port the db port - * @param {String} crypto_key the key to be used for encryption on the db, max legnth 256 - */ -exports.addPersistence = function(db_link) { - db = db_link; - // if(mm && db) db.getActionModules(function(err, obj) { - // if(err) log.error('EN', 'retrieving Action Modules from DB!'); - // else { - // if(!obj) { - // log.info('EN', 'No Action Modules found in DB!'); - // loadRulesFromDB(); - // } else { - // var m; - // for(var el in obj) { - // log.info('EN', 'Loading Action Module from DB: ' + el); - // try{ - // m = mm.requireFromString(obj[el], el); - // db.getActionModuleAuth(el, function(mod) { - // return function(err, obj) { - // if(obj && mod.loadCredentials) mod.loadCredentials(JSON.parse(obj)); - // }; - // }(m)); - // listActionModules[el] = m; - // } catch(e) { - // e.addInfo = 'error in action module "' + el + '"'; - // log.error('EN', e); - // } - // } - // loadRulesFromDB(); - // } - // } - // }); - // else log.severe('EN', new Error('Module Loader or DB not defined!')); -}; +var updateActionModules = function() { + for ( var user in listRules ) { + if(!listActionModules[user]) listActionModules[user] = {}; + for ( var rule in listRules[user] ) { + var actions = listRules[user][rule].actions; + for ( var i = 0; i < actions.length; i++ ){ + var arrMod = actions[i].split(' -> '); + if ( !listActionModules[user][arrMod[0]] ){ + db.getActionInvoker(arrMod[0], function( err, objAM ){ + db.getActionUserParams(arrMod[0], user, function( err, objParams ) { + console.log (objAM); -function loadRulesFromDB() { - if(db) db.getRules(function(err, obj) { - for(var el in obj){ - if(obj[el]) exports.addRule(JSON.parse(obj[el])); + //FIXME am name is called 'actions'??? + // if(objParams) { //TODO we don't need them for all modules + var answ = dynmod.compileString(objAM.code, objAM.actions + "_" + user, objParams, objAM.lang); + console.log('answ'); + console.log(answ); + listActionModules[user][arrMod[0]] = answ.module; + console.log('loaded ' + user + ': ' + arrMod[0]); + console.log(listActionModules); + // } + }); + }); + } + } } - - }); - //start to poll the event queue - pollQueue(); -} - -/** - * Insert an action module into the list of available interfaces. - * @param {Object} objModule the action module object - */ -exports.loadActionModule = function(name, objModule) { - - //TODO not used yet, load action modules from db for each rule per user - // TODO only load module once, load user specific parameters per user - // when rule is activated by user. invoked action then uses user specific - // parameters - log.info('EN', 'Action module "' + name + '" loaded'); - listActionModules[name] = objModule; -}; - -exports.getActionModule = function(name) { - return listActionModules[name]; -}; - -/** - * Add a rule into the working memory - * @param {Object} objRule the rule object - */ -exports.addRule = function(objRule) { - //TODO validate rule - log.info('EN', 'Loading Rule'); - log.info('EN', objRule); - log.info('EN', 'Loading Rule: ' + objRule.id); - if(listRules[objRule.id]) log.info('EN', 'Replacing rule: ' + objRule.id); - listRules[objRule.id] = objRule; - - // Notify poller about eventual candidate - try { - poller.send('event|'+objRule.event); - } catch (err) { - log.info('EN', 'Unable to inform poller about new active rule!'); } }; +exports.internalEvent = function( evt, data ) { + try{ + var obj = JSON.parse( data ); + db.getRuleActivatedUsers(obj.id, function ( err, arrUsers ) { + for(var i = 0; i < arrUsers.length; i++) { + if( !listRules[arrUsers[i]]) listRules[arrUsers[i]] = {}; + listRules[arrUsers[i]][obj.id] = obj; + updateActionModules(); + } + }); + } catch( err ) { + console.log( err ); + } +}; + + function pollQueue() { if(isRunning) { db.popEvent(function (err, obj) { @@ -123,8 +79,10 @@ function pollQueue() { function processEvent(evt) { log.info('EN', 'processing event: ' + evt.event + '(' + evt.eventid + ')'); var actions = checkEvent(evt); - for(var i = 0; i < actions.length; i++) { - invokeAction(evt, actions[i]); + for(var user in actions) { + for(var i = 0; i < actions[user].length; i++) { + invokeAction(evt, user, actions[user][i]); + } } } @@ -134,25 +92,50 @@ function processEvent(evt) { * @param {Object} evt the event to check */ function checkEvent(evt) { - var actions = []; - for(var rn in listRules) { + var actions = {}; + for(var user in listRules) { + actions[user] = []; + for(var rule in listRules[user]) { //TODO this needs to get depth safe, not only data but eventually also // on one level above (eventid and other meta) - if(listRules[rn].event === evt.event && validConditions(evt.payload, listRules[rn])) { - log.info('EN', 'Rule "' + rn + '" fired'); - actions = actions.concat(listRules[rn].actions); + + if(listRules[user][rule].event === evt.event && validConditions(evt.payload, listRules[user][rule])) { + log.info('EN', 'Rule "' + rule + '" fired'); + var arrAct = listRules[user][rule].actions; + for(var i = 0; i < arrAct.length; i++) { + if(actions[user].indexOf(arrAct[i]) === -1) actions[user].push(arrAct[i]); + } + } } } return actions; } +// { +// "event": "emailyak -> newMail", +// "payload": { +// "TextBody": "hello" +// } +// } + +// exports.sendMail = ( args ) -> +// url = 'https://api.emailyak.com/v1/ps1g59ndfcwg10w/json/send/email/' + +// data = +// FromAddress: 'tester@mscliveweb.simpleyak.com' +// ToAddress: 'dominic.bosch.db@gmail.com' +// TextBody: 'test' + +// needle.post url, JSON.stringify( data ), {json: true}, ( err, resp, body ) -> +// log err +// log body /** * Checks whether all conditions of the rule are met by the event. * @param {Object} evt the event to check * @param {Object} rule the rule with its conditions */ function validConditions(evt, rule) { - for(var property in rule.condition){ + for(var property in rule.conditions){ if(!evt[property] || evt[property] != rule.condition[property]) return false; } return true; @@ -163,22 +146,27 @@ function validConditions(evt, rule) { * @param {Object} evt The event that invoked the action * @param {Object} action The action to be invoked */ -function invokeAction(evt, action) { +function invokeAction( evt, user, action ) { var actionargs = {}, - arrModule = action.module.split('->'); + arrModule = action.split(' -> '); + //FIXME internal events, such as loopback ha sno arrow //TODO this requires change. the module property will be the identifier // in the actions object (or shall we allow several times the same action?) if(arrModule.length < 2) { log.error('EN', 'Invalid rule detected!'); return; } - var srvc = listActionModules[arrModule[0]]; + console.log('invoking action'); + console.log(arrModule[0]); + console.log(listActionModules); + var srvc = listActionModules[user][arrModule[0]]; + console.log(srvc); if(srvc && srvc[arrModule[1]]) { //FIXME preprocessing not only on data //FIXME no preprocessing at all, why don't we just pass the whole event to the action?' - preprocessActionArguments(evt.payload, action.arguments, actionargs); + // preprocessActionArguments(evt.payload, action.arguments, actionargs); try { - if(srvc[arrModule[1]]) srvc[arrModule[1]](actionargs); + if(srvc[arrModule[1]]) srvc[arrModule[1]](evt.payload); } catch(err) { log.error('EN', 'during action execution: ' + err); } @@ -186,53 +174,52 @@ function invokeAction(evt, action) { else log.info('EN', 'No api interface found for: ' + action.module); } -/** - * Action properties may contain event properties which need to be resolved beforehand. - * @param {Object} evt The event whose property values can be used in the rules action - * @param {Object} act The rules action arguments - * @param {Object} res The object to be used to enter the new properties - */ -function preprocessActionArguments(evt, act, res) { - for(var prop in act) { - /* - * If the property is an object itself we go into recursion - */ - if(typeof act[prop] === 'object') { - res[prop] = {}; - preprocessActionArguments(evt, act[prop], res[prop]); - } - else { - var txt = act[prop]; - var arr = txt.match(regex); - /* - * If rules action property holds event properties we resolve them and - * replace the original action property - */ - // console.log(evt); - if(arr) { - for(var i = 0; i < arr.length; i++) { - /* - * The first three characters are '$X.', followed by the property - */ - var actionProp = arr[i].substring(3).toLowerCase(); - // console.log(actionProp); - for(var eprop in evt) { - // our rules language doesn't care about upper or lower case - if(eprop.toLowerCase() === actionProp) { - txt = txt.replace(arr[i], evt[eprop]); - } - } - txt = txt.replace(arr[i], '[property not available]'); - } - } - res[prop] = txt; - } - } -} +// /** +// * Action properties may contain event properties which need to be resolved beforehand. +// * @param {Object} evt The event whose property values can be used in the rules action +// * @param {Object} act The rules action arguments +// * @param {Object} res The object to be used to enter the new properties +// */ +// function preprocessActionArguments(evt, act, res) { +// for(var prop in act) { +// /* +// * If the property is an object itself we go into recursion +// */ +// if(typeof act[prop] === 'object') { +// res[prop] = {}; +// preprocessActionArguments(evt, act[prop], res[prop]); +// } +// else { +// var txt = act[prop]; +// var arr = txt.match(regex); + +// * If rules action property holds event properties we resolve them and +// * replace the original action property + +// // console.log(evt); +// if(arr) { +// for(var i = 0; i < arr.length; i++) { +// /* +// * The first three characters are '$X.', followed by the property +// */ +// var actionProp = arr[i].substring(3).toLowerCase(); +// // console.log(actionProp); +// for(var eprop in evt) { +// // our rules language doesn't care about upper or lower case +// if(eprop.toLowerCase() === actionProp) { +// txt = txt.replace(arr[i], evt[eprop]); +// } +// } +// txt = txt.replace(arr[i], '[property not available]'); +// } +// } +// res[prop] = txt; +// } +// } +// } exports.shutDown = function() { if(log) log.info('EN', 'Shutting down Poller and DB Link'); isRunning = false; - if(poller) poller.send('cmd|shutdown'); if(db) db.shutDown(); }; diff --git a/js-coffee/event-poller.js b/js-coffee/event-poller.js index 4f7d59e..440e34c 100644 --- a/js-coffee/event-poller.js +++ b/js-coffee/event-poller.js @@ -114,8 +114,8 @@ function initMessageActions() { }; process.on('message', function( obj ) { - console.log( 'message: '); - console.log (obj); + // console.log( 'message: '); + // console.log (obj); // var arrProps = obj .split('|'); // if(arrProps.length < 2) log.error('EP', 'too few parameter in message!'); // else { diff --git a/js-coffee/request-handler.js b/js-coffee/request-handler.js index a3634b1..1779c88 100644 --- a/js-coffee/request-handler.js +++ b/js-coffee/request-handler.js @@ -74,7 +74,7 @@ Request Handler return req.on('end', function() { var answ, obj, rand, timestamp; if (req.session && req.session.user) { - obj = qs.parse(body); + obj = JSON.parse(body); if (obj && obj.event) { timestamp = (new Date).toISOString(); rand = (Math.floor(Math.random() * 10e9)).toString(16).toUpperCase(); diff --git a/js-coffee/webapi-eca.js b/js-coffee/webapi-eca.js index dac33f2..76f78a2 100644 --- a/js-coffee/webapi-eca.js +++ b/js-coffee/webapi-eca.js @@ -149,11 +149,23 @@ WebAPI-ECA Engine poller = cp.fork(path.resolve(__dirname, nameEP), cliArgs); _this.log.info('RS | Initialzing module manager'); cm(args); - cm.addListener('newRule', function(evt) { - return poller.send(evt); + cm.addListener('init', function(evt) { + return poller.send({ + event: 'init', + data: evt + }); }); cm.addListener('newRule', function(evt) { - return engine.internalEvent(evt); + return poller.send({ + event: 'newRule', + data: evt + }); + }); + cm.addListener('init', function(evt) { + return engine.internalEvent('init', evt); + }); + cm.addListener('newRule', function(evt) { + return engine.internalEvent('newRule', evt); }); _this.log.info('RS | Initialzing http listener'); args['request-service'] = cm.processRequest; diff --git a/webpages/handlers/coffee/error.coffee b/webpages/handlers/coffee/error.coffee new file mode 100644 index 0000000..ba95f7a --- /dev/null +++ b/webpages/handlers/coffee/error.coffee @@ -0,0 +1,8 @@ + +fOnLoad = () -> + document.title = 'Error!' + $( '#pagetitle' ).text 'Hi {{{user.username}}}, there has been an error!' + $( '#info' ).text 'Error: {{{message}}}' + $( '#info' ).attr 'class', 'error' + +window.addEventListener 'load', fOnLoad, true diff --git a/webpages/handlers/coffee/forge_event.coffee b/webpages/handlers/coffee/forge_event.coffee index c0f899a..a627521 100644 --- a/webpages/handlers/coffee/forge_event.coffee +++ b/webpages/handlers/coffee/forge_event.coffee @@ -13,8 +13,9 @@ fOnLoad = () -> $( '#but_submit' ).click () -> try - data = JSON.parse editor.getValue() - $.post( '/event', data ) + val = editor.getValue() + JSON.parse val # try to parse, throw an error if JSON not valid + $.post( '/event', val ) .done ( data ) -> $( '#info' ).text data.message $( '#info' ).attr 'class', 'success' diff --git a/webpages/handlers/coffee/forge_rule.coffee b/webpages/handlers/coffee/forge_rule.coffee index 06757ee..67d96da 100644 --- a/webpages/handlers/coffee/forge_rule.coffee +++ b/webpages/handlers/coffee/forge_rule.coffee @@ -127,10 +127,13 @@ fOnLoad = () -> $( '#but_submit' ).click () -> - arrEP = $( '#select_event option:selected' ).val().split ' -> ' try + if $( '#select_event option:selected' ).length is 0 + throw new Error 'Please create an Event Poller first!' + + arrEP = $( '#select_event option:selected' ).val().split ' -> ' if $( '#input_id' ).val() is '' - throw new Error 'Please enter a module name!' + throw new Error 'Please enter a rule name!' ep = {} $( "#event_poller_params tr" ).each () -> diff --git a/webpages/handlers/js/error.js b/webpages/handlers/js/error.js new file mode 100644 index 0000000..2bb94fc --- /dev/null +++ b/webpages/handlers/js/error.js @@ -0,0 +1,14 @@ +// Generated by CoffeeScript 1.6.3 +(function() { + var fOnLoad; + + fOnLoad = function() { + document.title = 'Error!'; + $('#pagetitle').text('Hi {{{user.username}}}, there has been an error!'); + $('#info').text('Error: {{{message}}}'); + return $('#info').attr('class', 'error'); + }; + + window.addEventListener('load', fOnLoad, true); + +}).call(this); diff --git a/webpages/handlers/js/forge_event.js b/webpages/handlers/js/forge_event.js index a248587..90e5936 100644 --- a/webpages/handlers/js/forge_event.js +++ b/webpages/handlers/js/forge_event.js @@ -13,10 +13,11 @@ $('#editor').css('height', '400px'); $('#editor').css('width', '600px'); return $('#but_submit').click(function() { - var data, err; + var err, val; try { - data = JSON.parse(editor.getValue()); - return $.post('/event', data).done(function(data) { + val = editor.getValue(); + JSON.parse(val); + return $.post('/event', val).done(function(data) { $('#info').text(data.message); return $('#info').attr('class', 'success'); }).fail(function(err) { diff --git a/webpages/handlers/js/forge_rule.js b/webpages/handlers/js/forge_rule.js index de8b7d6..57398f4 100644 --- a/webpages/handlers/js/forge_rule.js +++ b/webpages/handlers/js/forge_rule.js @@ -162,10 +162,13 @@ }); return $('#but_submit').click(function() { var acts, ap, arrEP, ep, err; - arrEP = $('#select_event option:selected').val().split(' -> '); try { + if ($('#select_event option:selected').length === 0) { + throw new Error('Please create an Event Poller first!'); + } + arrEP = $('#select_event option:selected').val().split(' -> '); if ($('#input_id').val() === '') { - throw new Error('Please enter a module name!'); + throw new Error('Please enter a rule name!'); } ep = {}; $("#event_poller_params tr").each(function() { diff --git a/webpages/handlers/templates/error.html b/webpages/handlers/templates/error.html new file mode 100644 index 0000000..e69de29 diff --git a/webpages/handlers/templates/forge_action_invoker.html b/webpages/handlers/templates/forge_action_invoker.html index 155899d..97d3dc6 100644 --- a/webpages/handlers/templates/forge_action_invoker.html +++ b/webpages/handlers/templates/forge_action_invoker.html @@ -37,7 +37,8 @@ exports.createBinderEntry = ( args ) -> if err log err if resp.statusCode isnt 200 - log "Request not successful: #{ body }" + log 'Request not successful:' + log body