// Generated by CoffeeScript 1.7.1 /* 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; db = require('./persistence'); dynmod = require('./dynamic-modules'); fs = require('fs'); path = require('path'); events = require('events'); 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); /* Add an event handler (eh) that listens for rules. @public addRuleListener ( *eh* ) @param {function} eh */ 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(userName) { return function(rule) { return db.getRule(rule, (function(_this) { return function(err, strRule) { var oRule; try { oRule = JSON.parse(strRule); db.resetLog(userName, oRule.id); db.appendLog(userName, oRule.id, "INIT", "Rule '" + oRule.id + "' initialized"); return eventEmitter.emit('rule', { event: 'init', user: userName, rule: oRule }); } catch (_error) { err = _error; return _this.log.warn("CM | There's an invalid rule in the system: " + strRule); } }; })(this)); }; }; _results = []; for (_i = 0, _len = rules.length; _i < _len; _i++) { rule = rules[_i]; _results.push(fFetchRule(user)(rule)); } 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. - `user` is the user object as it comes from the DB. - `oReq` is the request object that contains: - `command` as a string - `payload` an optional stringified JSON object The callback function `callback( obj )` will receive an object containing the HTTP response code and a corresponding message. @public processRequest ( *user, oReq, callback* ) */ exports.processRequest = function(user, oReq, callback) { var dat, err; if (!oReq.payload) { oReq.payload = '{}'; } try { dat = JSON.parse(oReq.payload); } catch (_error) { err = _error; return callback({ code: 404, message: 'You had a strange payload in your request!' }); } if (commandFunctions[oReq.command]) { return commandFunctions[oReq.command](user, dat, callback); } else { return callback({ code: 404, message: 'What do you want from me?' }); } }; /* Checks whether all required parameters are present in the payload. @private hasRequiredParams ( *arrParams, oPayload* ) @param {Array} arrParams @param {Object} oPayload */ hasRequiredParams = function(arrParams, oPayload) { var answ, param, _i, _len; answ = { code: 400, message: "Your request didn't contain all necessary fields! Requires: " + (arrParams.join()) }; for (_i = 0, _len = arrParams.length; _i < _len; _i++) { param = arrParams[_i]; if (!oPayload[param]) { return answ; } } answ.code = 200; answ.message = 'All required properties found'; return answ; }; /* Fetches all available modules and return them together with the available functions. @private getModules ( *user, oPayload, dbMod, callback* ) @param {Object} user @param {Object} oPayload @param {Object} dbMod @param {function} callback */ getModules = function(user, oPayload, dbMod, callback) { return dbMod.getAvailableModuleIds(user.username, function(err, arrNames) { var answReq, fGetFunctions, id, oRes, sem, _i, _len, _results; oRes = {}; answReq = function() { return callback({ code: 200, message: JSON.stringify(oRes) }); }; sem = arrNames.length; if (sem === 0) { return answReq(); } else { 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]; _results.push(fGetFunctions(id)); } return _results; } }); }; getModuleParams = function(user, oPayload, dbMod, callback) { var answ; answ = hasRequiredParams(['id'], oPayload); if (answ.code !== 200) { return callback(answ); } else { return dbMod.getModuleParams(oPayload.id, function(err, oPayload) { answ.message = oPayload; return callback(answ); }); } }; 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 src; if (mod) { answ.code = 409; answ.message = 'Module name already existing: ' + oPayload.id; return callback(answ); } else { src = oPayload.data; return dynmod.compileString(src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, function(cm) { var funcs, id, name, _ref; 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 = " Module " + oPayload.id + " successfully stored! Found following function(s): " + funcs; oPayload.functions = JSON.stringify(funcs); oPayload.functionParameters = JSON.stringify(cm.funcParams); dbMod.storeModule(user.username, oPayload); if (oPayload["public"] === 'true') { dbMod.publish(oPayload.id); } } return callback(answ); }); } }); } }; })(this); commandFunctions = { get_public_key: function(user, oPayload, callback) { return callback({ code: 200, message: dynmod.getPublicKey() }); }, get_event_pollers: function(user, oPayload, callback) { return getModules(user, oPayload, db.eventPollers, callback); }, get_full_event_poller: function(user, oPayload, callback) { return db.eventPollers.getModule(oPayload.id, function(err, obj) { return callback({ code: 200, message: JSON.stringify(obj) }); }); }, get_event_poller_params: function(user, oPayload, callback) { return getModuleParams(user, oPayload, db.eventPollers, callback); }, forge_event_poller: function(user, oPayload, callback) { return forgeModule(user, oPayload, db.eventPollers, callback); }, delete_event_poller: function(user, oPayload, callback) { var answ; answ = hasRequiredParams(['id'], oPayload); if (answ.code !== 200) { return callback(answ); } else { db.eventPollers.deleteModule(oPayload.id); return callback({ code: 200, message: 'OK!' }); } }, get_action_invokers: function(user, oPayload, callback) { return getModules(user, oPayload, db.actionInvokers, callback); }, get_full_action_invoker: function(user, oPayload, callback) { var answ; answ = hasRequiredParams(['id'], oPayload); if (answ.code !== 200) { return callback(answ); } else { return db.actionInvokers.getModule(oPayload.id, function(err, obj) { return callback({ code: 200, message: JSON.stringify(obj) }); }); } }, get_action_invoker_params: function(user, oPayload, callback) { return getModuleParams(user, oPayload, db.actionInvokers, callback); }, get_action_invoker_function_params: function(user, oPayload, callback) { var answ; answ = hasRequiredParams(['id'], oPayload); if (answ.code !== 200) { return callback(answ); } else { return db.actionInvokers.getModuleField(oPayload.id, 'functionParameters', function(err, obj) { return callback({ code: 200, message: obj }); }); } }, forge_action_invoker: function(user, oPayload, callback) { return forgeModule(user, oPayload, db.actionInvokers, callback); }, delete_action_invoker: function(user, oPayload, callback) { var answ; answ = hasRequiredParams(['id'], oPayload); if (answ.code !== 200) { return callback(answ); } else { db.actionInvokers.deleteModule(oPayload.id); return callback({ code: 200, message: 'OK!' }); } }, get_rules: function(user, oPayload, callback) { return db.getUserLinkedRules(user.username, function(err, obj) { return callback({ code: 200, message: obj }); }); }, get_rule_log: function(user, oPayload, callback) { var answ; answ = hasRequiredParams(['id'], oPayload); if (answ.code !== 200) { return callback(answ); } else { return db.getLog(user.username, oPayload.id, function(err, obj) { return callback({ code: 200, message: obj }); }); } }, forge_rule: function(user, oPayload, callback) { var answ; answ = hasRequiredParams(['id', 'event', 'conditions', 'actions'], oPayload); if (answ.code !== 200) { return callback(answ); } else { return db.getRule(oPayload.id, function(err, oExisting) { var arrParams, epModId, id, params, rule, strRule; if (oExisting !== null) { answ = { code: 409, message: 'Rule name already existing!' }; } else { console.log('new ruke'); rule = { id: oPayload.id, event: oPayload.event, conditions: oPayload.conditions, actions: oPayload.actions }; strRule = JSON.stringify(rule); console.log('stringified'); db.storeRule(rule.id, strRule); console.log('stored'); db.linkRule(rule.id, user.username); console.log('linked'); db.activateRule(rule.id, user.username); console.log('activated'); if (oPayload.event_params) { epModId = rule.event.split(' -> ')[0]; db.eventPollers.storeUserParams(epModId, user.username, oPayload.event_params); } console.log('event params loaded'); arrParams = oPayload.action_params; console.log('arractionparams'); for (id in arrParams) { params = arrParams[id]; db.actionInvokers.storeUserParams(id, user.username, JSON.stringify(params)); } console.log('action aprams stored'); db.resetLog(user.username, rule.id); db.appendLog(user.username, rule.id, "INIT", "Rule '" + rule.id + "' initialized"); eventEmitter.emit('rule', { event: 'new', user: user.username, rule: rule }); answ = { code: 200, message: "Rule '" + rule.id + "' stored and activated!" }; console.log('done'); } return callback(answ); }); } }, delete_rule: function(user, oPayload, callback) { var answ; answ = hasRequiredParams(['id'], oPayload); if (answ.code !== 200) { return callback(answ); } else { db.deleteRule(oPayload.id); eventEmitter.emit('rule', { event: 'del', user: user.username, rule: null, ruleId: oPayload.id }); return callback({ code: 200, message: 'OK!' }); } } }; }).call(this);