Ability to specify per device, per product class, or per oui configuration. Reimplemented Libxmljs options on the new configuration system.
This commit is contained in:
1 parent
3d201981e2
commit
ee9a35b9b3
10 files changed
+162
-98
No files matched your search
+8
-3
@@ -19,6 +19,11 @@ config = require './config'
|
||||
cluster = require 'cluster'
|
||||
util = require 'util'
|
||||
|
||||
# Keep current configuration to pass that to workers as environment variables
|
||||
ENVIRONMENT_VARIABLES = {}
|
||||
for k, v of config.allConfig
|
||||
ENVIRONMENT_VARIABLES["GENIEACS_#{k}"] = v
|
||||
|
||||
|
||||
cluster.on('listening', (worker, address) ->
|
||||
util.log("Worker #{worker.process.pid} listening to #{address.address}:#{address.port}")
|
||||
@@ -26,12 +31,12 @@ cluster.on('listening', (worker, address) ->
|
||||
|
||||
cluster.on('exit', (worker, code, signal) ->
|
||||
util.log("Worker #{worker.process.pid} died (#{worker.process.exitCode})")
|
||||
cluster.fork()
|
||||
cluster.fork(ENVIRONMENT_VARIABLES)
|
||||
)
|
||||
|
||||
|
||||
start = (service) ->
|
||||
workerProcesses = config["#{service.toUpperCase()}_WORKER_PROCESSES"]
|
||||
workerProcesses = config.get("#{service.toUpperCase()}_WORKER_PROCESSES")
|
||||
|
||||
cluster.setupMaster({
|
||||
exec : 'lib/server',
|
||||
@@ -39,7 +44,7 @@ start = (service) ->
|
||||
})
|
||||
|
||||
for [0 ... workerProcesses]
|
||||
cluster.fork()
|
||||
cluster.fork(ENVIRONMENT_VARIABLES)
|
||||
|
||||
|
||||
exports.start = start
|
||||
+97
-53
@@ -18,64 +18,89 @@
|
||||
path = require 'path'
|
||||
common = require './common'
|
||||
|
||||
options = {
|
||||
CONFIG_DIR : {type : 'string', default : 'config'},
|
||||
MONGODB_CONNECTION_URL : {type : 'string', default : 'mongodb://127.0.0.1/genieacs'},
|
||||
REDIS_PORT : {type : 'int', default : 6379},
|
||||
REDIS_HOST : {type : 'string', default : '127.0.0.1'},
|
||||
REDIS_DB : {type : 'int', default : 0},
|
||||
|
||||
defaults = {
|
||||
CONFIG_DIR : './config',
|
||||
CWMP_WORKER_PROCESSES : {type : 'int', default : 4},
|
||||
CWMP_PORT : {type : 'int', default : 7547},
|
||||
CWMP_INTERFACE : {type : 'string', default : '0.0.0.0'},
|
||||
CWMP_SSL : {type : 'bool', default : false},
|
||||
|
||||
MONGODB_CONNECTION_URL : 'mongodb://127.0.0.1/genieacs',
|
||||
REDIS_PORT : 6379,
|
||||
REDIS_HOST : '127.0.0.1',
|
||||
REDIS_DB : 0,
|
||||
NBI_WORKER_PROCESSES : {type : 'int', default : 2},
|
||||
NBI_PORT : {type : 'int', default : 7557},
|
||||
NBI_INTERFACE : {type : 'string', default : '0.0.0.0'},
|
||||
NBI_SSL : {type : 'bool', default : false},
|
||||
|
||||
CWMP_WORKER_PROCESSES : 4,
|
||||
CWMP_PORT : 7547, # CWMP port as assigned by IANA
|
||||
CWMP_INTERFACE : '0.0.0.0',
|
||||
CWMP_SSL : false,
|
||||
NBI_WORKER_PROCESSES : 2,
|
||||
NBI_PORT : 7557,
|
||||
NBI_INTERFACE : '0.0.0.0',
|
||||
NBI_SSL : false,
|
||||
FS_WORKER_PROCESSES : 2,
|
||||
FS_PORT : 7567,
|
||||
FS_INTERFACE : '0.0.0.0',
|
||||
FS_SSL : false,
|
||||
FS_IP : '192.168.0.1', # Used when sending download requests to devices
|
||||
FS_WORKER_PROCESSES : {type : 'int', default : 2},
|
||||
FS_PORT : {type : 'int', default : 7567},
|
||||
FS_INTERFACE : {type : 'string', default : '0.0.0.0'},
|
||||
FS_SSL : {type : 'bool', default : false},
|
||||
FS_IP : {type : 'string', default : '192.168.0.1'},
|
||||
|
||||
CACHE_DURATION : 60, # in seconds
|
||||
PRESETS_CACHE_DURATION : 86400,
|
||||
PRESETS_TIME_PADDING : 1,
|
||||
PRESETS_CACHE_DURATION : {type : 'int', default : 86400},
|
||||
LOG_INFORMS : {type : 'bool', default : true},
|
||||
DEBUG : {type : 'bool', default : false},
|
||||
RETRY_DELAY : {type : 'int', default : 300},
|
||||
IGNORE_XML_NAMESPACES : {type : 'bool', default : false},
|
||||
SESSION_TIMEOUT : {type : 'int', default : 30},
|
||||
GET_PARAMETER_NAMES_DEPTH_THRESHOLD : {type : 'int', default : 0},
|
||||
TASK_PARAMETERS_BATCH_SIZE : {type : 'int', default : 32},
|
||||
|
||||
LOG_INFORMS : true,
|
||||
DEBUG : false,
|
||||
DEVICE_ONLINE_THRESHOLD : 4000,
|
||||
RETRY_DELAY : 300,
|
||||
IGNORE_XML_NAMESPACES : false, # Traverse XML using element's local name only
|
||||
SESSION_TIMEOUT : 30,
|
||||
GET_PARAMETER_NAMES_DEPTH_THRESHOLD : 0,
|
||||
TASK_PARAMETERS_BATCH_SIZE : 32
|
||||
# Libxml related configuration
|
||||
XML_PARSE_RECOVER : {type : 'bool'},
|
||||
XML_PARSE_NOENT : {type : 'bool'},
|
||||
XML_PARSE_NOBLANKS : {type : 'bool'},
|
||||
XML_PARSE_NSCLEAN : {type : 'bool'},
|
||||
XML_PARSE_NOCDATA : {type : 'bool'},
|
||||
XML_PARSE_IGNORE_ENC : {type : 'bool'},
|
||||
|
||||
# Should probably never be changed
|
||||
PRESETS_TIME_PADDING : {type : 'int', default : 1},
|
||||
DEVICE_ONLINE_THRESHOLD : {type : 'int', default : 4000}
|
||||
}
|
||||
|
||||
exports.LIBXMLJS_OPTIONS = {}
|
||||
allConfig = {}
|
||||
|
||||
|
||||
setConfig = (name, value) ->
|
||||
return true if exports[name]?
|
||||
setConfig = (name, value, commandLineArgument) ->
|
||||
return true if allConfig[name]?
|
||||
|
||||
cast = (val, type) ->
|
||||
switch type
|
||||
when 'int'
|
||||
Number(val)
|
||||
when 'bool'
|
||||
String(val).trim().toLowerCase() in ['true', 'on', 'yes', '1']
|
||||
when 'string'
|
||||
String(val)
|
||||
else
|
||||
null
|
||||
|
||||
_value = null
|
||||
|
||||
if defaults[name]?
|
||||
_value = common.matchType(defaults[name], value)
|
||||
else if common.startsWith(name, 'XML_PARSE_')
|
||||
n = name[10..].toLowerCase() # libxmljs' options are lower case
|
||||
_value = common.matchType(true, value)
|
||||
exports.LIBXMLJS_OPTIONS[n] = _value
|
||||
for optionName, optionDetails of options
|
||||
n = optionName
|
||||
if commandLineArgument
|
||||
n = n.toLowerCase().replace(/_/g, '-')
|
||||
|
||||
if name == n
|
||||
_value = cast(value, optionDetails.type)
|
||||
n = optionName
|
||||
else if common.startsWith(name, "#{n}-")
|
||||
_value = cast(value, optionDetails.type)
|
||||
n = "#{optionName}-#{name[optionName.length+1..]}"
|
||||
|
||||
if _value?
|
||||
exports[name] = _value
|
||||
allConfig[n] = _value
|
||||
# Save as environmnet variable to pass on to any child processes
|
||||
process.env["GENIEACS_#{name}"] = _value
|
||||
process.env[n] = _value
|
||||
return true
|
||||
|
||||
return _value?
|
||||
return false
|
||||
|
||||
|
||||
# Command line arguments
|
||||
@@ -86,41 +111,60 @@ while argv.length
|
||||
if arg[0] == '-'
|
||||
v = argv.shift()
|
||||
exports.argv[arg] = v
|
||||
n = arg[2..].toUpperCase().replace(/-/g, '_')
|
||||
setConfig(n, v)
|
||||
setConfig(arg[2..], v, true)
|
||||
else
|
||||
exports.argv.push(arg)
|
||||
|
||||
|
||||
# Environment variable
|
||||
for k, v of process.env
|
||||
continue if k.lastIndexOf('GENIEACS_', 0) != 0
|
||||
k = k[9..] # remove "GENIEACS_" prefix
|
||||
setConfig(k, v)
|
||||
|
||||
|
||||
# Find config dir
|
||||
if exports.argv['--config-dir']?
|
||||
exports.CONFIG_DIR = exports.argv['--config-dir']
|
||||
allConfig.CONFIG_DIR = exports.argv['--config-dir']
|
||||
else if process.env['GENIEACS_CONFIG_DIR']?
|
||||
exports.CONFIG_DIR = process.env['GENIEACS_CONFIG_DIR']
|
||||
allConfig.CONFIG_DIR = process.env['GENIEACS_CONFIG_DIR']
|
||||
else
|
||||
exports.CONFIG_DIR = defaults.CONFIG_DIR
|
||||
allConfig.CONFIG_DIR = options.CONFIG_DIR.default
|
||||
|
||||
|
||||
# Configuration file
|
||||
for k, v of require(path.resolve(exports.CONFIG_DIR, 'config'))
|
||||
for k, v of require(path.resolve(allConfig.CONFIG_DIR, 'config'))
|
||||
setConfig(k, v)
|
||||
|
||||
|
||||
# Defaults
|
||||
for k, v of defaults
|
||||
setConfig(k, v)
|
||||
for k, v of options
|
||||
setConfig(k, v.default) if v.default?
|
||||
|
||||
|
||||
get = (option, deviceId) ->
|
||||
if deviceId?
|
||||
name = "#{option}-#{deviceId}"
|
||||
v = allConfig[name]
|
||||
return v if v?
|
||||
i = name.lastIndexOf('-')
|
||||
v = allConfig[name[0...i]]
|
||||
return v if v?
|
||||
i = name.lastIndexOf('-', i-1)
|
||||
v = allConfig[name[0...i]]
|
||||
return v if v? or i == -1
|
||||
|
||||
return allConfig[option]
|
||||
|
||||
|
||||
# load parameter configurations
|
||||
exports.PARAMETERS = require(path.resolve(exports.CONFIG_DIR, 'parameters'))
|
||||
exports.PARAMETERS = require(path.resolve(allConfig.CONFIG_DIR, 'parameters'))
|
||||
|
||||
# load authentication scripts
|
||||
exports.auth = require(path.resolve(exports.CONFIG_DIR, 'auth'))
|
||||
exports.auth = require(path.resolve(allConfig.CONFIG_DIR, 'auth'))
|
||||
|
||||
exports.CUSTOM_COMMANDS = require(path.resolve(exports.CONFIG_DIR, 'custom_commands'))
|
||||
exports.CUSTOM_COMMANDS = require(path.resolve(allConfig.CONFIG_DIR, 'custom_commands'))
|
||||
|
||||
exports.get = get
|
||||
|
||||
exports.allConfig = allConfig
|
||||
+19
-13
@@ -58,7 +58,7 @@ holdUntil = Date.now()
|
||||
|
||||
|
||||
writeResponse = (currentRequest, res) ->
|
||||
if config.DEBUG
|
||||
if config.get('DEBUG', currentRequest.session.deviceId)
|
||||
dump = "# RESPONSE #{new Date(Date.now())}\n" + JSON.stringify(res.headers) + "\n#{res.data}\n\n"
|
||||
require('fs').appendFile("../debug/#{currentRequest.session.deviceId}.dump", dump, (err) ->
|
||||
throw err if err
|
||||
@@ -102,7 +102,8 @@ inform = (currentRequest, cwmpRequest) ->
|
||||
|
||||
now = new Date(Date.now())
|
||||
|
||||
util.log("#{currentRequest.session.deviceId}: Inform (#{cwmpRequest.methodRequest.event}); retry count #{cwmpRequest.methodRequest.retryCount}") if config.LOG_INFORMS
|
||||
if config.get('LOG_INFORMS', currentRequest.session.deviceId)
|
||||
util.log("#{currentRequest.session.deviceId}: Inform (#{cwmpRequest.methodRequest.event}); retry count #{cwmpRequest.methodRequest.retryCount}")
|
||||
|
||||
parameterNames = (p[0] for p in cwmpRequest.methodRequest.parameterList)
|
||||
|
||||
@@ -138,7 +139,7 @@ inform = (currentRequest, cwmpRequest) ->
|
||||
if oldInformHash == informHash and not lastBootstrap?
|
||||
return updateAndRespond()
|
||||
|
||||
db.redisClient.setex("#{currentRequest.session.deviceId}_inform_hash", config.PRESETS_CACHE_DURATION, informHash, (err, res) ->
|
||||
db.redisClient.setex("#{currentRequest.session.deviceId}_inform_hash", config.get('PRESETS_CACHE_DURATION', currentRequest.session.deviceId), informHash, (err, res) ->
|
||||
throw err if err
|
||||
)
|
||||
|
||||
@@ -234,7 +235,7 @@ runTask = (currentRequest, task, methodResponse) ->
|
||||
switch status & ~tasks.STATUS_SAVE
|
||||
when tasks.STATUS_OK
|
||||
f = () ->
|
||||
db.redisClient.setex(String(task._id), config.CACHE_DURATION, JSON.stringify(task), (err) ->
|
||||
db.redisClient.setex(String(task._id), currentRequest.session.sessionTimeout, JSON.stringify(task), (err) ->
|
||||
throw err if err
|
||||
res = soap.response({
|
||||
id : task._id,
|
||||
@@ -268,7 +269,7 @@ runTask = (currentRequest, task, methodResponse) ->
|
||||
)
|
||||
)
|
||||
when tasks.STATUS_FAULT
|
||||
retryAfter = config.RETRY_DELAY * Math.pow(2, task.retries ? 0)
|
||||
retryAfter = config.get('RETRY_DELAY', currentRequest.session.deviceId) * Math.pow(2, task.retries ? 0)
|
||||
util.log("#{currentRequest.session.deviceId}: Fault response for task #{task._id}. Retrying after #{retryAfter} seconds.")
|
||||
taskUpdate = {fault : task.fault, timestamp : new Date(Date.now() + retryAfter * 1000)}
|
||||
if save
|
||||
@@ -297,16 +298,17 @@ assertPresets = (currentRequest) ->
|
||||
# no discrepancy, end the session
|
||||
endSession(currentRequest)
|
||||
else
|
||||
PRESETS_CACHE_DURATION = config.get('PRESETS_CACHE_DURATION', currentRequest.session.deviceId)
|
||||
db.getPresetsObjectsAliases((allPresets, allObjects, allAliases) ->
|
||||
if not presetsHash?
|
||||
presetsHash = presets.calculatePresetsHash(allPresets, allObjects)
|
||||
db.redisClient.setex('presets_hash', config.PRESETS_CACHE_DURATION, presetsHash, (err, res) ->
|
||||
db.redisClient.setex('presets_hash', PRESETS_CACHE_DURATION, presetsHash, (err, res) ->
|
||||
throw err if err
|
||||
)
|
||||
|
||||
presets.getDevicePreset(currentRequest.session.deviceId, allPresets, allObjects, allAliases, (devicePreset) ->
|
||||
presets.processDevicePreset(currentRequest.session.deviceId, devicePreset, (taskList, addTags, deleteTags, expiry) ->
|
||||
db.redisClient.setex("#{currentRequest.session.deviceId}_presets_hash", Math.floor(Math.max(1, expiry - config.PRESETS_TIME_PADDING)), presetsHash, (err, res) ->
|
||||
db.redisClient.setex("#{currentRequest.session.deviceId}_presets_hash", Math.floor(Math.max(1, expiry - config.get('PRESETS_TIME_PADDING'))), presetsHash, (err, res) ->
|
||||
throw err if err
|
||||
)
|
||||
|
||||
@@ -436,12 +438,16 @@ listener = (httpRequest, httpResponse) ->
|
||||
httpResponse.writeHead(400)
|
||||
httpResponse.end('Session is expired')
|
||||
return
|
||||
session = {
|
||||
deviceId : common.generateDeviceId(cwmpRequest.methodRequest.deviceId),
|
||||
cwmpVersion : cwmpRequest.cwmpVersion,
|
||||
sessionTimeout : cwmpRequest.sessionTimeout ? config.SESSION_TIMEOUT
|
||||
}
|
||||
|
||||
deviceId = common.generateDeviceId(cwmpRequest.methodRequest.deviceId)
|
||||
sessionId = crypto.randomBytes(8).toString('hex')
|
||||
|
||||
session = {
|
||||
deviceId : deviceId,
|
||||
cwmpVersion : cwmpRequest.cwmpVersion,
|
||||
sessionTimeout : cwmpRequest.sessionTimeout ? config.get('SESSION_TIMEOUT', deviceId)
|
||||
}
|
||||
|
||||
httpRequest.connection.setTimeout(session.sessionTimeout * 1000)
|
||||
|
||||
currentRequest = {
|
||||
@@ -451,7 +457,7 @@ listener = (httpRequest, httpResponse) ->
|
||||
session : session
|
||||
}
|
||||
|
||||
if config.DEBUG
|
||||
if config.get('DEBUG', currentRequest.session.deviceId)
|
||||
dump = "# REQUEST #{new Date(Date.now())}\n" + JSON.stringify(httpRequest.headers) + "\n#{httpRequest.getBody()}\n\n"
|
||||
require('fs').appendFile("../debug/#{currentRequest.session.deviceId}.dump", dump, (err) ->
|
||||
throw err if err
|
||||
|
||||
+7
-7
@@ -52,7 +52,7 @@ flushRedis = (callback) ->
|
||||
|
||||
connect = (callback) ->
|
||||
callbackCounter = 6
|
||||
mongodb.MongoClient.connect(config.MONGODB_CONNECTION_URL, {db:{w:1},server:{autoReconnect:true}}, (err, db) ->
|
||||
mongodb.MongoClient.connect(config.get('MONGODB_CONNECTION_URL'), {db:{w:1},server:{autoReconnect:true}}, (err, db) ->
|
||||
return callback(err) if err
|
||||
exports.mongoDb = db
|
||||
db.collection('tasks', (err, collection) ->
|
||||
@@ -93,8 +93,8 @@ connect = (callback) ->
|
||||
return callback(err)
|
||||
)
|
||||
|
||||
exports.redisClient = redisClient = redis.createClient(config.REDIS_PORT, config.REDIS_HOST)
|
||||
redisClient.select(config.REDIS_DB, (err) ->
|
||||
exports.redisClient = redisClient = redis.createClient(config.get('REDIS_PORT'), config.get('REDIS_HOST'))
|
||||
redisClient.select(config.get('REDIS_DB'), (err) ->
|
||||
if err
|
||||
callbackCounter = 0
|
||||
return callback(err)
|
||||
@@ -174,7 +174,7 @@ getCached = (name, valueCallback, valueExpiry, callback) ->
|
||||
|
||||
|
||||
getAliases = (callback) ->
|
||||
getCached('aliases', parameters.compileAliases, config.PRESETS_CACHE_DURATION, (err, res) ->
|
||||
getCached('aliases', parameters.compileAliases, config.get('PRESETS_CACHE_DURATION'), (err, res) ->
|
||||
throw err if err
|
||||
callback(res)
|
||||
)
|
||||
@@ -194,7 +194,7 @@ getPresetsObjectsAliases = (callback) ->
|
||||
presetsCollection.find().toArray((err, res) ->
|
||||
callback(err, res)
|
||||
)
|
||||
, config.PRESETS_CACHE_DURATION, (err, res) ->
|
||||
, config.get('PRESETS_CACHE_DURATION'), (err, res) ->
|
||||
throw err if err
|
||||
presets = res
|
||||
callback(presets, objects, aliases) if objects and aliases
|
||||
@@ -208,14 +208,14 @@ getPresetsObjectsAliases = (callback) ->
|
||||
objs[r._id] = r for r in res
|
||||
callback(null, objs)
|
||||
)
|
||||
, config.PRESETS_CACHE_DURATION, (err, res) ->
|
||||
, config.get('PRESETS_CACHE_DURATION'), (err, res) ->
|
||||
throw err if err
|
||||
objects = res
|
||||
callback(presets, objects, aliases) if presets and aliases
|
||||
)
|
||||
|
||||
if not aliases
|
||||
getCached('aliases', parameters.compileAliases, config.PRESETS_CACHE_DURATION, (err, res) ->
|
||||
getCached('aliases', parameters.compileAliases, config.get('PRESETS_CACHE_DURATION'), (err, res) ->
|
||||
throw err if err
|
||||
aliases = res
|
||||
callback(presets, objects, aliases) if presets and objects
|
||||
|
||||
+1
-1
@@ -198,7 +198,7 @@ listener = (request, response) ->
|
||||
response.writeHead(202)
|
||||
response.end()
|
||||
else
|
||||
apiFunctions.watchTask(task._id, config.DEVICE_ONLINE_THRESHOLD, (err) ->
|
||||
apiFunctions.watchTask(task._id, config.get('DEVICE_ONLINE_THRESHOLD', deviceId), (err) ->
|
||||
if err
|
||||
response.writeHead(202)
|
||||
response.end()
|
||||
|
||||
@@ -177,7 +177,7 @@ compileAliases = (callback) ->
|
||||
counter = 0
|
||||
splitIds(4, (batches) ->
|
||||
if not batches?
|
||||
return callback(null, aliases, config.ALIASES_CACHE)
|
||||
return callback(null, aliases)
|
||||
|
||||
for batch in batches
|
||||
options = {
|
||||
@@ -201,7 +201,7 @@ compileAliases = (callback) ->
|
||||
aliases[alias].push(id)
|
||||
|
||||
if ++counter == batches.length
|
||||
callback?(null, aliases, config.ALIASES_CACHE)
|
||||
callback?(null, aliases)
|
||||
)
|
||||
return
|
||||
)
|
||||
|
||||
+4
-3
@@ -218,8 +218,9 @@ exports.getDevicePreset = (deviceId, presets, objects, aliases, callback) ->
|
||||
|
||||
|
||||
exports.processDevicePreset = (deviceId, devicePreset, callback) ->
|
||||
PRESETS_TIME_PADDING = config.get('PRESETS_TIME_PADDING')
|
||||
now = new Date()
|
||||
expiry = config.PRESETS_CACHE_DURATION
|
||||
expiry = config.get('PRESETS_CACHE_DURATION', deviceId)
|
||||
getParameterValues = []
|
||||
setParameterValues = []
|
||||
addTags = []
|
||||
@@ -236,7 +237,7 @@ exports.processDevicePreset = (deviceId, devicePreset, callback) ->
|
||||
setParameterValues.push([parameterPath, presetValue, parameterDetails.current._type])
|
||||
else if parameterDetails.preset.expiry?
|
||||
diff = parameterDetails.preset.expiry - (now - (parameterDetails.current._timestamp ? 0)) / 1000
|
||||
if diff <= config.PRESETS_TIME_PADDING
|
||||
if diff <= PRESETS_TIME_PADDING
|
||||
if parameterDetails.current._value?
|
||||
getParameterValues.push(parameterPath)
|
||||
else
|
||||
@@ -284,7 +285,7 @@ exports.processDevicePreset = (deviceId, devicePreset, callback) ->
|
||||
taskList.push({device : deviceId, name : 'customCommand', command : commandDetails.preset.valueCommand})
|
||||
else if commandDetails.preset.expiry?
|
||||
diff = commandDetails.preset.expiry - (now - (commandDetails.current._timestamp ? 0)) / 1000
|
||||
if diff <= config.PRESETS_TIME_PADDING
|
||||
if diff <= PRESETS_TIME_PADDING
|
||||
taskList.push({device : deviceId, name : 'customCommand', command : commandDetails.preset.expiryCommand})
|
||||
else
|
||||
expiry = Math.min(expiry, diff)
|
||||
|
||||
+5
-5
@@ -25,9 +25,9 @@ service = config.argv[0]
|
||||
if not service?
|
||||
throw new Error('Missing argument cwmp, fs, or nbi')
|
||||
|
||||
networkInterface = config["#{service.toUpperCase()}_INTERFACE"]
|
||||
port = config["#{service.toUpperCase()}_PORT"]
|
||||
useHttps = config["#{service.toUpperCase()}_SSL"]
|
||||
networkInterface = config.get("#{service.toUpperCase()}_INTERFACE")
|
||||
port = config.get("#{service.toUpperCase()}_PORT")
|
||||
useHttps = config.get("#{service.toUpperCase()}_SSL")
|
||||
|
||||
serviceListener = require("./#{service}").listener
|
||||
|
||||
@@ -67,8 +67,8 @@ listener = (httpRequest, httpResponse) ->
|
||||
if useHttps
|
||||
path = require 'path'
|
||||
fs = require 'fs'
|
||||
httpsKey = path.resolve(config.CONFIG_DIR, "#{service}.key")
|
||||
httpsCert = path.resolve(config.CONFIG_DIR, "#{service}.crt")
|
||||
httpsKey = path.resolve(config.get('CONFIG_DIR'), "#{service}.key")
|
||||
httpsCert = path.resolve(config.get('CONFIG_DIR'), "#{service}.crt")
|
||||
options = {
|
||||
key: fs.readFileSync(httpsKey),
|
||||
cert: fs.readFileSync(httpsCert)
|
||||
|
||||
+9
-3
@@ -81,9 +81,15 @@ NAMESPACES = {
|
||||
}
|
||||
}
|
||||
|
||||
# Generate Libxmljs options
|
||||
LIBXMLJS_OPTIONS = {}
|
||||
for k, v of config.allConfig
|
||||
if k.lastIndexOf('XML_PARSE_', 0) == 0
|
||||
LIBXMLJS_OPTIONS[k] = v
|
||||
|
||||
|
||||
# Workaround for devices that don't use correct namespace declarations or prefixes
|
||||
if config.IGNORE_XML_NAMESPACES
|
||||
if config.get('IGNORE_XML_NAMESPACES')
|
||||
libxmljs.Element.prototype.__find = libxmljs.Element.prototype.find
|
||||
libxmljs.Element.prototype.find = (xpath, namespaces) ->
|
||||
# Modify xpath queries to work regardless of element's namespace
|
||||
@@ -291,7 +297,7 @@ exports.request = (httpRequest, cwmpVersion) ->
|
||||
data = httpRequest.getBody()
|
||||
|
||||
if data.length > 0
|
||||
xml = libxmljs.parseXml(data, config.LIBXMLJS_OPTIONS)
|
||||
xml = libxmljs.parseXml(data, LIBXMLJS_OPTIONS)
|
||||
|
||||
if not cwmpRequest.cwmpVersion?
|
||||
# cwmpVersion not passed, thus it's an inform request
|
||||
@@ -318,7 +324,7 @@ exports.request = (httpRequest, cwmpVersion) ->
|
||||
|
||||
cwmpRequest.id = try xml.get('/soap-env:Envelope/soap-env:Header/cwmp:ID', NAMESPACES[cwmpRequest.cwmpVersion]).text() catch then null
|
||||
|
||||
if methodElement? and not (config.IGNORE_XML_NAMESPACES and methodElement.name() is 'Fault')
|
||||
if methodElement? and not (config.get('IGNORE_XML_NAMESPACES') and methodElement.name() is 'Fault')
|
||||
switch methodElement.name()
|
||||
when 'Inform'
|
||||
cwmpRequest.methodRequest = acsInform(methodElement)
|
||||
|
||||
+10
-8
@@ -72,7 +72,7 @@ this.refreshObject = (task, methodResponse, callback) ->
|
||||
task.session.parameterNames.push(p[0])
|
||||
|
||||
if status & STATUS_COMPLETED
|
||||
task.session.subtask = {name : 'getParameterValues', parameterNames : task.session.parameterNames}
|
||||
task.session.subtask = {device : task.device, name : 'getParameterValues', parameterNames : task.session.parameterNames}
|
||||
delete task.session.parameterNames
|
||||
|
||||
this.getParameterValues(task.session.subtask, {}, (err, status, methodRequest) ->
|
||||
@@ -102,6 +102,8 @@ this.getParameterNames = (task, methodResponse, callback) ->
|
||||
callback(null, STATUS_FAULT)
|
||||
return
|
||||
|
||||
GET_PARAMETER_NAMES_DEPTH_THRESHOLD = config.get('GET_PARAMETER_NAMES_DEPTH_THRESHOLD', task.device)
|
||||
|
||||
getParameterDepth = (param) ->
|
||||
return 0 if !param
|
||||
return (param[...-1] + '.').split('.').length - 1
|
||||
@@ -110,7 +112,7 @@ this.getParameterNames = (task, methodResponse, callback) ->
|
||||
path = task.session.queue.pop()
|
||||
|
||||
# If parameter depth higher than the threshold, nextLevel was set to false
|
||||
if not task.nextLevel? and getParameterDepth(path) < config.GET_PARAMETER_NAMES_DEPTH_THRESHOLD
|
||||
if not task.nextLevel? and getParameterDepth(path) < GET_PARAMETER_NAMES_DEPTH_THRESHOLD
|
||||
for p in methodResponse.parameterList
|
||||
task.session.queue.push(p[0]) if p[0][-1..] == '.'
|
||||
|
||||
@@ -138,7 +140,7 @@ this.getParameterNames = (task, methodResponse, callback) ->
|
||||
methodRequest = {
|
||||
type : 'GetParameterNames',
|
||||
parameterPath : path,
|
||||
nextLevel : task.nextLevel ? getParameterDepth(path) < config.GET_PARAMETER_NAMES_DEPTH_THRESHOLD
|
||||
nextLevel : task.nextLevel ? getParameterDepth(path) < GET_PARAMETER_NAMES_DEPTH_THRESHOLD
|
||||
}
|
||||
return callback(null, STATUS_OK, methodRequest, deviceUpdates)
|
||||
else
|
||||
@@ -158,7 +160,7 @@ this.getParameterValues = (task, methodResponse, callback) ->
|
||||
else if methodResponse.parameterList?
|
||||
task.session.currentIndex = task.session.nextIndex
|
||||
|
||||
task.session.nextIndex = Math.min(task.session.currentIndex + config.TASK_PARAMETERS_BATCH_SIZE, task.parameterNames.length)
|
||||
task.session.nextIndex = Math.min(task.session.currentIndex + config.get('TASK_PARAMETERS_BATCH_SIZE', task.device), task.parameterNames.length)
|
||||
names = task.parameterNames.slice(task.session.currentIndex, task.session.nextIndex)
|
||||
|
||||
if methodResponse.type is 'GetParameterValuesResponse'
|
||||
@@ -188,7 +190,7 @@ this.setParameterValues = (task, methodResponse, callback) ->
|
||||
prevValues = task.parameterValues.slice(task.session.currentIndex, task.session.nextIndex)
|
||||
task.session.currentIndex = task.session.nextIndex
|
||||
|
||||
task.session.nextIndex = Math.min(task.session.currentIndex + config.TASK_PARAMETERS_BATCH_SIZE, task.parameterValues.length)
|
||||
task.session.nextIndex = Math.min(task.session.currentIndex + config.get('TASK_PARAMETERS_BATCH_SIZE', task.device), task.parameterValues.length)
|
||||
values = task.parameterValues.slice(task.session.currentIndex, task.session.nextIndex)
|
||||
|
||||
if prevValues?
|
||||
@@ -233,7 +235,7 @@ this.addObject = (task, methodResponse, callback) ->
|
||||
task.session.parameterNames.push(p[0]) if not common.endsWith(p[0], '.')
|
||||
|
||||
if status & STATUS_COMPLETED
|
||||
task.session.subtask = {name : 'getParameterValues', parameterNames : task.session.parameterNames}
|
||||
task.session.subtask = {device : task.device, name : 'getParameterValues', parameterNames : task.session.parameterNames}
|
||||
subtask()
|
||||
else if status & STATUS_OK
|
||||
# Use STATUS_SAVE to avoid adding duplicate object in case of error
|
||||
@@ -260,7 +262,7 @@ this.addObject = (task, methodResponse, callback) ->
|
||||
return callback(null, STATUS_FAULT)
|
||||
|
||||
if status & STATUS_COMPLETED and task.session.appliedParameterValues.length > 0
|
||||
task.session.subtask = {name : 'setParameterValues', parameterValues : task.session.appliedParameterValues}
|
||||
task.session.subtask = {device : task.device, name : 'setParameterValues', parameterValues : task.session.appliedParameterValues}
|
||||
subtask()
|
||||
else
|
||||
callback(err, status, methodRequest, allDeviceUpdates)
|
||||
@@ -332,7 +334,7 @@ this.download = (task, methodResponse, callback) ->
|
||||
type : 'Download',
|
||||
fileType : file.metadata.fileType,
|
||||
fileSize : file.length,
|
||||
url : "http://#{config.FS_IP}:#{config.FS_PORT}/#{encodeURIComponent(file.filename)}",
|
||||
url : "http://#{config.get('FS_IP')}:#{config.get('FS_PORT')}/#{encodeURIComponent(file.filename)}",
|
||||
successUrl : task.successUrl,
|
||||
failureUrl : task.failureUrl
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user