mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-03-16 22:10:31 +00:00
Engine up and running again, now in coffeescript. only event-poller remains
This commit is contained in:
parent
0cb2241ea0
commit
c71bf520a4
14 changed files with 1068 additions and 849 deletions
|
|
@ -15,6 +15,10 @@ db = require './persistence'
|
|||
# - [Dynamic Modules](dynamic-modules.html)
|
||||
dynmod = require './dynamic-modules'
|
||||
|
||||
# - External Modules:
|
||||
# [js-select](https://www.npmjs.org/package/js-select)
|
||||
jsonQuery = require 'js-select'
|
||||
|
||||
listUserRules = {}
|
||||
isRunning = false
|
||||
|
||||
|
|
@ -36,14 +40,25 @@ exports = module.exports = ( args ) =>
|
|||
|
||||
|
||||
###
|
||||
Add an event handler (eh) that listens for rules.
|
||||
|
||||
@public addRuleListener ( *eh* )
|
||||
@param {function} eh
|
||||
This is a helper function for the unit tests so we can verify that action
|
||||
modules are loaded correctly
|
||||
#TODO we should change this to functions returning true or false rather than returning
|
||||
#the whole list
|
||||
@public getListUserRules ()
|
||||
###
|
||||
exports.getListUserRules = () ->
|
||||
listUserRules
|
||||
|
||||
|
||||
###
|
||||
An event associated to rules happened and is captured here. Such events
|
||||
are basically CRUD on rules.
|
||||
|
||||
@public internalEvent ( *evt* )
|
||||
@param {Object} evt
|
||||
###
|
||||
exports.internalEvent = ( evt ) =>
|
||||
if not listUserRules[evt.user]
|
||||
if not listUserRules[evt.user] and evt.event isnt 'del'
|
||||
listUserRules[evt.user] =
|
||||
rules: {}
|
||||
actions: {}
|
||||
|
|
@ -52,20 +67,42 @@ exports.internalEvent = ( evt ) =>
|
|||
oRule = evt.rule
|
||||
if evt.event is 'new' or ( evt.event is 'init' and not oUser.rules[oRule.id] )
|
||||
oUser.rules[oRule.id] = oRule
|
||||
updateActionModules oRule
|
||||
updateActionModules oRule, false
|
||||
|
||||
updateActionModules = ( oNewRule ) ->
|
||||
if evt.event is 'del' and oUser
|
||||
delete oUser.rules[oRule.id]
|
||||
updateActionModules oRule, true
|
||||
|
||||
|
||||
###
|
||||
As soon as changes were made to the rule set we need to ensure that the aprropriate action
|
||||
invoker modules are loaded, updated or deleted.
|
||||
|
||||
@private updateActionModules ( *oNewRule* )
|
||||
@param {Object} oNewRule
|
||||
###
|
||||
updateActionModules = ( oNewRule, isDeleteOp ) ->
|
||||
|
||||
# Remove all action invoker modules that are not required anymore
|
||||
fRemoveNotRequired = ( oUser ) ->
|
||||
|
||||
# Check whether the action is still existing in a rule
|
||||
fRequired = ( actionName ) ->
|
||||
return true for nmRl, oRl of oUser.rules when actionName in oRl.actions
|
||||
return false
|
||||
# return true for nmRl, oRl of oUser.rules when actionName in oRl.actions
|
||||
for nmRl, oRl of oUser.rules
|
||||
for action in oRl.actions
|
||||
mod = (action.split ' -> ')[0]
|
||||
if mod is actionName
|
||||
return true
|
||||
false
|
||||
|
||||
|
||||
# Go thorugh all actions and check whether the action is still required
|
||||
delete oUser.actions[action] for action of oUser.actions when not fRequired action
|
||||
for action of oUser.actions
|
||||
req = fRequired action
|
||||
if not req
|
||||
delete oUser.actions[action]
|
||||
# delete oUser.actions[action] for action of oUser.actions when not fRequired action
|
||||
|
||||
fRemoveNotRequired oUser for name, oUser of listUserRules
|
||||
|
||||
|
|
@ -78,7 +115,7 @@ updateActionModules = ( oNewRule ) ->
|
|||
# Load the action invoker module if it was part of the updated rule or if it's new
|
||||
fAddIfNewOrNotExisting = ( actionName ) ->
|
||||
moduleName = (actionName.split ' -> ')[0]
|
||||
if not oUser.actions[moduleName] or oRule.id is oNewRule.id
|
||||
if not isDeleteOp and ( not oUser.actions[moduleName] or oRule.id is oNewRule.id )
|
||||
db.actionInvokers.getModule moduleName, ( err, obj ) ->
|
||||
params = {}
|
||||
res = dynmod.compileString obj.data, userName, moduleName, params, obj.lang
|
||||
|
|
@ -88,6 +125,8 @@ updateActionModules = ( oNewRule ) ->
|
|||
|
||||
# Go thorugh all actions and check whether the action is still required
|
||||
fCheckRules oRl for nmRl, oRl of oUser.rules
|
||||
if JSON.stringify( oUser.rules ) is "{}" # TODO check whether this is really doing what it is supposed to do
|
||||
delete listUserRules[userName]
|
||||
|
||||
fAddRequired userName, oUser for userName, oUser of listUserRules
|
||||
|
||||
|
|
@ -106,8 +145,8 @@ Checks whether all conditions of the rule are met by the event.
|
|||
@param {Object} rule
|
||||
###
|
||||
validConditions = ( evt, rule ) ->
|
||||
conds = rule.conditions
|
||||
return false for prop of conds when not evt[prop] or evt[prop] isnt conds[prop]
|
||||
for prop in rule.conditions
|
||||
return false if jsonQuery( evt, prop ).nodes().length is 0
|
||||
return true
|
||||
|
||||
###
|
||||
|
|
@ -116,78 +155,16 @@ Handles retrieved events.
|
|||
@private processEvent ( *evt* )
|
||||
@param {Object} evt
|
||||
###
|
||||
processEvent = ( evt ) ->
|
||||
@log.info('EN | processing event: ' + evt.event + '(' + evt.eventid + ')');
|
||||
# var actions = checkEvent(evt);
|
||||
# console.log('found actions to invoke:');
|
||||
# console.log(actions);
|
||||
# for(var user in actions) {
|
||||
# for(var module in actions[user]) {
|
||||
# for(var i = 0; i < actions[user][module]['functions'].length; i++) {
|
||||
# var act = {
|
||||
# module: module,
|
||||
# function: actions[user][module]['functions'][i]
|
||||
# }
|
||||
# invokeAction(evt, user, act);
|
||||
|
||||
# */
|
||||
# function checkEvent(evt) {
|
||||
# var actions = {}, tEvt;
|
||||
# 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)
|
||||
# tEvt = listRules[user][rule].event;
|
||||
# if(tEvt.module + ' -> ' + tEvt.function === evt.event && validConditions(evt.payload, listRules[user][rule])) {
|
||||
# log.info('EN', 'Rule "' + rule + '" fired');
|
||||
# var oAct = listRules[user][rule].actions;
|
||||
# console.log (oAct);
|
||||
# for(var module in oAct) {
|
||||
# if(!actions[user][module]) {
|
||||
# actions[user][module] = {
|
||||
# functions: []
|
||||
# };
|
||||
# }
|
||||
# for(var i = 0; i < oAct[module]['functions'].length; i++ ){
|
||||
# console.log ('processing action ' + i + ', ' + oAct[module]['functions'][i]);
|
||||
# actions[user][module]['functions'].push(oAct[module]['functions'][i]);
|
||||
# // if(actions[user].indexOf(arrAct[i]) === -1) actions[user].push(arrAct[i]);
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# return actions;
|
||||
# }
|
||||
|
||||
# /**
|
||||
# * Invoke an action according to its type.
|
||||
# * @param {Object} evt The event that invoked the action
|
||||
# * @param {Object} action The action to be invoked
|
||||
# */
|
||||
# function invokeAction( evt, user, action ) {
|
||||
# console.log('invoking action');
|
||||
# var actionargs = {};
|
||||
# //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?)
|
||||
# console.log(action.module);
|
||||
# console.log(listActionModules);
|
||||
# var srvc = listActionModules[user][action.module];
|
||||
# console.log(srvc);
|
||||
# if(srvc && srvc[action.function]) {
|
||||
# //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);
|
||||
# try {
|
||||
# if(srvc[action.function]) srvc[action.function](evt.payload);
|
||||
# } catch(err) {
|
||||
# log.error('EN', 'during action execution: ' + err);
|
||||
# }
|
||||
# }
|
||||
# else log.info('EN', 'No api interface found for: ' + action.module);
|
||||
# }
|
||||
processEvent = ( evt ) =>
|
||||
@log.info 'EN | processing event: ' + evt.event + '(' + evt.eventid + ')'
|
||||
for userName, oUser of listUserRules
|
||||
for ruleName, oRule of oUser.rules
|
||||
if evt.event is oRule.event and validConditions evt, oRule
|
||||
@log.info 'EN | EVENT FIRED: ' + evt.event + '(' + evt.eventid + ') for rule ' + ruleName
|
||||
# fStoreAction userName, action for action in oRule.actions
|
||||
for action in oRule.actions
|
||||
arr = action.split ' -> '
|
||||
listUserRules[userName]['actions'][arr[0]][arr[1]] evt
|
||||
|
||||
exports.shutDown = () ->
|
||||
isRunning = false
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
|
||||
/*
|
||||
|
||||
Components Manager
|
||||
|
|
@ -6,12 +7,10 @@ Components Manager
|
|||
> The components manager takes care of the dynamic JS modules and the rules.
|
||||
> Event Poller and Action Invoker modules are loaded as strings and stored in the database,
|
||||
> then compiled into node modules and rules and used in the engine and event poller.
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var commandFunctions, db, dynmod, eventEmitter, events, exports, forgeModule, fs, getModuleParams, getModules, hasRequiredParams, path,
|
||||
_this = this;
|
||||
var commandFunctions, db, dynmod, eventEmitter, events, exports, forgeModule, fs, getModuleParams, getModules, hasRequiredParams, path;
|
||||
|
||||
db = require('./persistence');
|
||||
|
||||
|
|
@ -25,61 +24,67 @@ Components Manager
|
|||
|
||||
eventEmitter = new events.EventEmitter();
|
||||
|
||||
|
||||
/*
|
||||
Module call
|
||||
-----------
|
||||
Initializes the Components Manager and constructs a new Event Emitter.
|
||||
|
||||
@param {Object} args
|
||||
*/
|
||||
*/
|
||||
|
||||
exports = module.exports = (function(_this) {
|
||||
return function(args) {
|
||||
_this.log = args.logger;
|
||||
db(args);
|
||||
dynmod(args);
|
||||
return module.exports;
|
||||
};
|
||||
})(this);
|
||||
|
||||
exports = module.exports = function(args) {
|
||||
_this.log = args.logger;
|
||||
db(args);
|
||||
dynmod(args);
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
/*
|
||||
Add an event handler (eh) that listens for rules.
|
||||
|
||||
@public addRuleListener ( *eh* )
|
||||
@param {function} eh
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
exports.addRuleListener = function(eh) {
|
||||
eventEmitter.addListener('rule', eh);
|
||||
return db.getAllActivatedRuleIdsPerUser(function(err, objUsers) {
|
||||
var fGoThroughUsers, rules, user, _results;
|
||||
fGoThroughUsers = function(user, rules) {
|
||||
var fFetchRule, rule, _i, _len, _results;
|
||||
fFetchRule = function(rule) {
|
||||
var _this = this;
|
||||
return db.getRule(rule, function(err, oRule) {
|
||||
return eventEmitter.emit('rule', {
|
||||
event: 'init',
|
||||
user: user,
|
||||
rule: JSON.parse(oRule)
|
||||
});
|
||||
});
|
||||
exports.addRuleListener = (function(_this) {
|
||||
return function(eh) {
|
||||
eventEmitter.addListener('rule', eh);
|
||||
return db.getAllActivatedRuleIdsPerUser(function(err, objUsers) {
|
||||
var fGoThroughUsers, rules, user, _results;
|
||||
fGoThroughUsers = function(user, rules) {
|
||||
var fFetchRule, rule, _i, _len, _results;
|
||||
fFetchRule = function(rule) {
|
||||
return db.getRule(rule, (function(_this) {
|
||||
return function(err, oRule) {
|
||||
return eventEmitter.emit('rule', {
|
||||
event: 'init',
|
||||
user: user,
|
||||
rule: JSON.parse(oRule)
|
||||
});
|
||||
};
|
||||
})(this));
|
||||
};
|
||||
_results = [];
|
||||
for (_i = 0, _len = rules.length; _i < _len; _i++) {
|
||||
rule = rules[_i];
|
||||
_results.push(fFetchRule(rule));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
_results = [];
|
||||
for (_i = 0, _len = rules.length; _i < _len; _i++) {
|
||||
rule = rules[_i];
|
||||
_results.push(fFetchRule(rule));
|
||||
for (user in objUsers) {
|
||||
rules = objUsers[user];
|
||||
_results.push(fGoThroughUsers(user, rules));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
_results = [];
|
||||
for (user in objUsers) {
|
||||
rules = objUsers[user];
|
||||
_results.push(fGoThroughUsers(user, rules));
|
||||
}
|
||||
return _results;
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
})(this);
|
||||
|
||||
|
||||
/*
|
||||
Processes a user request coming through the request-handler.
|
||||
|
|
@ -94,8 +99,7 @@ Components Manager
|
|||
@param {Object} user
|
||||
@param {Object} oReq
|
||||
@param {function} callback
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
exports.processRequest = function(user, oReq, callback) {
|
||||
var dat, err;
|
||||
|
|
@ -140,8 +144,7 @@ Components Manager
|
|||
|
||||
getModules = function(user, oPayload, dbMod, callback) {
|
||||
return dbMod.getAvailableModuleIds(user.username, function(err, arrNames) {
|
||||
var answReq, fGetFunctions, id, oRes, sem, _i, _len, _results,
|
||||
_this = this;
|
||||
var answReq, fGetFunctions, id, oRes, sem, _i, _len, _results;
|
||||
oRes = {};
|
||||
answReq = function() {
|
||||
return callback({
|
||||
|
|
@ -153,16 +156,18 @@ Components Manager
|
|||
if (sem === 0) {
|
||||
return answReq();
|
||||
} else {
|
||||
fGetFunctions = function(id) {
|
||||
return dbMod.getModule(id, function(err, oModule) {
|
||||
if (oModule) {
|
||||
oRes[id] = JSON.parse(oModule.functions);
|
||||
}
|
||||
if (--sem === 0) {
|
||||
return answReq();
|
||||
}
|
||||
});
|
||||
};
|
||||
fGetFunctions = (function(_this) {
|
||||
return function(id) {
|
||||
return dbMod.getModule(id, function(err, oModule) {
|
||||
if (oModule) {
|
||||
oRes[id] = JSON.parse(oModule.functions);
|
||||
}
|
||||
if (--sem === 0) {
|
||||
return answReq();
|
||||
}
|
||||
});
|
||||
};
|
||||
})(this);
|
||||
_results = [];
|
||||
for (_i = 0, _len = arrNames.length; _i < _len; _i++) {
|
||||
id = arrNames[_i];
|
||||
|
|
@ -186,41 +191,43 @@ Components Manager
|
|||
}
|
||||
};
|
||||
|
||||
forgeModule = function(user, oPayload, dbMod, callback) {
|
||||
var answ;
|
||||
answ = hasRequiredParams(['id', 'params', 'lang', 'data'], oPayload);
|
||||
if (answ.code !== 200) {
|
||||
return callback(answ);
|
||||
} else {
|
||||
return dbMod.getModule(oPayload.id, function(err, mod) {
|
||||
var cm, funcs, id, name, src, _ref;
|
||||
if (mod) {
|
||||
answ.code = 409;
|
||||
answ.message = 'Event Poller module name already existing: ' + oPayload.id;
|
||||
} else {
|
||||
src = oPayload.data;
|
||||
cm = dynmod.compileString(src, user.username, oPayload.id, {}, oPayload.lang);
|
||||
answ = cm.answ;
|
||||
if (answ.code === 200) {
|
||||
funcs = [];
|
||||
_ref = cm.module;
|
||||
for (name in _ref) {
|
||||
id = _ref[name];
|
||||
funcs.push(name);
|
||||
}
|
||||
_this.log.info("CM | Storing new module with functions " + (funcs.join()));
|
||||
answ.message = "Event Poller module successfully stored! Found following function(s): " + funcs;
|
||||
oPayload.functions = JSON.stringify(funcs);
|
||||
dbMod.storeModule(user.username, oPayload);
|
||||
if (oPayload["public"] === 'true') {
|
||||
dbMod.publish(oPayload.id);
|
||||
forgeModule = (function(_this) {
|
||||
return function(user, oPayload, dbMod, callback) {
|
||||
var answ;
|
||||
answ = hasRequiredParams(['id', 'params', 'lang', 'data'], oPayload);
|
||||
if (answ.code !== 200) {
|
||||
return callback(answ);
|
||||
} else {
|
||||
return dbMod.getModule(oPayload.id, function(err, mod) {
|
||||
var cm, funcs, id, name, src, _ref;
|
||||
if (mod) {
|
||||
answ.code = 409;
|
||||
answ.message = 'Event Poller module name already existing: ' + oPayload.id;
|
||||
} else {
|
||||
src = oPayload.data;
|
||||
cm = dynmod.compileString(src, user.username, oPayload.id, {}, oPayload.lang);
|
||||
answ = cm.answ;
|
||||
if (answ.code === 200) {
|
||||
funcs = [];
|
||||
_ref = cm.module;
|
||||
for (name in _ref) {
|
||||
id = _ref[name];
|
||||
funcs.push(name);
|
||||
}
|
||||
_this.log.info("CM | Storing new module with functions " + (funcs.join()));
|
||||
answ.message = "Event Poller module successfully stored! Found following function(s): " + funcs;
|
||||
oPayload.functions = JSON.stringify(funcs);
|
||||
dbMod.storeModule(user.username, oPayload);
|
||||
if (oPayload["public"] === 'true') {
|
||||
dbMod.publish(oPayload.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return callback(answ);
|
||||
});
|
||||
}
|
||||
};
|
||||
return callback(answ);
|
||||
});
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
|
||||
commandFunctions = {
|
||||
get_public_key: function(user, oPayload, callback) {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
|
||||
/*
|
||||
|
||||
Configuration
|
||||
=============
|
||||
> Loads the configuration file and acts as an interface to it.
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var exports, fetchProp, fs, loadConfigFile, path,
|
||||
_this = this;
|
||||
var exports, fetchProp, fs, loadConfigFile, path;
|
||||
|
||||
fs = require('fs');
|
||||
|
||||
path = require('path');
|
||||
|
||||
|
||||
/*
|
||||
Module call
|
||||
-----------
|
||||
|
|
@ -24,21 +24,23 @@ Configuration
|
|||
be generated) and configPath for a custom configuration file path.
|
||||
|
||||
@param {Object} args
|
||||
*/
|
||||
*/
|
||||
|
||||
exports = module.exports = (function(_this) {
|
||||
return function(args) {
|
||||
args = args != null ? args : {};
|
||||
if (args.nolog) {
|
||||
_this.nolog = true;
|
||||
}
|
||||
if (args.configPath) {
|
||||
loadConfigFile(args.configPath);
|
||||
} else {
|
||||
loadConfigFile(path.join('config', 'system.json'));
|
||||
}
|
||||
return module.exports;
|
||||
};
|
||||
})(this);
|
||||
|
||||
exports = module.exports = function(args) {
|
||||
args = args != null ? args : {};
|
||||
if (args.nolog) {
|
||||
_this.nolog = true;
|
||||
}
|
||||
if (args.configPath) {
|
||||
loadConfigFile(args.configPath);
|
||||
} else {
|
||||
loadConfigFile(path.join('config', 'system.json'));
|
||||
}
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
/*
|
||||
Tries to load a configuration file from the path relative to this module's parent folder.
|
||||
|
|
@ -46,97 +48,102 @@ Configuration
|
|||
|
||||
@private loadConfigFile
|
||||
@param {String} configPath
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
loadConfigFile = function(configPath) {
|
||||
var confProperties, e, prop, _i, _len;
|
||||
_this.config = null;
|
||||
confProperties = ['log', 'http-port', 'db-port'];
|
||||
try {
|
||||
_this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath)));
|
||||
_this.isReady = true;
|
||||
for (_i = 0, _len = confProperties.length; _i < _len; _i++) {
|
||||
prop = confProperties[_i];
|
||||
if (!_this.config[prop]) {
|
||||
_this.isReady = false;
|
||||
loadConfigFile = (function(_this) {
|
||||
return function(configPath) {
|
||||
var confProperties, e, prop, _i, _len;
|
||||
_this.config = null;
|
||||
confProperties = ['log', 'http-port', 'db-port'];
|
||||
try {
|
||||
_this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath)));
|
||||
_this.isReady = true;
|
||||
for (_i = 0, _len = confProperties.length; _i < _len; _i++) {
|
||||
prop = confProperties[_i];
|
||||
if (!_this.config[prop]) {
|
||||
_this.isReady = false;
|
||||
}
|
||||
}
|
||||
if (!_this.isReady && !_this.nolog) {
|
||||
return console.error("Missing property in config file, requires:\n" + (" - " + (confProperties.join("\n - "))));
|
||||
}
|
||||
} catch (_error) {
|
||||
e = _error;
|
||||
_this.isReady = false;
|
||||
if (!_this.nolog) {
|
||||
return console.error("Failed loading config file: " + e.message);
|
||||
}
|
||||
}
|
||||
if (!_this.isReady && !_this.nolog) {
|
||||
return console.error("Missing property in config file, requires:\n" + (" - " + (confProperties.join("\n - "))));
|
||||
}
|
||||
} catch (_error) {
|
||||
e = _error;
|
||||
_this.isReady = false;
|
||||
if (!_this.nolog) {
|
||||
return console.error("Failed loading config file: " + e.message);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})(this);
|
||||
|
||||
|
||||
/*
|
||||
Fetch a property from the configuration
|
||||
|
||||
@private fetchProp( *prop* )
|
||||
@param {String} prop
|
||||
*/
|
||||
*/
|
||||
|
||||
fetchProp = (function(_this) {
|
||||
return function(prop) {
|
||||
var _ref;
|
||||
return (_ref = _this.config) != null ? _ref[prop] : void 0;
|
||||
};
|
||||
})(this);
|
||||
|
||||
fetchProp = function(prop) {
|
||||
var _ref;
|
||||
return (_ref = _this.config) != null ? _ref[prop] : void 0;
|
||||
};
|
||||
|
||||
/*
|
||||
***Returns*** true if the config file is ready, else false
|
||||
|
||||
@public isReady()
|
||||
*/
|
||||
*/
|
||||
|
||||
exports.isReady = (function(_this) {
|
||||
return function() {
|
||||
return _this.isReady;
|
||||
};
|
||||
})(this);
|
||||
|
||||
exports.isReady = function() {
|
||||
return _this.isReady;
|
||||
};
|
||||
|
||||
/*
|
||||
***Returns*** the HTTP port
|
||||
|
||||
@public getHttpPort()
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
exports.getHttpPort = function() {
|
||||
return fetchProp('http-port');
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
***Returns*** the DB port*
|
||||
|
||||
@public getDBPort()
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
exports.getDbPort = function() {
|
||||
return fetchProp('db-port');
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
***Returns*** the log conf object
|
||||
|
||||
@public getLogConf()
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
exports.getLogConf = function() {
|
||||
return fetchProp('log');
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
***Returns*** the crypto key
|
||||
|
||||
@public getCryptoKey()
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
exports.getKeygenPassphrase = function() {
|
||||
return fetchProp('keygen-passphrase');
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
|
||||
/*
|
||||
|
||||
Dynamic Modules
|
||||
===============
|
||||
> Compiles CoffeeScript modules and loads JS modules in a VM, together
|
||||
> with only a few allowed node.js modules.
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var cryptico, cs, exports, needle, vm,
|
||||
_this = this;
|
||||
var cryptico, cs, exports, needle, vm;
|
||||
|
||||
vm = require('vm');
|
||||
|
||||
|
|
@ -20,31 +19,36 @@ Dynamic Modules
|
|||
|
||||
cryptico = require('my-cryptico');
|
||||
|
||||
|
||||
/*
|
||||
Module call
|
||||
-----------
|
||||
Initializes the dynamic module handler.
|
||||
|
||||
@param {Object} args
|
||||
*/
|
||||
*/
|
||||
|
||||
exports = module.exports = (function(_this) {
|
||||
return function(args) {
|
||||
var numBits, passPhrase;
|
||||
_this.log = args.logger;
|
||||
if (!_this.strPublicKey && args['keygen']) {
|
||||
passPhrase = args['keygen'];
|
||||
numBits = 1024;
|
||||
_this.oPrivateRSAkey = cryptico.generateRSAKey(passPhrase, numBits);
|
||||
_this.strPublicKey = cryptico.publicKeyString(_this.oPrivateRSAkey);
|
||||
_this.log.info("Public Key generated: " + _this.strPublicKey);
|
||||
}
|
||||
return module.exports;
|
||||
};
|
||||
})(this);
|
||||
|
||||
exports = module.exports = function(args) {
|
||||
var numBits, passPhrase;
|
||||
_this.log = args.logger;
|
||||
if (!_this.strPublicKey && args['keygen']) {
|
||||
passPhrase = args['keygen'];
|
||||
numBits = 1024;
|
||||
_this.oPrivateRSAkey = cryptico.generateRSAKey(passPhrase, numBits);
|
||||
_this.strPublicKey = cryptico.publicKeyString(_this.oPrivateRSAkey);
|
||||
_this.log.info("Public Key generated: " + _this.strPublicKey);
|
||||
}
|
||||
return module.exports;
|
||||
};
|
||||
exports.getPublicKey = (function(_this) {
|
||||
return function() {
|
||||
return _this.strPublicKey;
|
||||
};
|
||||
})(this);
|
||||
|
||||
exports.getPublicKey = function() {
|
||||
return _this.strPublicKey;
|
||||
};
|
||||
|
||||
/*
|
||||
Try to run a JS module from a string, together with the
|
||||
|
|
@ -56,43 +60,44 @@ Dynamic Modules
|
|||
@param {String} id
|
||||
@param {Object} params
|
||||
@param {String} lang
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
exports.compileString = function(src, userId, modId, params, lang) {
|
||||
var answ, err, ret, sandbox;
|
||||
answ = {
|
||||
code: 200,
|
||||
message: 'Successfully compiled'
|
||||
};
|
||||
if (lang === 'CoffeeScript') {
|
||||
exports.compileString = (function(_this) {
|
||||
return function(src, userId, modId, params, lang) {
|
||||
var answ, err, ret, sandbox;
|
||||
answ = {
|
||||
code: 200,
|
||||
message: 'Successfully compiled'
|
||||
};
|
||||
if (lang === 'CoffeeScript') {
|
||||
try {
|
||||
src = cs.compile(src);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
answ.code = 400;
|
||||
answ.message = 'Compilation of CoffeeScript failed at line ' + err.location.first_line;
|
||||
}
|
||||
}
|
||||
sandbox = {
|
||||
id: userId + '.' + modId + '.vm',
|
||||
params: params,
|
||||
needle: needle,
|
||||
log: console.log,
|
||||
exports: {}
|
||||
};
|
||||
try {
|
||||
src = cs.compile(src);
|
||||
vm.runInNewContext(src, sandbox, sandbox.id);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
answ.code = 400;
|
||||
answ.message = 'Compilation of CoffeeScript failed at line ' + err.location.first_line;
|
||||
answ.message = 'Loading Module failed: ' + err.message;
|
||||
}
|
||||
}
|
||||
sandbox = {
|
||||
id: userId + '.' + modId + '.vm',
|
||||
params: params,
|
||||
needle: needle,
|
||||
log: console.log,
|
||||
exports: {}
|
||||
ret = {
|
||||
answ: answ,
|
||||
module: sandbox.exports
|
||||
};
|
||||
return ret;
|
||||
};
|
||||
try {
|
||||
vm.runInNewContext(src, sandbox, sandbox.id);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
answ.code = 400;
|
||||
answ.message = 'Loading Module failed: ' + err.message;
|
||||
}
|
||||
ret = {
|
||||
answ: answ,
|
||||
module: sandbox.exports
|
||||
};
|
||||
return ret;
|
||||
};
|
||||
})(this);
|
||||
|
||||
}).call(this);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
|
||||
/*
|
||||
|
||||
Engine
|
||||
|
|
@ -6,85 +7,123 @@ Engine
|
|||
> The heart of the WebAPI ECA System. The engine loads action invoker modules
|
||||
> corresponding to active rules actions and invokes them if an appropriate event
|
||||
> is retrieved.
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var db, dynmod, exports, isRunning, listUserRules, pollQueue, processEvent, updateActionModules, validConditions,
|
||||
_this = this,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
var db, dynmod, exports, isRunning, jsonQuery, listUserRules, pollQueue, processEvent, updateActionModules, validConditions;
|
||||
|
||||
db = require('./persistence');
|
||||
|
||||
dynmod = require('./dynamic-modules');
|
||||
|
||||
jsonQuery = require('js-select');
|
||||
|
||||
listUserRules = {};
|
||||
|
||||
isRunning = false;
|
||||
|
||||
|
||||
/*
|
||||
Module call
|
||||
-----------
|
||||
Initializes the Engine and starts polling the event queue for new events.
|
||||
|
||||
@param {Object} args
|
||||
*/
|
||||
*/
|
||||
|
||||
exports = module.exports = (function(_this) {
|
||||
return function(args) {
|
||||
if (!isRunning) {
|
||||
isRunning = true;
|
||||
_this.log = args.logger;
|
||||
db(args);
|
||||
dynmod(args);
|
||||
pollQueue();
|
||||
return module.exports;
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
|
||||
exports = module.exports = function(args) {
|
||||
if (!isRunning) {
|
||||
isRunning = true;
|
||||
_this.log = args.logger;
|
||||
db(args);
|
||||
dynmod(args);
|
||||
pollQueue();
|
||||
return module.exports;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Add an event handler (eh) that listens for rules.
|
||||
|
||||
@public addRuleListener ( *eh* )
|
||||
@param {function} eh
|
||||
*/
|
||||
This is a helper function for the unit tests so we can verify that action
|
||||
modules are loaded correctly
|
||||
*TODO we should change this to functions returning true or false rather than returning
|
||||
*the whole list
|
||||
@public getListUserRules ()
|
||||
*/
|
||||
|
||||
|
||||
exports.internalEvent = function(evt) {
|
||||
var oRule, oUser;
|
||||
if (!listUserRules[evt.user]) {
|
||||
listUserRules[evt.user] = {
|
||||
rules: {},
|
||||
actions: {}
|
||||
};
|
||||
}
|
||||
oUser = listUserRules[evt.user];
|
||||
oRule = evt.rule;
|
||||
if (evt.event === 'new' || (evt.event === 'init' && !oUser.rules[oRule.id])) {
|
||||
oUser.rules[oRule.id] = oRule;
|
||||
return updateActionModules(oRule);
|
||||
}
|
||||
exports.getListUserRules = function() {
|
||||
return listUserRules;
|
||||
};
|
||||
|
||||
updateActionModules = function(oNewRule) {
|
||||
|
||||
/*
|
||||
An event associated to rules happened and is captured here. Such events
|
||||
are basically CRUD on rules.
|
||||
|
||||
@public internalEvent ( *evt* )
|
||||
@param {Object} evt
|
||||
*/
|
||||
|
||||
exports.internalEvent = (function(_this) {
|
||||
return function(evt) {
|
||||
var oRule, oUser;
|
||||
if (!listUserRules[evt.user] && evt.event !== 'del') {
|
||||
listUserRules[evt.user] = {
|
||||
rules: {},
|
||||
actions: {}
|
||||
};
|
||||
}
|
||||
oUser = listUserRules[evt.user];
|
||||
oRule = evt.rule;
|
||||
if (evt.event === 'new' || (evt.event === 'init' && !oUser.rules[oRule.id])) {
|
||||
oUser.rules[oRule.id] = oRule;
|
||||
updateActionModules(oRule, false);
|
||||
}
|
||||
if (evt.event === 'del' && oUser) {
|
||||
delete oUser.rules[oRule.id];
|
||||
return updateActionModules(oRule, true);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
|
||||
|
||||
/*
|
||||
As soon as changes were made to the rule set we need to ensure that the aprropriate action
|
||||
invoker modules are loaded, updated or deleted.
|
||||
|
||||
@private updateActionModules ( *oNewRule* )
|
||||
@param {Object} oNewRule
|
||||
*/
|
||||
|
||||
updateActionModules = function(oNewRule, isDeleteOp) {
|
||||
var fAddRequired, fRemoveNotRequired, name, oUser, userName, _results;
|
||||
fRemoveNotRequired = function(oUser) {
|
||||
var action, fRequired, _results;
|
||||
var action, fRequired, req, _results;
|
||||
fRequired = function(actionName) {
|
||||
var nmRl, oRl, _ref;
|
||||
var action, mod, nmRl, oRl, _i, _len, _ref, _ref1;
|
||||
_ref = oUser.rules;
|
||||
for (nmRl in _ref) {
|
||||
oRl = _ref[nmRl];
|
||||
if (__indexOf.call(oRl.actions, actionName) >= 0) {
|
||||
return true;
|
||||
_ref1 = oRl.actions;
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
action = _ref1[_i];
|
||||
mod = (action.split(' -> '))[0];
|
||||
if (mod === actionName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
_results = [];
|
||||
for (action in oUser.actions) {
|
||||
if (!fRequired(action)) {
|
||||
req = fRequired(action);
|
||||
if (!req) {
|
||||
_results.push(delete oUser.actions[action]);
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
|
|
@ -94,13 +133,13 @@ Engine
|
|||
fRemoveNotRequired(oUser);
|
||||
}
|
||||
fAddRequired = function(userName, oUser) {
|
||||
var fCheckRules, nmRl, oRl, _ref, _results;
|
||||
var fCheckRules, nmRl, oRl, _ref;
|
||||
fCheckRules = function(oRule) {
|
||||
var action, fAddIfNewOrNotExisting, _i, _len, _ref, _results;
|
||||
fAddIfNewOrNotExisting = function(actionName) {
|
||||
var moduleName;
|
||||
moduleName = (actionName.split(' -> '))[0];
|
||||
if (!oUser.actions[moduleName] || oRule.id === oNewRule.id) {
|
||||
if (!isDeleteOp && (!oUser.actions[moduleName] || oRule.id === oNewRule.id)) {
|
||||
return db.actionInvokers.getModule(moduleName, function(err, obj) {
|
||||
var params, res;
|
||||
params = {};
|
||||
|
|
@ -118,12 +157,13 @@ Engine
|
|||
return _results;
|
||||
};
|
||||
_ref = oUser.rules;
|
||||
_results = [];
|
||||
for (nmRl in _ref) {
|
||||
oRl = _ref[nmRl];
|
||||
_results.push(fCheckRules(oRl));
|
||||
fCheckRules(oRl);
|
||||
}
|
||||
if (JSON.stringify(oUser.rules) === "{}") {
|
||||
return delete listUserRules[userName];
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
_results = [];
|
||||
for (userName in listUserRules) {
|
||||
|
|
@ -144,37 +184,71 @@ Engine
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Checks whether all conditions of the rule are met by the event.
|
||||
|
||||
@private validConditions ( *evt, rule* )
|
||||
@param {Object} evt
|
||||
@param {Object} rule
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
validConditions = function(evt, rule) {
|
||||
var conds, prop;
|
||||
conds = rule.conditions;
|
||||
for (prop in conds) {
|
||||
if (!evt[prop] || evt[prop] !== conds[prop]) {
|
||||
var prop, _i, _len, _ref;
|
||||
_ref = rule.conditions;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
prop = _ref[_i];
|
||||
if (jsonQuery(evt, prop).nodes().length === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Handles retrieved events.
|
||||
|
||||
@private processEvent ( *evt* )
|
||||
@param {Object} evt
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
processEvent = function(evt) {
|
||||
return this.log.info('EN | processing event: ' + evt.event + '(' + evt.eventid + ')');
|
||||
};
|
||||
processEvent = (function(_this) {
|
||||
return function(evt) {
|
||||
var action, arr, oRule, oUser, ruleName, userName, _results;
|
||||
_this.log.info('EN | processing event: ' + evt.event + '(' + evt.eventid + ')');
|
||||
_results = [];
|
||||
for (userName in listUserRules) {
|
||||
oUser = listUserRules[userName];
|
||||
_results.push((function() {
|
||||
var _ref, _results1;
|
||||
_ref = oUser.rules;
|
||||
_results1 = [];
|
||||
for (ruleName in _ref) {
|
||||
oRule = _ref[ruleName];
|
||||
if (evt.event === oRule.event && validConditions(evt, oRule)) {
|
||||
this.log.info('EN | EVENT FIRED: ' + evt.event + '(' + evt.eventid + ') for rule ' + ruleName);
|
||||
_results1.push((function() {
|
||||
var _i, _len, _ref1, _results2;
|
||||
_ref1 = oRule.actions;
|
||||
_results2 = [];
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
action = _ref1[_i];
|
||||
arr = action.split(' -> ');
|
||||
_results2.push(listUserRules[userName]['actions'][arr[0]][arr[1]](evt));
|
||||
}
|
||||
return _results2;
|
||||
})());
|
||||
} else {
|
||||
_results1.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results1;
|
||||
}).call(_this));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
})(this);
|
||||
|
||||
exports.shutDown = function() {
|
||||
return isRunning = false;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,5 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
|
||||
/*
|
||||
|
||||
WebAPI-ECA Engine
|
||||
|
|
@ -9,12 +10,10 @@ WebAPI-ECA Engine
|
|||
> node webapi-eca [opt]
|
||||
>
|
||||
> See below in the optimist CLI preparation for allowed optional parameters `[opt]`.
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var argv, cm, conf, cp, db, engine, fs, http, init, logconf, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage,
|
||||
_this = this;
|
||||
var argv, cm, conf, cp, db, engine, fs, http, init, logconf, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage;
|
||||
|
||||
logger = require('./logging');
|
||||
|
||||
|
|
@ -40,10 +39,10 @@ WebAPI-ECA Engine
|
|||
|
||||
procCmds = {};
|
||||
|
||||
|
||||
/*
|
||||
Let's prepare the optimist CLI optional arguments `[opt]`:
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
usage = 'This runs your webapi-based ECA engine';
|
||||
|
||||
|
|
@ -130,72 +129,76 @@ WebAPI-ECA Engine
|
|||
|
||||
this.log.info('RS | STARTING SERVER');
|
||||
|
||||
|
||||
/*
|
||||
This function is invoked right after the module is loaded and starts the server.
|
||||
|
||||
@private init()
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
init = function() {
|
||||
var args;
|
||||
args = {
|
||||
logger: _this.log,
|
||||
logconf: logconf
|
||||
init = (function(_this) {
|
||||
return function() {
|
||||
var args;
|
||||
args = {
|
||||
logger: _this.log,
|
||||
logconf: logconf
|
||||
};
|
||||
args['http-port'] = parseInt(argv.w || conf.getHttpPort());
|
||||
args['db-port'] = parseInt(argv.d || conf.getDbPort());
|
||||
args['keygen'] = conf.getKeygenPassphrase();
|
||||
_this.log.info('RS | Initialzing DB');
|
||||
db(args);
|
||||
return db.isConnected(function(err) {
|
||||
var cliArgs, poller;
|
||||
if (err) {
|
||||
_this.log.error('RS | No DB connection, shutting down system!');
|
||||
return shutDown();
|
||||
} else {
|
||||
_this.log.info('RS | Initialzing engine');
|
||||
engine(args);
|
||||
_this.log.info('RS | Forking a child process for the event poller');
|
||||
cliArgs = [args.logconf['mode'], args.logconf['io-level'], args.logconf['file-level'], args.logconf['file-path'], args.logconf['nolog']];
|
||||
poller = cp.fork(path.resolve(__dirname, nameEP), cliArgs);
|
||||
_this.log.info('RS | Initialzing module manager');
|
||||
cm(args);
|
||||
cm.addRuleListener(engine.internalEvent);
|
||||
cm.addRuleListener(function(evt) {
|
||||
return poller.send(evt);
|
||||
});
|
||||
_this.log.info('RS | Initialzing http listener');
|
||||
args['request-service'] = cm.processRequest;
|
||||
args['shutdown-function'] = shutDown;
|
||||
return http(args);
|
||||
}
|
||||
});
|
||||
};
|
||||
args['http-port'] = parseInt(argv.w || conf.getHttpPort());
|
||||
args['db-port'] = parseInt(argv.d || conf.getDbPort());
|
||||
args['keygen'] = conf.getKeygenPassphrase();
|
||||
_this.log.info('RS | Initialzing DB');
|
||||
db(args);
|
||||
return db.isConnected(function(err) {
|
||||
var cliArgs, poller;
|
||||
if (err) {
|
||||
_this.log.error('RS | No DB connection, shutting down system!');
|
||||
return shutDown();
|
||||
} else {
|
||||
_this.log.info('RS | Initialzing engine');
|
||||
engine(args);
|
||||
_this.log.info('RS | Forking a child process for the event poller');
|
||||
cliArgs = [args.logconf['mode'], args.logconf['io-level'], args.logconf['file-level'], args.logconf['file-path'], args.logconf['nolog']];
|
||||
poller = cp.fork(path.resolve(__dirname, nameEP), cliArgs);
|
||||
_this.log.info('RS | Initialzing module manager');
|
||||
cm(args);
|
||||
cm.addRuleListener(engine.internalEvent);
|
||||
cm.addRuleListener(function(evt) {
|
||||
return poller.send(evt);
|
||||
});
|
||||
_this.log.info('RS | Initialzing http listener');
|
||||
args['request-service'] = cm.processRequest;
|
||||
args['shutdown-function'] = shutDown;
|
||||
return http(args);
|
||||
}
|
||||
});
|
||||
};
|
||||
})(this);
|
||||
|
||||
|
||||
/*
|
||||
Shuts down the server.
|
||||
|
||||
@private shutDown()
|
||||
*/
|
||||
*/
|
||||
|
||||
shutDown = (function(_this) {
|
||||
return function() {
|
||||
_this.log.warn('RS | Received shut down command!');
|
||||
if (db != null) {
|
||||
db.shutDown();
|
||||
}
|
||||
engine.shutDown();
|
||||
return process.exit();
|
||||
};
|
||||
})(this);
|
||||
|
||||
shutDown = function() {
|
||||
_this.log.warn('RS | Received shut down command!');
|
||||
if (db != null) {
|
||||
db.shutDown();
|
||||
}
|
||||
engine.shutDown();
|
||||
return process.exit();
|
||||
};
|
||||
|
||||
/*
|
||||
## Process Commands
|
||||
*# 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) {
|
||||
return typeof procCmds[cmd] === "function" ? procCmds[cmd]() : void 0;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
"crypto-js": "3.1.2",
|
||||
"express": "3.4.8",
|
||||
"groc": "0.6.1",
|
||||
"js-select": "0.6.0",
|
||||
"mustache": "0.8.1",
|
||||
"needle": "0.6.3",
|
||||
"nodeunit": "0.8.4",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@
|
|||
},
|
||||
"eventTwo":{
|
||||
"event": "test_2"
|
||||
},
|
||||
"eventReal":{
|
||||
"event": "epOne -> newMail",
|
||||
"payload": {
|
||||
"property": "test_1",
|
||||
"nestedProperty": {
|
||||
"more": "really nested"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"eps": {
|
||||
|
|
@ -43,10 +52,10 @@
|
|||
"aiTwo": {
|
||||
"id":"aiTwo",
|
||||
"lang":"CoffeeScript",
|
||||
"data":"# Send a mail through emailyak\nexports.sendMail = ( args ) ->\n\turl = 'https://api.emailyak.com/v1/' + params.apikey + '/json/send/email/'\n\tpayload =\n\t FromAddress : \"testsender@mscliveweb.simpleyak.com\",\n\t ToAddress: \"dominic.bosch@gmail.com\",\n\t Subject: \"TestMAIL\",\n\t TextBody: \"Hello\"\n\t\n\tneedle.post url, payload, ( err, resp, body ) ->\n\t\tif err\n\t\t\tlog err\n\t\tif resp.statusCode isnt 200\n\t\t\tlog 'Request not successful:'\n\t\t\tlog body\n",
|
||||
"data":"# Send a mail through emailyak\nexports.otherEvent = ( args ) ->\n\turl = 'https://api.emailyak.com/v1/' + params.apikey + '/json/send/email/'\n\tpayload =\n\t FromAddress : \"testsender@mscliveweb.simpleyak.com\",\n\t ToAddress: \"dominic.bosch@gmail.com\",\n\t Subject: \"TestMAIL\",\n\t TextBody: \"Hello\"\n\t\n\tneedle.post url, payload, ( err, resp, body ) ->\n\t\tif err\n\t\t\tlog err\n\t\tif resp.statusCode isnt 200\n\t\t\tlog 'Request not successful:'\n\t\t\tlog body\n",
|
||||
"public":"false",
|
||||
"params":"[\"apikey\",\"andmore\"]",
|
||||
"functions":"[\"sendMail\"]"
|
||||
"functions":"[\"otherEvent\"]"
|
||||
}
|
||||
},
|
||||
"userparams": {
|
||||
|
|
@ -58,32 +67,32 @@
|
|||
"ruleOne": {
|
||||
"id": "ruleOne_id",
|
||||
"event": "custom-test-1",
|
||||
"conditions": {
|
||||
"property": "yourValue"
|
||||
},
|
||||
"conditions": [],
|
||||
"actions": []
|
||||
},
|
||||
"ruleTwo": {
|
||||
"id": "ruleTwo_id",
|
||||
"event": "custom-test-2",
|
||||
"conditions": {
|
||||
"property": "yourValue2"
|
||||
},
|
||||
"conditions": [],
|
||||
"actions": []
|
||||
},
|
||||
"ruleThree": {
|
||||
"id": "ruleThree_id",
|
||||
"event": "custom-test-3",
|
||||
"conditions": {
|
||||
"property": "yourValue3"
|
||||
},
|
||||
"conditions": [],
|
||||
"actions": []
|
||||
},
|
||||
"ruleReal": {
|
||||
"id": "ruleReal",
|
||||
"event": "epOne -> newMail",
|
||||
"conditions": {},
|
||||
"conditions": [".more:val(\"really nested\")"],
|
||||
"actions": ["aiOne -> sendMail"]
|
||||
},
|
||||
"ruleRealTwo": {
|
||||
"id": "ruleRealTwo",
|
||||
"event": "epOne -> newMail",
|
||||
"conditions": [],
|
||||
"actions": ["aiTwo -> otherEvent"]
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ exports.testListener = ( test ) =>
|
|||
|
||||
cm.addRuleListener ( evt ) =>
|
||||
strEvt = JSON.stringify evt.rule
|
||||
console.log evt
|
||||
if evt.event is 'init'
|
||||
if strEvt is strRuleOne or strEvt is strRuleTwo
|
||||
test.ok true, 'Dummy true to fill expected tests!'
|
||||
|
|
|
|||
|
|
@ -22,63 +22,136 @@ engine opts
|
|||
db = require path.join '..', 'js-coffee', 'persistence'
|
||||
db opts
|
||||
|
||||
listRules = engine.getListUserRules()
|
||||
|
||||
oUser = objects.users.userOne
|
||||
oRuleOne = objects.rules.ruleOne
|
||||
oRuleTwo = objects.rules.ruleTwo
|
||||
oRuleReal = objects.rules.ruleReal
|
||||
oEpOne = objects.eps.epOne
|
||||
oEpTwo = objects.eps.epTwo
|
||||
oRuleRealTwo = objects.rules.ruleRealTwo
|
||||
oAiOne = objects.ais.aiOne
|
||||
oAiTwo = objects.ais.aiTwo
|
||||
|
||||
exports.tearDown = ( cb ) ->
|
||||
db.deleteRule oRuleOne.id
|
||||
db.deleteRule oRuleTwo.id
|
||||
db.deleteRule oRuleReal.id
|
||||
db.actionInvokers.deleteModule oAiOne.id
|
||||
db.actionInvokers.deleteModule oAiTwo.id
|
||||
# TODO if user is deleted all his modules should be unlinked and deleted
|
||||
db.deleteUser oUser.username
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleRealTwo
|
||||
|
||||
setTimeout cb, 100
|
||||
|
||||
exports.ruleEvents =
|
||||
# init: first registration, multiple registration
|
||||
# actions loaded and added correctly
|
||||
# new: new actions added
|
||||
# old actions removed
|
||||
# delete: all actions removed if not required anymore
|
||||
testInit: ( test ) ->
|
||||
testInitAddDeleteMultiple: ( test ) ->
|
||||
test.expect 2 + 2 * oRuleReal.actions.length + oRuleRealTwo.actions.length
|
||||
|
||||
db.storeUser oUser
|
||||
test.done()
|
||||
strRuleOne = JSON.stringify oRuleOne
|
||||
strRuleTwo = JSON.stringify oRuleTwo
|
||||
strRuleReal = JSON.stringify oRuleReal
|
||||
|
||||
db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
|
||||
db.storeRule oRuleOne.id, strRuleOne
|
||||
db.linkRule oRuleOne.id, oUser.username
|
||||
db.activateRule oRuleOne.id, oUser.username
|
||||
|
||||
db.storeRule oRuleTwo.id, strRuleTwo
|
||||
db.linkRule oRuleTwo.id, oUser.username
|
||||
db.activateRule oRuleTwo.id, oUser.username
|
||||
|
||||
db.storeRule oRuleReal.id, strRuleReal
|
||||
db.storeRule oRuleReal.id, JSON.stringify oRuleReal
|
||||
db.linkRule oRuleReal.id, oUser.username
|
||||
db.activateRule oRuleReal.id, oUser.username
|
||||
db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
db.actionInvokers.storeModule oUser.username, oAiTwo
|
||||
|
||||
db.getAllActivatedRuleIdsPerUser ( err, obj ) =>
|
||||
@existingRules = obj
|
||||
console.log 'existing'
|
||||
console.log obj
|
||||
test.strictEqual listRules[oUser.username], undefined, 'Initial user object exists!?'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
|
||||
fWaitForPersistence = () ->
|
||||
|
||||
for act in oRuleReal.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username].actions[mod], 'Missing action!'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'init'
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
rule: oRuleRealTwo
|
||||
|
||||
fCheckRules = () ->
|
||||
db.getAllActivatedRuleIdsPerUser ( err, obj ) =>
|
||||
console.log 'after init'
|
||||
console.log obj
|
||||
console.log @existingRules is obj
|
||||
fWaitAgainForPersistence = () ->
|
||||
|
||||
for act in oRuleRealTwo.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username].actions[mod], 'Missing action!'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleRealTwo
|
||||
|
||||
for act in oRuleReal.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username].actions[mod], 'Missing action!'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
|
||||
test.strictEqual listRules[oUser.username], undefined, 'Final user object exists!?'
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitAgainForPersistence, 200
|
||||
|
||||
setTimeout fWaitForPersistence, 200
|
||||
|
||||
# #TODO
|
||||
# testUpdate: ( test ) ->
|
||||
# test.expect 0
|
||||
|
||||
# test.done()
|
||||
|
||||
# db.storeUser oUser
|
||||
# db.storeRule oRuleReal.id, JSON.stringify oRuleReal
|
||||
# db.linkRule oRuleReal.id, oUser.username
|
||||
# db.activateRule oRuleReal.id, oUser.username
|
||||
# db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
|
||||
|
||||
# db.getAllActivatedRuleIdsPerUser ( err, obj ) ->
|
||||
# console.log 'existing'
|
||||
# console.log obj
|
||||
|
||||
# engine.internalEvent
|
||||
# event: 'init'
|
||||
# user: oUser.username
|
||||
# rule: oRuleReal
|
||||
|
||||
# fCheckRules = () ->
|
||||
# db.getAllActivatedRuleIdsPerUser ( err, obj ) ->
|
||||
# console.log 'after init'
|
||||
# console.log obj
|
||||
|
||||
# setTimeout fCheckRules, 500
|
||||
|
||||
exports.engine =
|
||||
matchingEvent: ( test ) ->
|
||||
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleReal.id, JSON.stringify oRuleReal
|
||||
db.linkRule oRuleReal.id, oUser.username
|
||||
db.activateRule oRuleReal.id, oUser.username
|
||||
db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
|
||||
fWaitForPersistence = () ->
|
||||
evt = objects.events.eventReal
|
||||
evt.eventid = 'event_testid'
|
||||
db.pushEvent evt
|
||||
setTimeout fWaitForPersistence, 200
|
||||
setTimeout test.done, 500
|
||||
|
||||
setTimeout fCheckRules, 500
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
(function() {
|
||||
var fOnLoad;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
(function() {
|
||||
var fOnLoad;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
// Generated by CoffeeScript 1.7.1
|
||||
(function() {
|
||||
var fOnLoad, strPublicKey;
|
||||
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
table.append(tr);
|
||||
if ($('#ap_' + arrAI[0]).length === 0) {
|
||||
div = $('<div>').attr('id', 'ap_' + arrAI[0]);
|
||||
div.append($('<div> ').attr('class', 'underlined').text(arrAI[0]));
|
||||
div.append($('<div> ')).attr('class', 'underlined').text(arrAI[0]);
|
||||
$('#action_params').append(div);
|
||||
fFetchActionParams(div, arrAI[0]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue