mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-05-10 08:14:54 +00:00
Huge refactoring of architecture started
This commit is contained in:
parent
92ab16ba74
commit
264ef6eeb6
25 changed files with 742 additions and 411 deletions
|
|
@ -7,26 +7,26 @@ Configuration
|
||||||
###
|
###
|
||||||
|
|
||||||
# **Requires:**
|
# **Requires:**
|
||||||
|
|
||||||
# - [Logging](logging.html)
|
|
||||||
log = require './logging'
|
|
||||||
|
|
||||||
# - Node.js Modules: [fs](http://nodejs.org/api/fs.html) and
|
# - Node.js Modules: [fs](http://nodejs.org/api/fs.html) and
|
||||||
# [path](http://nodejs.org/api/path.html)
|
# [path](http://nodejs.org/api/path.html)
|
||||||
fs = require 'fs'
|
fs = require 'fs'
|
||||||
path = require 'path'
|
path = require 'path'
|
||||||
|
|
||||||
###
|
###
|
||||||
##Module call
|
Module call
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Calling the module as a function will act as a constructor and load the config file.
|
||||||
|
It is possible to hand an args object with the properties nolog (true if no outputs shall
|
||||||
|
be generated) and configPath for a custom configuration file path.
|
||||||
|
|
||||||
Calling the module as a function will make it look for the `configPath` property in the
|
|
||||||
args object and then try to load a config file from that relative path.
|
|
||||||
@param {Object} args
|
@param {Object} args
|
||||||
###
|
###
|
||||||
exports = module.exports = ( args ) ->
|
exports = module.exports = ( args ) =>
|
||||||
args = args ? {}
|
args = args ? {}
|
||||||
log args
|
if args.nolog
|
||||||
if typeof args.configPath is 'string'
|
@nolog = true
|
||||||
|
if args.configPath
|
||||||
loadConfigFile args.configPath
|
loadConfigFile args.configPath
|
||||||
else
|
else
|
||||||
loadConfigFile path.join 'config', 'config.json'
|
loadConfigFile path.join 'config', 'config.json'
|
||||||
|
|
@ -41,20 +41,25 @@ Reads the config file synchronously from the file system and try to parse it.
|
||||||
###
|
###
|
||||||
loadConfigFile = ( configPath ) =>
|
loadConfigFile = ( configPath ) =>
|
||||||
@config = null
|
@config = null
|
||||||
|
confProperties = [
|
||||||
|
'log'
|
||||||
|
'http-port'
|
||||||
|
'db-port'
|
||||||
|
'crypto-key'
|
||||||
|
]
|
||||||
|
#TODO Try to get rid of crypto key
|
||||||
try
|
try
|
||||||
@config = JSON.parse fs.readFileSync path.resolve __dirname, '..', configPath
|
@config = JSON.parse fs.readFileSync path.resolve __dirname, '..', configPath
|
||||||
if @config and @config.http_port and @config.db_port and
|
isReady = true
|
||||||
@config.crypto_key and @config.session_secret
|
for prop in confProperties
|
||||||
log.print 'CF', 'config file loaded successfully'
|
if !@config[prop]
|
||||||
else
|
isReady = false
|
||||||
log.error 'CF', new Error """Missing property in config file, requires:
|
if not isReady and not @nolog
|
||||||
- http_port
|
console.error """Missing property in config file, requires:
|
||||||
- db_port
|
- #{ confProperties.join "\n -" }"""
|
||||||
- crypto_key
|
|
||||||
- session_secret"""
|
|
||||||
catch e
|
catch e
|
||||||
e.addInfo = 'no config ready'
|
if not @nolog
|
||||||
log.error 'CF', e
|
console.error "Failed loading config file: #{ e.message }"
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
@ -77,25 +82,25 @@ exports.isReady = => @config?
|
||||||
|
|
||||||
@public getHttpPort()
|
@public getHttpPort()
|
||||||
###
|
###
|
||||||
exports.getHttpPort = -> fetchProp 'http_port'
|
exports.getHttpPort = -> fetchProp 'http-port'
|
||||||
|
|
||||||
###
|
###
|
||||||
***Returns*** the DB port*
|
***Returns*** the DB port*
|
||||||
|
|
||||||
@public getDBPort()
|
@public getDBPort()
|
||||||
###
|
###
|
||||||
exports.getDBPort = -> fetchProp 'db_port'
|
exports.getDBPort = -> fetchProp 'db-port'
|
||||||
|
|
||||||
|
###
|
||||||
|
***Returns*** the log conf object
|
||||||
|
|
||||||
|
@public getLogConf()
|
||||||
|
###
|
||||||
|
exports.getLogConf = -> fetchProp 'log'
|
||||||
|
|
||||||
###
|
###
|
||||||
***Returns*** the crypto key
|
***Returns*** the crypto key
|
||||||
|
|
||||||
@public getCryptoKey()
|
@public getCryptoKey()
|
||||||
###
|
###
|
||||||
exports.getCryptoKey = -> fetchProp 'crypto_key'
|
exports.getCryptoKey = -> fetchProp 'crypto-key'
|
||||||
|
|
||||||
###
|
|
||||||
***Returns*** the session secret
|
|
||||||
|
|
||||||
@public getSessionSecret()
|
|
||||||
###
|
|
||||||
exports.getSessionSecret = -> fetchProp 'session_secret'
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ log = require './logging'
|
||||||
|
|
||||||
# - [Config](config.html)
|
# - [Config](config.html)
|
||||||
config = require './config'
|
config = require './config'
|
||||||
|
# TODO remove config
|
||||||
|
|
||||||
# - [User Handler](user_handler.html)
|
# - [User Handler](user_handler.html)
|
||||||
requestHandler = require './request_handler'
|
requestHandler = require './request_handler'
|
||||||
|
|
@ -53,10 +54,14 @@ Adds the shutdown handler to the admin commands.
|
||||||
@public addHandlers( *fShutDown* )
|
@public addHandlers( *fShutDown* )
|
||||||
###
|
###
|
||||||
exports.addHandlers = ( fShutDown ) ->
|
exports.addHandlers = ( fShutDown ) ->
|
||||||
requestHandler.addHandlers fShutDown
|
requestHandler.addShutdownHandler fShutDown
|
||||||
# Add cookie support for session handling.
|
# Add cookie support for session handling.
|
||||||
app.use express.cookieParser()
|
app.use express.cookieParser()
|
||||||
app.use express.session { secret: config.getSessionSecret() }
|
#TODO This needs to be fixed!
|
||||||
|
sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw"
|
||||||
|
app.use express.session { secret: sess_sec }
|
||||||
|
# app.use express.session { secret: config.getSessionSecret() }
|
||||||
|
|
||||||
#At the moment there's no redis session backbone (didn't work straight away)
|
#At the moment there's no redis session backbone (didn't work straight away)
|
||||||
log.print 'HL', 'no session backbone'
|
log.print 'HL', 'no session backbone'
|
||||||
|
|
||||||
|
|
|
||||||
59
coffee/new_logging.coffee
Normal file
59
coffee/new_logging.coffee
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
# =======
|
||||||
|
# A Helper to handle logging.
|
||||||
|
|
||||||
|
# **Requires:**
|
||||||
|
# - Node.js Module(s): [path](http://nodejs.org/api/path.html)
|
||||||
|
path = require 'path'
|
||||||
|
|
||||||
|
# - External Module(s): [bunyan](https://github.com/trentm/node-bunyan)
|
||||||
|
bunyan = require 'bunyan'
|
||||||
|
|
||||||
|
###
|
||||||
|
Module call
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Calling the module as a function will act as a constructor and load the config file.
|
||||||
|
It is possible to hand an args object with the properties nolog (true if no outputs shall
|
||||||
|
be generated) and configPath for a custom configuration file path.
|
||||||
|
|
||||||
|
@param {Object} args
|
||||||
|
###
|
||||||
|
exports = module.exports = ( args ) =>
|
||||||
|
emptylog =
|
||||||
|
{
|
||||||
|
info: () ->
|
||||||
|
warn: () ->
|
||||||
|
error: () ->
|
||||||
|
}
|
||||||
|
args = args ? {}
|
||||||
|
if args.nolog
|
||||||
|
emptylog
|
||||||
|
else
|
||||||
|
try
|
||||||
|
opt =
|
||||||
|
name: "webapi-eca"
|
||||||
|
if args['mode'] is 'development'
|
||||||
|
opt.src = true
|
||||||
|
if args['file-path']
|
||||||
|
@logPath = path.resolve __dirname, '..', 'logs', args['file-path']
|
||||||
|
else
|
||||||
|
@logPath = path.resolve __dirname, '..', 'logs', 'server.log'
|
||||||
|
opt.streams = [
|
||||||
|
{
|
||||||
|
level: args['io-level']
|
||||||
|
stream: process.stdout
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: args['file-level']
|
||||||
|
type: 'rotating-file'
|
||||||
|
path: @logPath
|
||||||
|
period: '1d'
|
||||||
|
count: 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
bunyan.createLogger opt
|
||||||
|
catch e
|
||||||
|
console.error e
|
||||||
|
emptylog
|
||||||
|
|
@ -845,4 +845,4 @@ Shuts down the db link.
|
||||||
|
|
||||||
@public shutDown()
|
@public shutDown()
|
||||||
###
|
###
|
||||||
exports.shutDown = => @db.quit()
|
exports.shutDown = () => @db.quit()
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,6 @@ qs = require 'querystring'
|
||||||
mustache = require 'mustache'
|
mustache = require 'mustache'
|
||||||
crypto = require 'crypto-js'
|
crypto = require 'crypto-js'
|
||||||
|
|
||||||
# Prepare the admin command handlers which are invoked via HTTP requests.
|
|
||||||
objAdminCmds =
|
|
||||||
'loadrules': mm.loadRulesFromFS
|
|
||||||
'loadaction': mm.loadActionModuleFromFS
|
|
||||||
'loadactions': mm.loadActionModulesFromFS
|
|
||||||
'loadevent': mm.loadEventModuleFromFS
|
|
||||||
'loadevents': mm.loadEventModulesFromFS
|
|
||||||
|
|
||||||
# Prepare the user command handlers which are invoked via HTTP requests.
|
# Prepare the user command handlers which are invoked via HTTP requests.
|
||||||
objUserCmds =
|
objUserCmds =
|
||||||
'store_action': mm.storeActionModule
|
'store_action': mm.storeActionModule
|
||||||
|
|
@ -57,15 +49,14 @@ exports = module.exports = ( args ) ->
|
||||||
module.exports
|
module.exports
|
||||||
|
|
||||||
###
|
###
|
||||||
This allows the parent to add handlers. The event handler will receive
|
This allows the parent to add the shutdown handler.
|
||||||
the events that were received. The shutdown function will be called if the
|
The shutdown function will be called if the admin command shutdown is issued.
|
||||||
admin command shutdown is issued.
|
|
||||||
|
|
||||||
@public addHandlers( *fShutdown* )
|
@public addShutdownHandler( *fShutdown* )
|
||||||
@param {function} fShutdown
|
@param {function} fShutdown
|
||||||
###
|
###
|
||||||
exports.addHandlers = ( fShutdown ) =>
|
exports.addShutdownHandler = ( fShutdown ) =>
|
||||||
objAdminCmds.shutdown = ( args, answerHandler ) ->
|
@objAdminCmds.shutdown = ( args, answerHandler ) ->
|
||||||
answerHandler.answerSuccess 'Shutting down... BYE!'
|
answerHandler.answerSuccess 'Shutting down... BYE!'
|
||||||
setTimeout fShutdown, 500
|
setTimeout fShutdown, 500
|
||||||
|
|
||||||
|
|
@ -284,13 +275,13 @@ objects.*
|
||||||
|
|
||||||
@public handleAdmin( *req, resp* )
|
@public handleAdmin( *req, resp* )
|
||||||
###
|
###
|
||||||
exports.handleAdmin = ( req, resp ) ->
|
exports.handleAdmin = ( req, resp ) =>
|
||||||
if req.session and req.session.user
|
if req.session and req.session.user
|
||||||
if req.session.user.isAdmin is "true"
|
if req.session.user.isAdmin is "true"
|
||||||
q = req.query
|
q = req.query
|
||||||
log.print 'RH', 'Received admin request: ' + req.originalUrl
|
log.print 'RH', 'Received admin request: ' + req.originalUrl
|
||||||
if q.cmd
|
if q.cmd
|
||||||
objAdminCmds[q.cmd]? q, answerHandler req, resp, true
|
@objAdminCmds[q.cmd]? q, answerHandler req, resp, true
|
||||||
else
|
else
|
||||||
resp.send 404, 'Command unknown!'
|
resp.send 404, 'Command unknown!'
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -5,26 +5,15 @@ Server
|
||||||
|
|
||||||
>This is the main module that is used to run the whole server:
|
>This is the main module that is used to run the whole server:
|
||||||
>
|
>
|
||||||
> node server [log_type http_port]
|
> node server [opt]
|
||||||
>
|
>
|
||||||
>Valid `log_type`'s are:
|
> See below in the optimist CLI preparation for allowed optional parameters
|
||||||
>
|
|
||||||
>- `0`: standard I/O output (default)
|
|
||||||
>- `1`: log file (server.log)
|
|
||||||
>- `2`: silent
|
|
||||||
>
|
|
||||||
>`http_port` can be set to use another port, than defined in the
|
|
||||||
>[config](config.html) file, to listen to, e.g. used by the test suite.
|
|
||||||
>
|
|
||||||
>
|
|
||||||
|
|
||||||
TODO how about we allow spawning child processes with servers based on address?
|
|
||||||
###
|
###
|
||||||
|
|
||||||
# **Requires:**
|
# **Requires:**
|
||||||
|
|
||||||
# - [Logging](logging.html)
|
# - [Logging](logging.html)
|
||||||
log = require './logging'
|
logger = require './new_logging'
|
||||||
|
|
||||||
# - [Configuration](config.html)
|
# - [Configuration](config.html)
|
||||||
conf = require './config'
|
conf = require './config'
|
||||||
|
|
@ -38,9 +27,54 @@ engine = require './engine'
|
||||||
# - [HTTP Listener](http_listener.html)
|
# - [HTTP Listener](http_listener.html)
|
||||||
http_listener = require './http_listener'
|
http_listener = require './http_listener'
|
||||||
|
|
||||||
args = {}
|
# - Node.js Modules: [fs](http://nodejs.org/api/fs.html),
|
||||||
|
# [path](http://nodejs.org/api/path.html)
|
||||||
|
# and [child_process](http://nodejs.org/api/child_process.html)
|
||||||
|
fs = require 'fs'
|
||||||
|
path = require 'path'
|
||||||
|
cp = require 'child_process'
|
||||||
|
|
||||||
|
# - External Module: [optimist](https://github.com/substack/node-optimist)
|
||||||
|
optimist = require 'optimist'
|
||||||
|
|
||||||
procCmds = {}
|
procCmds = {}
|
||||||
|
|
||||||
|
###
|
||||||
|
Let's prepare the optimist CLI
|
||||||
|
###
|
||||||
|
usage = 'This runs your webapi-based ECA engine'
|
||||||
|
opt =
|
||||||
|
'h':
|
||||||
|
alias : 'help',
|
||||||
|
describe: 'Display this'
|
||||||
|
'c':
|
||||||
|
alias : 'config-path',
|
||||||
|
describe: 'Specify a path to a custom configuration file, other than "config/config.json"'
|
||||||
|
'w':
|
||||||
|
alias : 'http-port',
|
||||||
|
describe: 'Specify a HTTP port for the web server'
|
||||||
|
'd':
|
||||||
|
alias : 'db-port',
|
||||||
|
describe: 'Specify a port for the redis DB'
|
||||||
|
'm':
|
||||||
|
alias : 'log-mode',
|
||||||
|
describe: 'Specify a log mode: [development|productive]'
|
||||||
|
'i':
|
||||||
|
alias : 'log-io-level',
|
||||||
|
describe: 'Specify the log level for the I/O'
|
||||||
|
'f':
|
||||||
|
alias : 'log-file-level',
|
||||||
|
describe: 'Specify the log level for the log file'
|
||||||
|
'p':
|
||||||
|
alias : 'log-file-path',
|
||||||
|
describe: 'Specify the path to the log file within the "logs" folder'
|
||||||
|
'n':
|
||||||
|
alias : 'nolog',
|
||||||
|
describe: 'Set this if no output shall be generated'
|
||||||
|
argv = optimist.usage( usage ).options( opt ).argv
|
||||||
|
if argv.help
|
||||||
|
console.log optimist.help()
|
||||||
|
process.exit()
|
||||||
|
|
||||||
###
|
###
|
||||||
Error handling of the express port listener requires special attention,
|
Error handling of the express port listener requires special attention,
|
||||||
|
|
@ -50,7 +84,7 @@ the port is already in use.
|
||||||
process.on 'uncaughtException', ( err ) ->
|
process.on 'uncaughtException', ( err ) ->
|
||||||
switch err.errno
|
switch err.errno
|
||||||
when 'EADDRINUSE'
|
when 'EADDRINUSE'
|
||||||
err.addInfo = 'http_port already in use, shutting down!'
|
err.addInfo = 'http-port already in use, shutting down!'
|
||||||
log.error 'RS', err
|
log.error 'RS', err
|
||||||
shutDown()
|
shutDown()
|
||||||
# else log.error 'RS', err
|
# else log.error 'RS', err
|
||||||
|
|
@ -61,50 +95,63 @@ This function is invoked right after the module is loaded and starts the server.
|
||||||
@private init()
|
@private init()
|
||||||
###
|
###
|
||||||
init = ->
|
init = ->
|
||||||
log.print 'RS', 'STARTING SERVER'
|
conf argv.c
|
||||||
conf args
|
|
||||||
# > Check whether the config file is ready, which is required to start the server.
|
# > Check whether the config file is ready, which is required to start the server.
|
||||||
if !conf.isReady()
|
if !conf.isReady()
|
||||||
log.error 'RS', 'Config file not ready!'
|
console.error 'FAIL: Config file not ready! Shutting down...'
|
||||||
process.exit()
|
process.exit()
|
||||||
|
|
||||||
# > Fetch the `log_type` argument and post a log about which log type is used.
|
logconf = conf.getLogConf()
|
||||||
if process.argv.length > 2
|
if argv.m
|
||||||
args.logType = parseInt(process.argv[2]) || 0
|
logconf[ 'mode' ] = argv.m
|
||||||
switch args.logType
|
if argv.i
|
||||||
when 0 then log.print 'RS', 'Log type set to standard I/O output'
|
logconf[ 'io-level' ] = argv.i
|
||||||
when 1 then log.print 'RS', 'Log type set to file output'
|
if argv.f
|
||||||
when 2 then log.print 'RS', 'Log type set to silent'
|
logconf[ 'file-level' ] = argv.f
|
||||||
else log.print 'RS', 'Unknown log type, using standard I/O'
|
if argv.p
|
||||||
log args
|
logconf[ 'file-path' ] = argv.p
|
||||||
else
|
if argv.n
|
||||||
log.print 'RS', 'No log method argument provided, using standard I/O'
|
logconf[ 'nolog' ] = argv.n
|
||||||
|
try
|
||||||
|
fs.unlinkSync path.resolve __dirname, '..', 'logs', logconf[ 'file-path' ]
|
||||||
|
log = logger logconf
|
||||||
|
log.info 'RS | STARTING SERVER'
|
||||||
|
|
||||||
# > Fetch the `http_port` argument
|
args =
|
||||||
if process.argv.length > 3 then args.http_port = parseInt process.argv[3]
|
logger: log
|
||||||
else log.print 'RS', 'No HTTP port passed, using standard port from config file'
|
logconf: logconf
|
||||||
|
# > Fetch the `http-port` argument
|
||||||
|
args[ 'http-port' ] = parseInt argv.w || conf.getHttpPort()
|
||||||
|
|
||||||
log.print 'RS', 'Initialzing DB'
|
log.info 'RS | Initialzing DB'
|
||||||
db args
|
db args
|
||||||
# > We only proceed with the initialization if the DB is ready
|
# > We only proceed with the initialization if the DB is ready
|
||||||
db.isConnected ( err, result ) ->
|
db.isConnected ( err, result ) ->
|
||||||
if !err
|
if !err
|
||||||
|
|
||||||
# > Initialize all required modules with the args object.
|
# > Initialize all required modules with the args object.
|
||||||
log.print 'RS', 'Initialzing engine'
|
log.info 'RS | Initialzing engine'
|
||||||
engine args
|
engine args
|
||||||
log.print 'RS', 'Initialzing http listener'
|
log.info 'RS | Initialzing http listener'
|
||||||
http_listener args
|
http_listener args
|
||||||
|
|
||||||
# > Distribute handlers between modules to link the application.
|
# > Distribute handlers between modules to link the application.
|
||||||
log.print 'RS', 'Passing handlers to engine'
|
log.info 'RS | Passing handlers to engine'
|
||||||
engine.addPersistence db
|
engine.addPersistence db
|
||||||
log.print 'RS', 'Passing handlers to http listener'
|
log.info 'RS | Passing handlers to http listener'
|
||||||
#TODO engine pushEvent needs to go into redis queue
|
#TODO engine pushEvent needs to go into redis queue
|
||||||
http_listener.addHandlers shutDown
|
http_listener.addShutdownHandler shutDown
|
||||||
#log.print 'RS', 'Passing handlers to module manager'
|
|
||||||
#TODO loadAction and addRule will be removed
|
#TODO loadAction and addRule will be removed
|
||||||
#mm.addHandlers db, engine.loadActionModule, engine.addRule
|
#mm.addHandlers db, engine.loadActionModule, engine.addRule
|
||||||
|
log.info 'RS | For e 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, 'event_poller' ), cliArgs
|
||||||
|
|
||||||
###
|
###
|
||||||
Shuts down the server.
|
Shuts down the server.
|
||||||
|
|
@ -112,7 +159,7 @@ Shuts down the server.
|
||||||
@private shutDown()
|
@private shutDown()
|
||||||
###
|
###
|
||||||
shutDown = ->
|
shutDown = ->
|
||||||
log.print 'RS', 'Received shut down command!'
|
log.warn 'RS | Received shut down command!'
|
||||||
engine?.shutDown()
|
engine?.shutDown()
|
||||||
http_listener?.shutDown()
|
http_listener?.shutDown()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,31 @@ Configuration
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var exports, fetchProp, fs, loadConfigFile, log, path,
|
var exports, fetchProp, fs, loadConfigFile, path,
|
||||||
_this = this;
|
_this = this;
|
||||||
|
|
||||||
log = require('./logging');
|
|
||||||
|
|
||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
|
|
||||||
path = require('path');
|
path = require('path');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
##Module call
|
Module call
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Calling the module as a function will act as a constructor and load the config file.
|
||||||
|
It is possible to hand an args object with the properties nolog (true if no outputs shall
|
||||||
|
be generated) and configPath for a custom configuration file path.
|
||||||
|
|
||||||
Calling the module as a function will make it look for the `configPath` property in the
|
|
||||||
args object and then try to load a config file from that relative path.
|
|
||||||
@param {Object} args
|
@param {Object} args
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
exports = module.exports = function(args) {
|
exports = module.exports = function(args) {
|
||||||
args = args != null ? args : {};
|
args = args != null ? args : {};
|
||||||
log(args);
|
if (args.nolog) {
|
||||||
if (typeof args.configPath === 'string') {
|
_this.nolog = true;
|
||||||
|
}
|
||||||
|
if (args.configPath) {
|
||||||
loadConfigFile(args.configPath);
|
loadConfigFile(args.configPath);
|
||||||
} else {
|
} else {
|
||||||
loadConfigFile(path.join('config', 'config.json'));
|
loadConfigFile(path.join('config', 'config.json'));
|
||||||
|
|
@ -47,19 +50,26 @@ Configuration
|
||||||
|
|
||||||
|
|
||||||
loadConfigFile = function(configPath) {
|
loadConfigFile = function(configPath) {
|
||||||
var e;
|
var confProperties, e, isReady, prop, _i, _len;
|
||||||
_this.config = null;
|
_this.config = null;
|
||||||
|
confProperties = ['log', 'http-port', 'db-port', 'crypto-key'];
|
||||||
try {
|
try {
|
||||||
_this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath)));
|
_this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath)));
|
||||||
if (_this.config && _this.config.http_port && _this.config.db_port && _this.config.crypto_key && _this.config.session_secret) {
|
isReady = true;
|
||||||
return log.print('CF', 'config file loaded successfully');
|
for (_i = 0, _len = confProperties.length; _i < _len; _i++) {
|
||||||
} else {
|
prop = confProperties[_i];
|
||||||
return log.error('CF', new Error("Missing property in config file, requires:\n- http_port\n- db_port\n- crypto_key\n- session_secret"));
|
if (!_this.config[prop]) {
|
||||||
|
isReady = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isReady && !_this.nolog) {
|
||||||
|
return console.error("Missing property in config file, requires: \n- " + (confProperties.join("\n -")));
|
||||||
}
|
}
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
e = _error;
|
e = _error;
|
||||||
e.addInfo = 'no config ready';
|
if (!_this.nolog) {
|
||||||
return log.error('CF', e);
|
return console.error("Failed loading config file: " + e.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -95,7 +105,7 @@ Configuration
|
||||||
|
|
||||||
|
|
||||||
exports.getHttpPort = function() {
|
exports.getHttpPort = function() {
|
||||||
return fetchProp('http_port');
|
return fetchProp('http-port');
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -106,7 +116,18 @@ Configuration
|
||||||
|
|
||||||
|
|
||||||
exports.getDBPort = function() {
|
exports.getDBPort = function() {
|
||||||
return fetchProp('db_port');
|
return fetchProp('db-port');
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
***Returns*** the log conf object
|
||||||
|
|
||||||
|
@public getLogConf()
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
exports.getLogConf = function() {
|
||||||
|
return fetchProp('log');
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -117,18 +138,7 @@ Configuration
|
||||||
|
|
||||||
|
|
||||||
exports.getCryptoKey = function() {
|
exports.getCryptoKey = function() {
|
||||||
return fetchProp('crypto_key');
|
return fetchProp('crypto-key');
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
***Returns*** the session secret
|
|
||||||
|
|
||||||
@public getSessionSecret()
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
exports.getSessionSecret = function() {
|
|
||||||
return fetchProp('session_secret');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,18 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path'),
|
var path = require('path'),
|
||||||
cp = require('child_process'),
|
|
||||||
log = require('./logging'),
|
log = require('./logging'),
|
||||||
qEvents = new (require('./queue')).Queue(), //TODO export queue into redis
|
// qEvents = new (require('./queue')).Queue(), //TODO export queue into redis
|
||||||
regex = /\$X\.[\w\.\[\]]*/g, // find properties of $X
|
regex = /\$X\.[\w\.\[\]]*/g, // find properties of $X
|
||||||
listRules = {},
|
listRules = {},
|
||||||
listActionModules = {},
|
listActionModules = {},
|
||||||
isRunning = true,
|
isRunning = true,
|
||||||
ml, poller, db;
|
ml, poller, db;
|
||||||
|
|
||||||
exports = module.exports = function(args) {
|
exports = module.exports = function( args ) {
|
||||||
args = args || {};
|
args = args || {};
|
||||||
log(args);
|
log(args);
|
||||||
ml = require('./module_loader')(args);
|
ml = require('./module_loader')(args);
|
||||||
poller = cp.fork(path.resolve(__dirname, 'eventpoller'), [log.getLogType()]);
|
|
||||||
poller.on('message', function(evt) {
|
|
||||||
exports.pushEvent(evt);
|
|
||||||
});
|
|
||||||
return module.exports;
|
return module.exports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,13 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var fs = require('fs'),
|
var logger = require('./new_logging'),
|
||||||
path = require('path'),
|
|
||||||
log = require('./logging'),
|
|
||||||
listMessageActions = {},
|
listMessageActions = {},
|
||||||
listAdminCommands = {},
|
listAdminCommands = {},
|
||||||
listEventModules = {},
|
listEventModules = {},
|
||||||
listPoll = {}, //TODO this will change in the future because it could have
|
listPoll = {}, //TODO this will change in the future because it could have
|
||||||
//several parameterized (user-specific) instances of each event module
|
//several parameterized (user-specific) instances of each event module
|
||||||
|
log,
|
||||||
isRunning = true,
|
isRunning = true,
|
||||||
eId = 0,
|
eId = 0,
|
||||||
db, ml;
|
db, ml;
|
||||||
|
|
@ -18,13 +17,26 @@ var fs = require('fs'),
|
||||||
|
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if(process.argv.length > 2) log({ logType: parseInt(process.argv[2]) || 0 });
|
if(process.argv.length < 7){
|
||||||
var args = { logType: log.getLogType() };
|
console.error('Not all arguments have been passed!');
|
||||||
(ml = require('./module_loader'))(args);
|
process.exit();
|
||||||
(db = require('./db_interface'))(args);
|
}
|
||||||
|
|
||||||
|
var logconf = {}
|
||||||
|
logconf['mode'] = process.argv[2]
|
||||||
|
logconf['io-level'] = process.argv[3]
|
||||||
|
logconf['file-level'] = process.argv[4]
|
||||||
|
logconf['file-path'] = process.argv[5]
|
||||||
|
logconf['nolog'] = process.argv[6]
|
||||||
|
|
||||||
|
log = logger(logconf);
|
||||||
|
var args = { logger: log };
|
||||||
|
(ml = require('./module_manager'))(args);
|
||||||
|
(db = require('./persistence'))(args);
|
||||||
initAdminCommands();
|
initAdminCommands();
|
||||||
initMessageActions();
|
initMessageActions();
|
||||||
pollLoop();
|
pollLoop();
|
||||||
|
log.info('Event Poller instantiated');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -128,11 +140,13 @@ function checkRemotes() {
|
||||||
err.additionalInfo = 'module: ' + p;
|
err.additionalInfo = 'module: ' + p;
|
||||||
log.error('EP', err);
|
log.error('EP', err);
|
||||||
} else {
|
} else {
|
||||||
process.send({
|
// FIXME this needs to be pushed into the db not passed to the process!
|
||||||
event: p,
|
console.error('eventpoller needs to push event into db queue')
|
||||||
eventid: 'polled_' + eId++,
|
// process.send({
|
||||||
payload: obj
|
// event: p,
|
||||||
});
|
// eventid: 'polled_' + eId++,
|
||||||
|
// payload: obj
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})(prop)
|
})(prop)
|
||||||
|
|
@ -54,11 +54,12 @@ HTTP Listener
|
||||||
|
|
||||||
|
|
||||||
exports.addHandlers = function(fShutDown) {
|
exports.addHandlers = function(fShutDown) {
|
||||||
var e, http_port;
|
var e, http_port, sess_sec;
|
||||||
requestHandler.addHandlers(fShutDown);
|
requestHandler.addShutdownHandler(fShutDown);
|
||||||
app.use(express.cookieParser());
|
app.use(express.cookieParser());
|
||||||
|
sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw";
|
||||||
app.use(express.session({
|
app.use(express.session({
|
||||||
secret: config.getSessionSecret()
|
secret: sess_sec
|
||||||
}));
|
}));
|
||||||
log.print('HL', 'no session backbone');
|
log.print('HL', 'no session backbone');
|
||||||
app.use('/', express["static"](path.resolve(__dirname, '..', 'webpages', 'public')));
|
app.use('/', express["static"](path.resolve(__dirname, '..', 'webpages', 'public')));
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
*/
|
*/
|
||||||
//TODO dynamic log file names (especially to track unit test logs)
|
//TODO dynamic log file names (especially to track unit test logs)
|
||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
|
wst = require('winston'),
|
||||||
logTypes = [ flushToConsole, flushToFile, null],
|
logTypes = [ flushToConsole, flushToFile, null],
|
||||||
logFile = require('path').resolve(__dirname, '..', 'server.log'),
|
logFile = require('path').resolve(__dirname, '..', 'server.log'),
|
||||||
logType = 0;
|
logType = 0;
|
||||||
|
|
@ -20,6 +21,8 @@ exports = module.exports = function(args) {
|
||||||
if(args.logType) logType = parseInt(args.logType) || 0;
|
if(args.logType) logType = parseInt(args.logType) || 0;
|
||||||
if(logType == 1) fs.truncateSync(logFile, 0);
|
if(logType == 1) fs.truncateSync(logFile, 0);
|
||||||
if(logType > logTypes.length - 1) logType = 0;
|
if(logType > logTypes.length - 1) logType = 0;
|
||||||
|
// winston.add(winston.transports.File, { filename: 'somefile.log' });
|
||||||
|
// winston.remove(winston.transports.Console);
|
||||||
return module.exports;
|
return module.exports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var fs = require('fs'),
|
|
||||||
path = require('path'),
|
|
||||||
log = require('./logging');
|
|
||||||
|
|
||||||
exports = module.exports = function(args) {
|
|
||||||
args = args || {};
|
|
||||||
log(args);
|
|
||||||
return module.exports;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.requireFromString = function(src, name, dir) {
|
|
||||||
if(!dir) dir = __dirname;
|
|
||||||
var id = path.resolve(dir, name, name + '.vm');
|
|
||||||
var vm = require('vm'),
|
|
||||||
// FIXME not log but debug module is required to provide information to the user
|
|
||||||
sandbox = {
|
|
||||||
id: id, // use this to gather kill info
|
|
||||||
needle: require('needle'),
|
|
||||||
log: log,
|
|
||||||
exports: {}
|
|
||||||
};
|
|
||||||
//TODO child_process to run module!
|
|
||||||
// Define max runtime per loop as 10 seconds, after that the child will be killed
|
|
||||||
// it can still be active after that if there was a timing function or a callback used...
|
|
||||||
// kill the child each time? how to determine whether there's still a token in the module?
|
|
||||||
try {
|
|
||||||
var mod = vm.runInNewContext(src, sandbox, id);
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
log.error('ML', 'Error running module in sandbox: ' + err.message);
|
|
||||||
}
|
|
||||||
return sandbox.exports;
|
|
||||||
};
|
|
||||||
|
|
||||||
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.print('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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -12,12 +12,11 @@
|
||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
log = require('./logging'),
|
log = require('./logging'),
|
||||||
ml, db, funcLoadAction, funcLoadRule;
|
db, funcLoadAction, funcLoadRule;
|
||||||
|
|
||||||
exports = module.exports = function(args) {
|
exports = module.exports = function(args) {
|
||||||
args = args || {};
|
args = args || {};
|
||||||
log(args);
|
log(args);
|
||||||
ml = require('./module_loader')(args);
|
|
||||||
return module.exports;
|
return module.exports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -25,12 +24,82 @@ exports.addDBLink = function(db_link) {
|
||||||
db = db_link;
|
db = db_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.requireFromString = function(src, name, dir) {
|
||||||
|
if(!dir) dir = __dirname;
|
||||||
|
var id = path.resolve(dir, name, name + '.vm');
|
||||||
|
var vm = require('vm'),
|
||||||
|
// FIXME not log but debug module is required to provide information to the user
|
||||||
|
sandbox = {
|
||||||
|
id: id, // use this to gather kill info
|
||||||
|
needle: require('needle'), //https://github.com/tomas/needle
|
||||||
|
log: log,
|
||||||
|
exports: {}
|
||||||
|
};
|
||||||
|
//TODO child_process to run module!
|
||||||
|
// Define max runtime per loop as 10 seconds, after that the child will be killed
|
||||||
|
// it can still be active after that if there was a timing function or a callback used...
|
||||||
|
// kill the child each time? how to determine whether there's still a token in the module?
|
||||||
|
try {
|
||||||
|
var mod = vm.runInNewContext(src, sandbox, id);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
log.error('ML', 'Error running module in sandbox: ' + err.message);
|
||||||
|
}
|
||||||
|
return sandbox.exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
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.print('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) {
|
exports.storeEventModule = function (objUser, obj, answHandler) {
|
||||||
try {
|
try {
|
||||||
// TODO in the future we might want to link the modules close to the user
|
// TODO in the future we might want to link the modules close to the user
|
||||||
// and allow for e.g. private modules
|
// and allow for e.g. private modules
|
||||||
// we need a child process to run this code and kill it after invocation
|
// we need a child process to run this code and kill it after invocation
|
||||||
var m = ml.requireFromString(obj.data, obj.id);
|
var m = exports.requireFromString(obj.data, obj.id);
|
||||||
obj.methods = Object.keys(m);
|
obj.methods = Object.keys(m);
|
||||||
answHandler.answerSuccess('Thank you for the event module!');
|
answHandler.answerSuccess('Thank you for the event module!');
|
||||||
db.storeEventModule(obj.id, obj);
|
db.storeEventModule(obj.id, obj);
|
||||||
|
|
@ -48,7 +117,7 @@ exports.getAllEventModules = function ( objUser, obj, answHandler ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.storeActionModule = function (objUser, obj, answHandler) {
|
exports.storeActionModule = function (objUser, obj, answHandler) {
|
||||||
var m = ml.requireFromString(obj.data, obj.id);
|
var m = exports.requireFromString(obj.data, obj.id);
|
||||||
obj.methods = Object.keys(m);
|
obj.methods = Object.keys(m);
|
||||||
answHandler.answerSuccess('Thank you for the action module!');
|
answHandler.answerSuccess('Thank you for the action module!');
|
||||||
db.storeActionModule(obj.id, obj);
|
db.storeActionModule(obj.id, obj);
|
||||||
|
|
@ -111,100 +180,3 @@ exports.storeRule = function (objUser, obj, answHandler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME REMOVE
|
|
||||||
/*
|
|
||||||
* Legacy file system loaders
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load Rules from fs
|
|
||||||
* ------------------
|
|
||||||
*/
|
|
||||||
exports.loadRulesFromFS = function(args, answHandler) {
|
|
||||||
if(!args) args = {};
|
|
||||||
if(!args.name) args.name = 'rules';
|
|
||||||
if(!funcLoadRule) log.error('ML', 'no rule loader function available');
|
|
||||||
else {
|
|
||||||
fs.readFile(path.resolve(__dirname, '..', 'rules', args.name + '.json'), 'utf8', function (err, data) {
|
|
||||||
if (err) {
|
|
||||||
log.error('ML', 'Loading rules file: ' + args.name + '.json');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
var arr = JSON.parse(data), txt = '';
|
|
||||||
log.print('ML', 'Loading ' + arr.length + ' rules:');
|
|
||||||
for(var i = 0; i < arr.length; i++) {
|
|
||||||
txt += arr[i].id + ', ';
|
|
||||||
db.storeRule(arr[i].id, 'james-t', JSON.stringify(arr[i]));
|
|
||||||
// funcLoadRule(arr[i]);
|
|
||||||
}
|
|
||||||
answHandler.answerSuccess('Yep, loaded rules: ' + txt);
|
|
||||||
} catch (e) {
|
|
||||||
log.error('ML', 'rules file was corrupt! (' + args.name + '.json)');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load Action Modules from fs
|
|
||||||
* ---------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {Object} name
|
|
||||||
* @param {Object} data
|
|
||||||
* @param {Object} mod
|
|
||||||
* @param {String} [auth] The string representation of the auth json
|
|
||||||
*/
|
|
||||||
function loadActionCallback(name, data, mod, auth) {
|
|
||||||
db.storeActionModule(name, data); // store module in db
|
|
||||||
// funcLoadAction(name, mod); // hand back compiled module
|
|
||||||
if(auth) db.storeActionModuleAuth(name, auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.loadActionModuleFromFS = function (args, answHandler) {
|
|
||||||
if(ml) {
|
|
||||||
if(args && args.name) {
|
|
||||||
answHandler.answerSuccess('Loading action module ' + args.name + '...');
|
|
||||||
ml.loadModule('mod_actions', args.name, loadActionCallback);
|
|
||||||
} else log.error('MM', 'Action Module name not provided!');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.loadActionModulesFromFS = function(args, answHandler) {
|
|
||||||
if(ml) {
|
|
||||||
answHandler.answerSuccess('Loading action modules...');
|
|
||||||
ml.loadModules('mod_actions', loadActionCallback);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load Event Modules from fs
|
|
||||||
* --------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
function loadEventCallback(name, data, mod, auth) {
|
|
||||||
if(db) {
|
|
||||||
db.storeEventModule(name, data); // store module in db
|
|
||||||
if(auth) db.storeEventModuleAuth(name, auth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.loadEventModuleFromFS = function(args, answHandler) {
|
|
||||||
if(ml) {
|
|
||||||
if(args && args.name) {
|
|
||||||
answHandler.answerSuccess('Loading event module ' + args.name + '...');
|
|
||||||
ml.loadModule('mod_events', args.name, loadEventCallback);
|
|
||||||
} else log.error('MM', 'Event Module name not provided!');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.loadEventModulesFromFS = function(args, answHandler) {
|
|
||||||
answHandler.answerSuccess('Loading event moules...');
|
|
||||||
ml.loadModules('mod_actions', loadEventCallback);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
||||||
66
js-coffee/new_logging.js
Normal file
66
js-coffee/new_logging.js
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Generated by CoffeeScript 1.6.3
|
||||||
|
(function() {
|
||||||
|
var bunyan, exports, path,
|
||||||
|
_this = this;
|
||||||
|
|
||||||
|
path = require('path');
|
||||||
|
|
||||||
|
bunyan = require('bunyan');
|
||||||
|
|
||||||
|
/*
|
||||||
|
Module call
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Calling the module as a function will act as a constructor and load the config file.
|
||||||
|
It is possible to hand an args object with the properties nolog (true if no outputs shall
|
||||||
|
be generated) and configPath for a custom configuration file path.
|
||||||
|
|
||||||
|
@param {Object} args
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
exports = module.exports = function(args) {
|
||||||
|
var e, emptylog, opt;
|
||||||
|
emptylog = {
|
||||||
|
info: function() {},
|
||||||
|
warn: function() {},
|
||||||
|
error: function() {}
|
||||||
|
};
|
||||||
|
args = args != null ? args : {};
|
||||||
|
if (args.nolog) {
|
||||||
|
return emptylog;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
opt = {
|
||||||
|
name: "webapi-eca"
|
||||||
|
};
|
||||||
|
if (args['mode'] === 'development') {
|
||||||
|
opt.src = true;
|
||||||
|
}
|
||||||
|
if (args['file-path']) {
|
||||||
|
_this.logPath = path.resolve(__dirname, '..', 'logs', args['file-path']);
|
||||||
|
} else {
|
||||||
|
_this.logPath = path.resolve(__dirname, '..', 'logs', 'server.log');
|
||||||
|
}
|
||||||
|
opt.streams = [
|
||||||
|
{
|
||||||
|
level: args['io-level'],
|
||||||
|
stream: process.stdout
|
||||||
|
}, {
|
||||||
|
level: args['file-level'],
|
||||||
|
type: 'rotating-file',
|
||||||
|
path: _this.logPath,
|
||||||
|
period: '1d',
|
||||||
|
count: 3
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return bunyan.createLogger(opt);
|
||||||
|
} catch (_error) {
|
||||||
|
e = _error;
|
||||||
|
console.error(e);
|
||||||
|
return emptylog;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
@ -8,7 +8,7 @@ Request Handler
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var answerHandler, crypto, db, exports, fs, getHandlerFileAsString, getHandlerPath, getIncludeFileAsString, log, mm, mustache, objAdminCmds, objUserCmds, path, qs, renderPage, sendLoginOrPage,
|
var answerHandler, crypto, db, exports, fs, getHandlerFileAsString, getHandlerPath, getIncludeFileAsString, log, mm, mustache, objUserCmds, path, qs, renderPage, sendLoginOrPage,
|
||||||
_this = this;
|
_this = this;
|
||||||
|
|
||||||
log = require('./logging');
|
log = require('./logging');
|
||||||
|
|
@ -27,14 +27,6 @@ Request Handler
|
||||||
|
|
||||||
crypto = require('crypto-js');
|
crypto = require('crypto-js');
|
||||||
|
|
||||||
objAdminCmds = {
|
|
||||||
'loadrules': mm.loadRulesFromFS,
|
|
||||||
'loadaction': mm.loadActionModuleFromFS,
|
|
||||||
'loadactions': mm.loadActionModulesFromFS,
|
|
||||||
'loadevent': mm.loadEventModuleFromFS,
|
|
||||||
'loadevents': mm.loadEventModulesFromFS
|
|
||||||
};
|
|
||||||
|
|
||||||
objUserCmds = {
|
objUserCmds = {
|
||||||
'store_action': mm.storeActionModule,
|
'store_action': mm.storeActionModule,
|
||||||
'get_actionmodules': mm.getAllActionModules,
|
'get_actionmodules': mm.getAllActionModules,
|
||||||
|
|
@ -59,17 +51,16 @@ Request Handler
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This allows the parent to add handlers. The event handler will receive
|
This allows the parent to add the shutdown handler.
|
||||||
the events that were received. The shutdown function will be called if the
|
The shutdown function will be called if the admin command shutdown is issued.
|
||||||
admin command shutdown is issued.
|
|
||||||
|
|
||||||
@public addHandlers( *fShutdown* )
|
@public addShutdownHandler( *fShutdown* )
|
||||||
@param {function} fShutdown
|
@param {function} fShutdown
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
exports.addHandlers = function(fShutdown) {
|
exports.addShutdownHandler = function(fShutdown) {
|
||||||
return objAdminCmds.shutdown = function(args, answerHandler) {
|
return _this.objAdminCmds.shutdown = function(args, answerHandler) {
|
||||||
answerHandler.answerSuccess('Shutting down... BYE!');
|
answerHandler.answerSuccess('Shutting down... BYE!');
|
||||||
return setTimeout(fShutdown, 500);
|
return setTimeout(fShutdown, 500);
|
||||||
};
|
};
|
||||||
|
|
@ -344,13 +335,13 @@ Request Handler
|
||||||
|
|
||||||
|
|
||||||
exports.handleAdmin = function(req, resp) {
|
exports.handleAdmin = function(req, resp) {
|
||||||
var q, _name;
|
var q, _base, _name;
|
||||||
if (req.session && req.session.user) {
|
if (req.session && req.session.user) {
|
||||||
if (req.session.user.isAdmin === "true") {
|
if (req.session.user.isAdmin === "true") {
|
||||||
q = req.query;
|
q = req.query;
|
||||||
log.print('RH', 'Received admin request: ' + req.originalUrl);
|
log.print('RH', 'Received admin request: ' + req.originalUrl);
|
||||||
if (q.cmd) {
|
if (q.cmd) {
|
||||||
return typeof objAdminCmds[_name = q.cmd] === "function" ? objAdminCmds[_name](q, answerHandler(req, resp, true)) : void 0;
|
return typeof (_base = _this.objAdminCmds)[_name = q.cmd] === "function" ? _base[_name](q, answerHandler(req, resp, true)) : void 0;
|
||||||
} else {
|
} else {
|
||||||
return resp.send(404, 'Command unknown!');
|
return resp.send(404, 'Command unknown!');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,16 @@ Server
|
||||||
|
|
||||||
>This is the main module that is used to run the whole server:
|
>This is the main module that is used to run the whole server:
|
||||||
>
|
>
|
||||||
> node server [log_type http_port]
|
> node server [opt]
|
||||||
>
|
>
|
||||||
>Valid `log_type`'s are:
|
> See below in the optimist CLI preparation for allowed optional parameters
|
||||||
>
|
|
||||||
>- `0`: standard I/O output (default)
|
|
||||||
>- `1`: log file (server.log)
|
|
||||||
>- `2`: silent
|
|
||||||
>
|
|
||||||
>`http_port` can be set to use another port, than defined in the
|
|
||||||
>[config](config.html) file, to listen to, e.g. used by the test suite.
|
|
||||||
>
|
|
||||||
>
|
|
||||||
|
|
||||||
TODO how about we allow spawning child processes with servers based on address?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var args, conf, db, engine, http_listener, init, log, procCmds, shutDown;
|
var argv, conf, cp, db, engine, fs, http_listener, init, logger, opt, optimist, path, procCmds, shutDown, usage;
|
||||||
|
|
||||||
log = require('./logging');
|
logger = require('./new_logging');
|
||||||
|
|
||||||
conf = require('./config');
|
conf = require('./config');
|
||||||
|
|
||||||
|
|
@ -36,10 +25,69 @@ TODO how about we allow spawning child processes with servers based on address?
|
||||||
|
|
||||||
http_listener = require('./http_listener');
|
http_listener = require('./http_listener');
|
||||||
|
|
||||||
args = {};
|
fs = require('fs');
|
||||||
|
|
||||||
|
path = require('path');
|
||||||
|
|
||||||
|
cp = require('child_process');
|
||||||
|
|
||||||
|
optimist = require('optimist');
|
||||||
|
|
||||||
procCmds = {};
|
procCmds = {};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Let's prepare the optimist CLI
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
usage = 'This runs your webapi-based ECA engine';
|
||||||
|
|
||||||
|
opt = {
|
||||||
|
'h': {
|
||||||
|
alias: 'help',
|
||||||
|
describe: 'Display this'
|
||||||
|
},
|
||||||
|
'c': {
|
||||||
|
alias: 'config-path',
|
||||||
|
describe: 'Specify a path to a custom configuration file, other than "config/config.json"'
|
||||||
|
},
|
||||||
|
'w': {
|
||||||
|
alias: 'http-port',
|
||||||
|
describe: 'Specify a HTTP port for the web server'
|
||||||
|
},
|
||||||
|
'd': {
|
||||||
|
alias: 'db-port',
|
||||||
|
describe: 'Specify a port for the redis DB'
|
||||||
|
},
|
||||||
|
'm': {
|
||||||
|
alias: 'log-mode',
|
||||||
|
describe: 'Specify a log mode: [development|productive]'
|
||||||
|
},
|
||||||
|
'i': {
|
||||||
|
alias: 'log-io-level',
|
||||||
|
describe: 'Specify the log level for the I/O'
|
||||||
|
},
|
||||||
|
'f': {
|
||||||
|
alias: 'log-file-level',
|
||||||
|
describe: 'Specify the log level for the log file'
|
||||||
|
},
|
||||||
|
'p': {
|
||||||
|
alias: 'log-file-path',
|
||||||
|
describe: 'Specify the path to the log file within the "logs" folder'
|
||||||
|
},
|
||||||
|
'n': {
|
||||||
|
alias: 'nolog',
|
||||||
|
describe: 'Set this if no output shall be generated'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
argv = optimist.usage(usage).options(opt).argv;
|
||||||
|
|
||||||
|
if (argv.help) {
|
||||||
|
console.log(optimist.help());
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Error handling of the express port listener requires special attention,
|
Error handling of the express port listener requires special attention,
|
||||||
thus we have to catch the process error, which is issued if
|
thus we have to catch the process error, which is issued if
|
||||||
|
|
@ -50,7 +98,7 @@ TODO how about we allow spawning child processes with servers based on address?
|
||||||
process.on('uncaughtException', function(err) {
|
process.on('uncaughtException', function(err) {
|
||||||
switch (err.errno) {
|
switch (err.errno) {
|
||||||
case 'EADDRINUSE':
|
case 'EADDRINUSE':
|
||||||
err.addInfo = 'http_port already in use, shutting down!';
|
err.addInfo = 'http-port already in use, shutting down!';
|
||||||
log.error('RS', err);
|
log.error('RS', err);
|
||||||
return shutDown();
|
return shutDown();
|
||||||
default:
|
default:
|
||||||
|
|
@ -66,48 +114,54 @@ TODO how about we allow spawning child processes with servers based on address?
|
||||||
|
|
||||||
|
|
||||||
init = function() {
|
init = function() {
|
||||||
log.print('RS', 'STARTING SERVER');
|
var args, log, logconf;
|
||||||
conf(args);
|
conf(argv.c);
|
||||||
if (!conf.isReady()) {
|
if (!conf.isReady()) {
|
||||||
log.error('RS', 'Config file not ready!');
|
console.error('FAIL: Config file not ready! Shutting down...');
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
if (process.argv.length > 2) {
|
logconf = conf.getLogConf();
|
||||||
args.logType = parseInt(process.argv[2]) || 0;
|
if (argv.m) {
|
||||||
switch (args.logType) {
|
logconf['mode'] = argv.m;
|
||||||
case 0:
|
|
||||||
log.print('RS', 'Log type set to standard I/O output');
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
log.print('RS', 'Log type set to file output');
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
log.print('RS', 'Log type set to silent');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log.print('RS', 'Unknown log type, using standard I/O');
|
|
||||||
}
|
|
||||||
log(args);
|
|
||||||
} else {
|
|
||||||
log.print('RS', 'No log method argument provided, using standard I/O');
|
|
||||||
}
|
}
|
||||||
if (process.argv.length > 3) {
|
if (argv.i) {
|
||||||
args.http_port = parseInt(process.argv[3]);
|
logconf['io-level'] = argv.i;
|
||||||
} else {
|
|
||||||
log.print('RS', 'No HTTP port passed, using standard port from config file');
|
|
||||||
}
|
}
|
||||||
log.print('RS', 'Initialzing DB');
|
if (argv.f) {
|
||||||
|
logconf['file-level'] = argv.f;
|
||||||
|
}
|
||||||
|
if (argv.p) {
|
||||||
|
logconf['file-path'] = argv.p;
|
||||||
|
}
|
||||||
|
if (argv.n) {
|
||||||
|
logconf['nolog'] = argv.n;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(path.resolve(__dirname, '..', 'logs', logconf['file-path']));
|
||||||
|
} catch (_error) {}
|
||||||
|
log = logger(logconf);
|
||||||
|
log.info('RS | STARTING SERVER');
|
||||||
|
args = {
|
||||||
|
logger: log,
|
||||||
|
logconf: logconf
|
||||||
|
};
|
||||||
|
args['http-port'] = parseInt(argv.w || conf.getHttpPort());
|
||||||
|
log.info('RS | Initialzing DB');
|
||||||
db(args);
|
db(args);
|
||||||
return db.isConnected(function(err, result) {
|
return db.isConnected(function(err, result) {
|
||||||
|
var cliArgs, poller;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
log.print('RS', 'Initialzing engine');
|
log.info('RS | Initialzing engine');
|
||||||
engine(args);
|
engine(args);
|
||||||
log.print('RS', 'Initialzing http listener');
|
log.info('RS | Initialzing http listener');
|
||||||
http_listener(args);
|
http_listener(args);
|
||||||
log.print('RS', 'Passing handlers to engine');
|
log.info('RS | Passing handlers to engine');
|
||||||
engine.addPersistence(db);
|
engine.addPersistence(db);
|
||||||
log.print('RS', 'Passing handlers to http listener');
|
log.info('RS | Passing handlers to http listener');
|
||||||
return http_listener.addHandlers(shutDown);
|
http_listener.addShutdownHandler(shutDown);
|
||||||
|
log.info('RS | For e 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']];
|
||||||
|
return poller = cp.fork(path.resolve(__dirname, 'event_poller'), cliArgs);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -120,7 +174,7 @@ TODO how about we allow spawning child processes with servers based on address?
|
||||||
|
|
||||||
|
|
||||||
shutDown = function() {
|
shutDown = function() {
|
||||||
log.print('RS', 'Received shut down command!');
|
log.warn('RS | Received shut down command!');
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
engine.shutDown();
|
engine.shutDown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@
|
||||||
* - 1 file
|
* - 1 file
|
||||||
* - 2 silent
|
* - 2 silent
|
||||||
*/
|
*/
|
||||||
|
//TODO dynamic log file names (especially to track unit test logs)
|
||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
|
wst = require('winston'),
|
||||||
logTypes = [ flushToConsole, flushToFile, null],
|
logTypes = [ flushToConsole, flushToFile, null],
|
||||||
logFile = require('path').resolve(__dirname, '..', 'server.log'),
|
logFile = require('path').resolve(__dirname, '..', 'server.log'),
|
||||||
logType = 0;
|
logType = 0;
|
||||||
|
|
@ -19,6 +21,8 @@ exports = module.exports = function(args) {
|
||||||
if(args.logType) logType = parseInt(args.logType) || 0;
|
if(args.logType) logType = parseInt(args.logType) || 0;
|
||||||
if(logType == 1) fs.truncateSync(logFile, 0);
|
if(logType == 1) fs.truncateSync(logFile, 0);
|
||||||
if(logType > logTypes.length - 1) logType = 0;
|
if(logType > logTypes.length - 1) logType = 0;
|
||||||
|
// winston.add(winston.transports.File, { filename: 'somefile.log' });
|
||||||
|
// winston.remove(winston.transports.Console);
|
||||||
return module.exports;
|
return module.exports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -29,8 +33,10 @@ function flush(err, msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function flushToConsole(err, msg) {
|
function flushToConsole(err, msg) {
|
||||||
if(err) console.error(msg);
|
if(err) console.error("\033[31m" + msg + "\033[0m");
|
||||||
else console.log(msg);
|
else console.log(msg);
|
||||||
|
// if(err) console.error(msg);
|
||||||
|
// else console.log(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function flushToFile(err, msg) {
|
function flushToFile(err, msg) {
|
||||||
|
|
@ -63,13 +69,13 @@ function printError(module, err, isSevere) {
|
||||||
// if(module) flush(true, ts + module + ' | ERROR AND BAD HANDLING: ' + err + '\n' + e.stack);
|
// if(module) flush(true, ts + module + ' | ERROR AND BAD HANDLING: ' + err + '\n' + e.stack);
|
||||||
// else flush(true, ts + '!N/A! | ERROR, BAD HANDLING AND NO MODULE NAME: ' + err + '\n' + e.stack);
|
// else flush(true, ts + '!N/A! | ERROR, BAD HANDLING AND NO MODULE NAME: ' + err + '\n' + e.stack);
|
||||||
// } else if(err) {
|
// } else if(err) {
|
||||||
if(err.addInfo) ai = ' (' + err.addInfo + ')';
|
if(err.addInfo) ai = ' (' + err.addInfo + ')';
|
||||||
if(!err.message) err.message = 'UNKNOWN REASON!\n' + err.stack;
|
if(!err.message) err.message = 'UNKNOWN REASON!\n' + err.stack;
|
||||||
if(module) {
|
if(module) {
|
||||||
var msg = ts + module + ' | ERROR'+ai+': ' + err.message;
|
var msg = ts + module + ' | ERROR'+ai+': ' + err.message;
|
||||||
if(isSevere) msg += '\n' + err.stack;
|
if(isSevere) msg += '\n' + err.stack;
|
||||||
flush(true, msg);
|
flush(true, msg);
|
||||||
} else flush(true, ts + '!N/A! | ERROR AND NO MODULE NAME'+ai+': ' + err.message + '\n' + err.stack);
|
} else flush(true, ts + '!N/A! | ERROR AND NO MODULE NAME'+ai+': ' + err.message + '\n' + err.stack);
|
||||||
// } else {
|
// } else {
|
||||||
// var e = new Error('Unexpected error');
|
// var e = new Error('Unexpected error');
|
||||||
// flush(true, e.message + ': \n' + e.stack);
|
// flush(true, e.message + ': \n' + e.stack);
|
||||||
|
|
@ -93,3 +99,9 @@ exports.error = function(module, err) {
|
||||||
exports.severe = function(module, err) {
|
exports.severe = function(module, err) {
|
||||||
printError(module, err, true);
|
printError(module, err, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.obj = function (varname, obj) {
|
||||||
|
var arrS = (new Error).stack.split('\n');
|
||||||
|
console.log('Dumping object "' + varname + '"' + arrS[2]);
|
||||||
|
console.log(obj);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@
|
||||||
"nodeunit": "0.8.4",
|
"nodeunit": "0.8.4",
|
||||||
"redis": "0.10.0",
|
"redis": "0.10.0",
|
||||||
"request": "2.33.0",
|
"request": "2.33.0",
|
||||||
"coffee-script": "1.6.3"
|
"coffee-script": "1.6.3",
|
||||||
|
"bunyan": "0.22.1",
|
||||||
|
"optimist": "0.6.1"
|
||||||
},
|
},
|
||||||
"__comment": {
|
"__comment": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
node $DIR/js-coffee/server
|
node $DIR/js-coffee/server | $DIR/node_modules/bunyan/bin/bunyan
|
||||||
|
|
|
||||||
15
run_tests.sh
15
run_tests.sh
|
|
@ -1,2 +1,15 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
require('nodeunit').reporters.default.run(['testing']);
|
process.chdir(__dirname);
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var args = process.argv.slice(2);
|
||||||
|
if( args[0] !== undefined ) {
|
||||||
|
var fl = path.join('testing', args[0]);
|
||||||
|
if (fs.existsSync(fl)) {
|
||||||
|
require('nodeunit').reporters.default.run([fl]);
|
||||||
|
} else {
|
||||||
|
console.error('File not found!!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
require('nodeunit').reporters.default.run(['testing']);
|
||||||
|
}
|
||||||
|
|
|
||||||
5
testing/js/test_logging.js
Normal file
5
testing/js/test_logging.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Generated by CoffeeScript 1.6.3
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
87
testing/js/test_persistence.js
Normal file
87
testing/js/test_persistence.js
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Generated by CoffeeScript 1.6.3
|
||||||
|
(function() {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
exports.setUp = function(cb) {
|
||||||
|
_this.path = require('path');
|
||||||
|
_this.db = require(path.join('..', 'js-coffee', 'persistence'));
|
||||||
|
console.log('setup');
|
||||||
|
console.log(_this.db);
|
||||||
|
_this.db({
|
||||||
|
logType: 2
|
||||||
|
});
|
||||||
|
return cb();
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.tearDown = function(cb) {
|
||||||
|
_this.db.shutDown();
|
||||||
|
return cb();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
# Test AVAILABILITY
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
exports.Availability = {
|
||||||
|
setUp: function(cb) {
|
||||||
|
_this.path = require('path');
|
||||||
|
_this.db = require(path.join('..', 'js-coffee', 'persistence'));
|
||||||
|
console.log('setup');
|
||||||
|
console.log(_this.db);
|
||||||
|
_this.db({
|
||||||
|
logType: 2
|
||||||
|
});
|
||||||
|
return cb();
|
||||||
|
},
|
||||||
|
testRequire: function(test) {
|
||||||
|
test.expect(1);
|
||||||
|
console.log('setup');
|
||||||
|
test.ok(_this.db, 'DB interface loaded');
|
||||||
|
return test.done();
|
||||||
|
},
|
||||||
|
testConnect: function(test) {
|
||||||
|
test.expect(1);
|
||||||
|
return _this.db.isConnected(function(err) {
|
||||||
|
test.ifError(err, 'Connection failed!');
|
||||||
|
return test.done();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
testNoConfig: function(test) {
|
||||||
|
test.expect(1);
|
||||||
|
_this.db({
|
||||||
|
configPath: 'nonexistingconf.file'
|
||||||
|
});
|
||||||
|
return _this.db.isConnected(function(err) {
|
||||||
|
test.ok(err, 'Still connected!?');
|
||||||
|
return test.done();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
testWrongConfig: function(test) {
|
||||||
|
test.expect(1);
|
||||||
|
_this.db({
|
||||||
|
configPath: _this.path.join('testing', 'jsonWrongConfig.json')
|
||||||
|
});
|
||||||
|
return _this.db.isConnected(function(err) {
|
||||||
|
test.ok(err, 'Still connected!?');
|
||||||
|
return test.done();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
testPurgeQueue: function(test) {
|
||||||
|
var evt;
|
||||||
|
test.expect(2);
|
||||||
|
evt = {
|
||||||
|
eventid: '1',
|
||||||
|
event: 'mail'
|
||||||
|
};
|
||||||
|
_this.db.pushEvent(evt);
|
||||||
|
_this.db.purgeEventQueue();
|
||||||
|
return _this.db.popEvent(function(err, obj) {
|
||||||
|
test.ifError(err, 'Error during pop after purging!');
|
||||||
|
test.strictEqual(obj, null, 'There was an event in the queue!?');
|
||||||
|
return test.done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
@ -3,7 +3,7 @@ path = require 'path'
|
||||||
exports.setUp = ( cb ) =>
|
exports.setUp = ( cb ) =>
|
||||||
@conf = require path.join '..', 'js-coffee', 'config'
|
@conf = require path.join '..', 'js-coffee', 'config'
|
||||||
@conf
|
@conf
|
||||||
logType: 2
|
nolog: true
|
||||||
cb()
|
cb()
|
||||||
|
|
||||||
exports.testRequire = ( test ) =>
|
exports.testRequire = ( test ) =>
|
||||||
|
|
@ -12,16 +12,26 @@ exports.testRequire = ( test ) =>
|
||||||
test.done()
|
test.done()
|
||||||
|
|
||||||
exports.testParameters = ( test ) =>
|
exports.testParameters = ( test ) =>
|
||||||
test.expect 4
|
reqProp = [
|
||||||
|
'mode'
|
||||||
|
'io-level'
|
||||||
|
'file-level'
|
||||||
|
'file-path'
|
||||||
|
]
|
||||||
|
test.expect 4 + reqProp.length
|
||||||
test.ok @conf.getHttpPort(), 'HTTP port does not exist!'
|
test.ok @conf.getHttpPort(), 'HTTP port does not exist!'
|
||||||
test.ok @conf.getDBPort(), 'DB port does not exist!'
|
test.ok @conf.getDBPort(), 'DB port does not exist!'
|
||||||
test.ok @conf.getCryptoKey(), 'Crypto key does not exist!'
|
test.ok @conf.getCryptoKey(), 'Crypto key does not exist!'
|
||||||
test.ok @conf.getSessionSecret(), 'Session Secret does not exist!'
|
logconf = @conf.getLogConf()
|
||||||
|
test.ok logconf, 'Log config does not exist!'
|
||||||
|
for prop in reqProp
|
||||||
|
test.ok logconf[prop], "Log conf property #{ prop } does not exist!"
|
||||||
test.done()
|
test.done()
|
||||||
|
|
||||||
exports.testDifferentConfigFile = ( test ) =>
|
exports.testDifferentConfigFile = ( test ) =>
|
||||||
test.expect 1
|
test.expect 1
|
||||||
@conf
|
@conf
|
||||||
|
nolog: true
|
||||||
configPath: path.join 'testing', 'files', 'jsonWrongConfig.json'
|
configPath: path.join 'testing', 'files', 'jsonWrongConfig.json'
|
||||||
test.ok @conf.isReady(), 'Different path not loaded!'
|
test.ok @conf.isReady(), 'Different path not loaded!'
|
||||||
test.done()
|
test.done()
|
||||||
|
|
@ -29,6 +39,7 @@ exports.testDifferentConfigFile = ( test ) =>
|
||||||
exports.testNoConfigFile = ( test ) =>
|
exports.testNoConfigFile = ( test ) =>
|
||||||
test.expect 1
|
test.expect 1
|
||||||
@conf
|
@conf
|
||||||
|
nolog: true
|
||||||
configPath: 'wrongpath.file'
|
configPath: 'wrongpath.file'
|
||||||
test.strictEqual @conf.isReady(), false, 'Wrong path still loaded!'
|
test.strictEqual @conf.isReady(), false, 'Wrong path still loaded!'
|
||||||
test.done()
|
test.done()
|
||||||
|
|
|
||||||
68
testing/test_logging.coffee
Normal file
68
testing/test_logging.coffee
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
|
||||||
|
exports.setUp = ( cb ) =>
|
||||||
|
@fs = require 'fs'
|
||||||
|
@path = require 'path'
|
||||||
|
@stdPath = @path.resolve __dirname, '..', 'logs', 'server.log'
|
||||||
|
try
|
||||||
|
@fs.unlinkSync @stdPath
|
||||||
|
catch e
|
||||||
|
@log = require @path.join '..', 'js-coffee', 'new_logging'
|
||||||
|
cb()
|
||||||
|
|
||||||
|
exports.tearDown = ( cb ) =>
|
||||||
|
cb()
|
||||||
|
|
||||||
|
exports.testInitIO = ( test ) =>
|
||||||
|
test.expect 1
|
||||||
|
conf =
|
||||||
|
logType: 0
|
||||||
|
@log.configure conf
|
||||||
|
@log.info 'TL', 'testInitIO - info'
|
||||||
|
@log.warn 'TL', 'testInitIO - warn'
|
||||||
|
@log.error 'TL', 'testInitIO - error'
|
||||||
|
test.ok !@fs.existsSync @stdPath
|
||||||
|
test.done()
|
||||||
|
|
||||||
|
exports.testInitFile = ( test ) =>
|
||||||
|
test.expect 1
|
||||||
|
|
||||||
|
conf =
|
||||||
|
logType: 1
|
||||||
|
@log.configure conf
|
||||||
|
@log.info 'UT', 'test 1'
|
||||||
|
|
||||||
|
fWait = () =>
|
||||||
|
@log.info 'UT', 'test 2'
|
||||||
|
test.ok @fs.existsSync @stdPath
|
||||||
|
test.done()
|
||||||
|
|
||||||
|
setTimeout fWait, 100
|
||||||
|
|
||||||
|
# exports.testInitSilent = ( test ) =>
|
||||||
|
# test.expect 1
|
||||||
|
|
||||||
|
# conf =
|
||||||
|
# logType: 2
|
||||||
|
# @log.configure conf
|
||||||
|
# @log.info 'test 3'
|
||||||
|
|
||||||
|
# test.ok true, 'yay'
|
||||||
|
# test.done()
|
||||||
|
|
||||||
|
# exports.testInitPath = ( test ) =>
|
||||||
|
# test.expect 1
|
||||||
|
|
||||||
|
# conf =
|
||||||
|
# logType: 1
|
||||||
|
# logPath: 'testing/log-initPath.log'
|
||||||
|
# @log.configure conf
|
||||||
|
# @log.info 'test 3'
|
||||||
|
|
||||||
|
# test.ok true, 'yay'
|
||||||
|
# test.done()
|
||||||
|
|
||||||
|
# exports.testPrint = ( test ) =>
|
||||||
|
# test.expect 1
|
||||||
|
# test.ok true, 'yay'
|
||||||
|
# @log.info 'test 3'
|
||||||
|
# test.done()
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
exports.setUp = ( cb ) =>
|
exports.setUp = ( cb ) =>
|
||||||
@db = require '../js-coffee/persistence'
|
@path = require 'path'
|
||||||
|
@db = require @path.join '..', 'js-coffee', 'persistence'
|
||||||
@db logType: 2
|
@db logType: 2
|
||||||
cb()
|
cb()
|
||||||
|
|
||||||
|
|
@ -38,7 +39,7 @@ exports.Availability =
|
||||||
testWrongConfig: ( test ) =>
|
testWrongConfig: ( test ) =>
|
||||||
test.expect 1
|
test.expect 1
|
||||||
|
|
||||||
@db { configPath: 'testing/jsonWrongConfig.json' }
|
@db { configPath: @path.join 'testing', 'jsonWrongConfig.json' }
|
||||||
@db.isConnected ( err ) ->
|
@db.isConnected ( err ) ->
|
||||||
test.ok err, 'Still connected!?'
|
test.ok err, 'Still connected!?'
|
||||||
test.done()
|
test.done()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue