diff --git a/lib/cache.coffee b/lib/cache.coffee index 8a5f22c..d0bd9f6 100644 --- a/lib/cache.coffee +++ b/lib/cache.coffee @@ -21,6 +21,8 @@ crypto = require 'crypto' later = require 'later' db = require './db' +query = require './query' + REFRESH = 3000 @@ -124,7 +126,7 @@ refresh = (callback) -> events = preset.events ? {} - precondition = JSON.parse(preset.precondition) + precondition = query.convertMongoQueryToFilters(JSON.parse(preset.precondition)) _provisions = preset.provisions or [] diff --git a/lib/cwmp.coffee b/lib/cwmp.coffee index cb9888c..b6afc2d 100644 --- a/lib/cwmp.coffee +++ b/lib/cwmp.coffee @@ -179,8 +179,9 @@ applyPresets = (currentRequest) -> (p.schedule.schedule and testSchedule(p.schedule, currentRequest.sessionData.timestamp)[0])) filteredPresets.push(p) - for a in Object.keys(query.queryProjection(p.precondition)) - parameters[a] = common.parsePath(a) + for k of p.precondition + p = k.split(/([^a-zA-Z0-9\-\_\.].*)/, 1)[0] + parameters[p] = common.parsePath(p) declarations = [] for k, v of parameters @@ -196,12 +197,14 @@ applyPresets = (currentRequest) -> unpacked = device.unpack(currentRequest.sessionData.deviceData, v) if unpacked[0] and (vv = currentRequest.sessionData.deviceData.attributes.get(unpacked[0]).value?[1])? parameters[k] = vv[0] + else + delete parameters[k] if whiteList? session.addProvisions(currentRequest.sessionData, whiteList, whiteListProvisions) for p in filteredPresets - if query.test(parameters, p.precondition) + if query.testFilter(parameters, p.precondition) session.addProvisions(currentRequest.sessionData, p.channel, p.provisions) session.rpcRequest(currentRequest.sessionData, null, (err, id, rpcRequest) -> diff --git a/lib/query.coffee b/lib/query.coffee index d7a4f42..c82f493 100644 --- a/lib/query.coffee +++ b/lib/query.coffee @@ -242,6 +242,74 @@ test = (params, query) -> return true +testFilter = (obj, filter) -> + for k, v of filter + [param, op] = k.split(/([^a-zA-Z0-9\-\_\.].*)/, 2) + val = common.matchType(obj[param], v) + switch op + when '=', undefined + return false if obj[param] != val + when '>' + return false if not (obj[param] > val) + when '>=' + return false if not (obj[param] >= val) + when '<' + return false if not (obj[param] < val) + when '<=' + return false if not (obj[param] <= val) + when '!' + return false if obj[param] == val + else + throw new Error("Unrecognized operator #{op}") + + return true + + +convertMongoQueryToFilters = (query, filters) -> + filters ?= {} + for k, v of query + if k[0] == '$' + if k == '$and' + for vv in v + convertMongoQueryToFilters(vv, filters) + else + throw new Error("Operator #{k} not supported") + else if k == '_tags' + if common.typeOf(v) is common.OBJECT_TYPE + for kk, vv of v + vv = vv.replace(/[^a-zA-Z0-9\-]+/g, '_') + switch kk + when '$ne' + filters["Tags.#{vv}!"] = true + else + throw new Error("Operator #{kk} not supported") + else + v = v.replace(/[^a-zA-Z0-9\-]+/g, '_') + filters["Tags.#{v}"] = true + else + if common.typeOf(v) is common.OBJECT_TYPE + for kk, vv of v + switch kk + when '$eq' + filters[k] = vv + when '$ne' + filters["#{k}!"] = vv + when '$lt' + filters["#{k}<"] = vv + when '$lte' + filters["#{k}<="] = vv + when '$gt' + filters["#{k}>"] = vv + when '$gte' + filters["#{k}>="] = vv + else + throw new Error("Oprator #{kk} not supported") + else + filters[k] = v + + return filters + + sanitizeQueryTypes = (query, types) -> for k, v of query if k[0] == '$' # logical operator @@ -268,3 +336,5 @@ exports.expand = expand exports.queryProjection = queryProjection exports.test = test exports.sanitizeQueryTypes = sanitizeQueryTypes +exports.convertMongoQueryToFilters = convertMongoQueryToFilters +exports.testFilter = testFilter