From 33b01d68caf38846b9adc97d383545b4d2d90c91 Mon Sep 17 00:00:00 2001 From: Zaid Abdulla Date: Thu, 29 Dec 2016 13:04:11 -0800 Subject: [PATCH] Support add/remove objects from presets and tasks --- lib/cache.coffee | 136 ++++++++++++++++++++++---------------- lib/cwmp.coffee | 9 ++- lib/default-provisions.js | 26 ++++++++ 3 files changed, 113 insertions(+), 58 deletions(-) diff --git a/lib/cache.coffee b/lib/cache.coffee index 4511530..86aec86 100644 --- a/lib/cache.coffee +++ b/lib/cache.coffee @@ -100,65 +100,87 @@ refresh = (callback) -> counter = 0 return - res.sort((a, b) -> - if a.weight == b.weight - return a._id > b._id - else - return a.weight - b.weight - ) + db.objectsCollection.find().toArray((err, objects) -> + if err + callback(err) if -- counter >= 0 + counter = 0 + return - presets = [] - - for preset in res - schedule = null - if preset.schedule - parts = preset.schedule.trim().split(/\s+/) - schedule = { - md5: crypto.createHash('md5').update(preset.schedule).digest('hex') - } - - try - schedule.duration = +(parts.shift()) * 1000 - parts.unshift('0') if parts.length == 5 - # TODO later.js doesn't throw erorr if expression is invalid! - schedule.schedule = later.schedule(later.parse.cron(parts.join(' '), true)) - catch err - # TODO show a warning - schedule.schedule = false - - events = preset.events ? {} - - precondition = query.convertMongoQueryToFilters(JSON.parse(preset.precondition)) - - _provisions = preset.provisions or [] - - # Generate provisions from the old configuration format - for c in preset.configurations - switch c.type - when 'age' - _provisions.push(['refresh', c.name, c.age]) - when 'value' - _provisions.push(['value', c.name, c.value]) - when 'add_tag' - _provisions.push(['tag', c.tag, true]) - when 'delete_tag' - _provisions.push(['tag', c.tag, false]) - when 'provision' - _provisions.push([c.name].concat(c.args or [])) - else - callback(new Error("Unknown configuration type #{c.type}")) if -- counter >= 0 - counter = 0 - return - - presets.push({name: preset._id, channel: preset.channel or 'default', schedule: schedule, events: events, precondition: precondition, provisions: _provisions}) - - if -- counter == 0 - computeHash() - db.redisClient.setex("presets_hash", 300, hash, (err) -> - unlockOrExtend(0) - nextRefresh = now + REFRESH - return callback() + res.sort((a, b) -> + if a.weight == b.weight + return a._id > b._id + else + return a.weight - b.weight ) + + presets = [] + + for preset in res + schedule = null + if preset.schedule + parts = preset.schedule.trim().split(/\s+/) + schedule = { + md5: crypto.createHash('md5').update(preset.schedule).digest('hex') + } + + try + schedule.duration = +(parts.shift()) * 1000 + parts.unshift('0') if parts.length == 5 + # TODO later.js doesn't throw erorr if expression is invalid! + schedule.schedule = later.schedule(later.parse.cron(parts.join(' '), true)) + catch err + # TODO show a warning + schedule.schedule = false + + events = preset.events ? {} + + precondition = query.convertMongoQueryToFilters(JSON.parse(preset.precondition)) + + _provisions = preset.provisions or [] + + # Generate provisions from the old configuration format + for c in preset.configurations + switch c.type + when 'age' + _provisions.push(['refresh', c.name, c.age]) + when 'value' + _provisions.push(['value', c.name, c.value]) + when 'add_tag' + _provisions.push(['tag', c.tag, true]) + when 'delete_tag' + _provisions.push(['tag', c.tag, false]) + when 'provision' + _provisions.push([c.name].concat(c.args or [])) + when 'add_object' + for obj in objects + if obj['_id'] == c.object + alias = ("#{k}:#{JSON.stringify(obj[k])}" for k in obj['_keys']).join(',') + p = "#{c.name}.[#{alias}]" + _provisions.push(['instances', p, 1]) + for k of obj + if k[0] != '_' and k not in obj['_keys'] + _provisions.push(['value', "#{p}.#{k}", obj[k]]) + when 'delete_object' + for obj in objects + if obj['_id'] == c.object + alias = ("#{k}:#{JSON.stringify(obj[k])}" for k in obj['_keys']).join(',') + p = "#{c.name}.[#{alias}]" + _provisions.push(['instances', p, 0]) + else + callback(new Error("Unknown configuration type #{c.type}")) if -- counter >= 0 + counter = 0 + return + + presets.push({name: preset._id, channel: preset.channel or 'default', schedule: schedule, events: events, precondition: precondition, provisions: _provisions}) + + if -- counter == 0 + computeHash() + db.redisClient.setex("presets_hash", 300, hash, (err) -> + unlockOrExtend(0) + nextRefresh = now + REFRESH + return callback() + ) + ) ) db.provisionsCollection.find().toArray((err, res) -> diff --git a/lib/cwmp.coffee b/lib/cwmp.coffee index 538e650..1017e19 100644 --- a/lib/cwmp.coffee +++ b/lib/cwmp.coffee @@ -400,7 +400,14 @@ nextRpc = (currentRequest) -> [['reset']]) when 'download' session.addProvisions(currentRequest.sessionData, "task_#{task._id}", - [['download', task.fileType, task.fileName, task.targetFileName]]) + [['download', task.fileType, task.fileName, task.targetFileName]]) + when 'addObject' + alias = ("#{p[0]}:#{JSON.stringify(p[1])}" for p in task.parameterValues or []).join(',') + session.addProvisions(currentRequest.sessionData, "task_#{task._id}", + [['instances', "#{task.objectName}.[#{alias}]", "+1"]]); + when 'deleteObject' + session.addProvisions(currentRequest.sessionData, "task_#{task._id}", + [['instances', task.objectName, 0]]); else return throwError(new Error('Task name not recognized'), currentRequest.httpResponse) if err diff --git a/lib/default-provisions.js b/lib/default-provisions.js index cabfc5f..e2f9ce7 100644 --- a/lib/default-provisions.js +++ b/lib/default-provisions.js @@ -18,6 +18,7 @@ const config = require("./config"); const common = require("./common"); +const device = require("./device"); const MAX_DEPTH = config.get("MAX_DEPTH"); @@ -79,9 +80,34 @@ function download(sessionData, provision, declarations, startRevision, endRevisi } +function instances(sessionData, provision, declarations, startRevision, endRevision) { + let count = Number(provision[2]); + + if (Number.isNaN(count)) + return true; + + let path = common.parsePath(provision[1]); + + if (provision[2][0] === "+" || provision[2][0] === "-") { + declarations.push([path, 1]); + + if (endRevision === startRevision) + return false; + + let unpacked = device.unpack(sessionData.deviceData, path, startRevision + 1); + count = Math.max(0, unpacked.length + count); + } + + declarations.push([path, 1, null, count]); + + return true; +} + + exports.refresh = refresh; exports.value = value; exports.tag = tag; exports.reboot = reboot; exports.reset = reset; exports.download = download; +exports.instances = instances;