### 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. ### # **Loads Modules:** # - [Persistence](persistence.html) db = require './persistence' # - [Dynamic Modules](dynamic-modules.html) dynmod = require './dynamic-modules' # - Node.js Modules: [fs](http://nodejs.org/api/fs.html), # [path](http://nodejs.org/api/path.html) and # [events](http://nodejs.org/api/events.html) 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 = ( args ) => @log = args.logger db args dynmod args module.exports ### Add an event handler (eh) that listens for rules. @public addRuleListener ( *eh* ) @param {function} eh ### exports.addRuleListener = ( eh ) => eventEmitter.addListener 'rule', eh # Fetch all active rules per user db.getAllActivatedRuleIdsPerUser ( err, objUsers ) -> # Go through all rules of each user fGoThroughUsers = ( user, rules ) -> # Fetch the rules object for each rule in each user fFetchRule = ( userName ) -> ( rule ) -> db.getRule rule, ( err, strRule ) => try oRule = JSON.parse strRule db.resetLog userName, oRule.id db.appendLog userName, oRule.id, "INIT", "Rule '#{ oRule.id }' initialized" eventEmitter.emit 'rule', event: 'init' user: userName rule: oRule catch err @log.warn "CM | There's an invalid rule in the system: #{ strRule }" # Go through all rules for each user fFetchRule( user ) rule for rule in rules # Go through each user fGoThroughUsers user, rules for user, rules of objUsers ### 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 = ( user, oReq, callback ) -> if not oReq.payload oReq.payload = '{}' try dat = JSON.parse oReq.payload catch err return callback code: 404 message: 'You had a strange payload in your request!' if commandFunctions[oReq.command] # If the command function was registered we invoke it commandFunctions[oReq.command] user, dat, callback else 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 = ( arrParams, oPayload ) -> answ = code: 400 message: "Your request didn't contain all necessary fields! Requires: #{ arrParams.join() }" return answ for param in arrParams when not oPayload[param] answ.code = 200 answ.message = 'All required properties found' 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 = ( user, oPayload, dbMod, callback ) -> dbMod.getAvailableModuleIds user.username, ( err, arrNames ) -> oRes = {} answReq = () -> callback code: 200 message: JSON.stringify oRes sem = arrNames.length if sem is 0 answReq() else fGetFunctions = ( id ) => dbMod.getModule id, ( err, oModule ) => if oModule oRes[id] = JSON.parse oModule.functions if --sem is 0 answReq() fGetFunctions id for id in arrNames getModuleParams = ( user, oPayload, dbMod, callback ) -> answ = hasRequiredParams [ 'id' ], oPayload if answ.code isnt 200 callback answ else dbMod.getModuleParams oPayload.id, ( err, oPayload ) -> answ.message = oPayload callback answ forgeModule = ( user, oPayload, dbMod, callback ) => answ = hasRequiredParams [ 'id', 'params', 'lang', 'data' ], oPayload if answ.code isnt 200 callback answ else dbMod.getModule oPayload.id, ( err, mod ) => if mod answ.code = 409 answ.message = 'Module name already existing: ' + oPayload.id callback answ else src = oPayload.data dynmod.compileString src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, ( cm ) => answ = cm.answ if answ.code is 200 funcs = [] funcs.push name for name, id of cm.module @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 is 'true' dbMod.publish oPayload.id callback answ commandFunctions = get_public_key: ( user, oPayload, callback ) -> callback code: 200 message: dynmod.getPublicKey() # EVENT POLLERS # ------------- get_event_pollers: ( user, oPayload, callback ) -> getModules user, oPayload, db.eventPollers, callback get_full_event_poller: ( user, oPayload, callback ) -> db.eventPollers.getModule oPayload.id, ( err, obj ) -> callback code: 200 message: JSON.stringify obj get_event_poller_params: ( user, oPayload, callback ) -> getModuleParams user, oPayload, db.eventPollers, callback forge_event_poller: ( user, oPayload, callback ) -> forgeModule user, oPayload, db.eventPollers, callback delete_event_poller: ( user, oPayload, callback ) -> answ = hasRequiredParams [ 'id' ], oPayload if answ.code isnt 200 callback answ else db.eventPollers.deleteModule oPayload.id callback code: 200 message: 'OK!' # ACTION INVOKERS # --------------- get_action_invokers: ( user, oPayload, callback ) -> getModules user, oPayload, db.actionInvokers, callback get_full_action_invoker: ( user, oPayload, callback ) -> answ = hasRequiredParams [ 'id' ], oPayload if answ.code isnt 200 callback answ else db.actionInvokers.getModule oPayload.id, ( err, obj ) -> callback code: 200 message: JSON.stringify obj get_action_invoker_params: ( user, oPayload, callback ) -> getModuleParams user, oPayload, db.actionInvokers, callback get_action_invoker_function_params: ( user, oPayload, callback ) -> answ = hasRequiredParams [ 'id' ], oPayload if answ.code isnt 200 callback answ else db.actionInvokers.getModuleField oPayload.id, 'functionParameters', ( err, obj ) -> callback code: 200 message: obj forge_action_invoker: ( user, oPayload, callback ) -> forgeModule user, oPayload, db.actionInvokers, callback delete_action_invoker: ( user, oPayload, callback ) -> answ = hasRequiredParams [ 'id' ], oPayload if answ.code isnt 200 callback answ else db.actionInvokers.deleteModule oPayload.id callback code: 200 message: 'OK!' # RULES # ----- get_rules: ( user, oPayload, callback ) -> db.getUserLinkedRules user.username, ( err, obj ) -> callback code: 200 message: obj get_rule_log: ( user, oPayload, callback ) -> answ = hasRequiredParams [ 'id' ], oPayload if answ.code isnt 200 callback answ else db.getLog user.username, oPayload.id, ( err, obj ) -> callback code: 200 message: obj # A rule needs to be in following format: # - id # - event # - conditions # - actions forge_rule: ( user, oPayload, callback ) -> answ = hasRequiredParams [ 'id', 'event', 'conditions', 'actions' ], oPayload if answ.code isnt 200 callback answ else db.getRule oPayload.id, ( err, oExisting ) -> if oExisting isnt 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' db.actionInvokers.storeUserParams id, user.username, JSON.stringify params for id, params of arrParams 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' callback answ delete_rule: ( user, oPayload, callback ) -> answ = hasRequiredParams [ 'id' ], oPayload if answ.code isnt 200 callback answ else db.deleteRule oPayload.id eventEmitter.emit 'rule', event: 'del' user: user.username rule: null ruleId: oPayload.id callback code: 200 message: 'OK!'