From 6cf6e0d07c5d90f7fd594c19f4bdd3773a4a149c Mon Sep 17 00:00:00 2001 From: David Ortiz Date: Fri, 2 Feb 2018 12:24:30 +0100 Subject: [PATCH] Extract MappingRule from Configuration --- gateway/src/apicast/configuration.lua | 66 +------------------ gateway/src/apicast/mapping_rule.lua | 94 +++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 64 deletions(-) create mode 100644 gateway/src/apicast/mapping_rule.lua diff --git a/gateway/src/apicast/configuration.lua b/gateway/src/apicast/configuration.lua index 771343d22..d220709c0 100644 --- a/gateway/src/apicast/configuration.lua +++ b/gateway/src/apicast/configuration.lua @@ -5,20 +5,18 @@ local _M = { local len = string.len local pairs = pairs local type = type -local error = error local tostring = tostring local next = next local lower = string.lower local insert = table.insert local setmetatable = setmetatable -local re_match = ngx.re.match -local inspect = require 'inspect' local re = require 'ngx.re' local env = require 'resty.env' local resty_url = require 'resty.url' local util = require 'apicast.util' local policy_chain = require 'apicast.policy_chain' +local mapping_rule = require 'apicast.mapping_rule' local mt = { __index = _M, __tostring = function() return 'Configuration' end } @@ -30,54 +28,6 @@ local function map(func, tbl) return newtbl end -local function regexpify(path) - return path:gsub('?.*', ''):gsub("{.-}", '([\\w_.-]+)'):gsub("%.", "\\.") -end - -local regex_variable = '\\{[-\\w_]+\\}' - -local function hash_to_array(hash) - local array = {} - for k,v in pairs(hash or {}) do - insert(array, { k, v }) - end - return array -end - -local function check_querystring_params(params, args) - local match = true - - for i=1, #params do - local param = params[i][1] - local expected = params[i][2] - local m, err = re_match(expected, regex_variable, 'oj') - local value = args[param] - - if m then - if not value then -- regex variable have to have some value - ngx.log(ngx.DEBUG, 'check query params ', param, ' value missing ', expected) - match = false - break - end - else - if err then ngx.log(ngx.ERR, 'check match error ', err) end - - -- if many values were passed use the last one - if type(value) == 'table' then - value = value[#value] - end - - if value ~= expected then -- normal variables have to have exact value - ngx.log(ngx.DEBUG, 'check query params does not match ', param, ' value ' , value, ' == ', expected) - match = false - break - end - end - end - - return match -end - local Service = require 'apicast.configuration.service' local noop = function() end @@ -159,19 +109,7 @@ function _M.parse_service(service) app_key = lower(proxy.auth_app_key or 'app_key') -- TODO: use App-Key if location is headers }, rules = map(function(proxy_rule) - local querystring_parameters = hash_to_array(proxy_rule.querystring_parameters) - - return { - method = proxy_rule.http_method, - pattern = proxy_rule.pattern, - regexpified_pattern = regexpify(proxy_rule.pattern), - parameters = proxy_rule.parameters, - querystring_params = function(args) - return check_querystring_params(querystring_parameters, args) - end, - system_name = proxy_rule.metric_system_name or error('missing metric name of rule ' .. inspect(proxy_rule)), - delta = proxy_rule.delta - } + return mapping_rule.from_proxy_rule(proxy_rule) end, proxy.proxy_rules or {}), -- I'm not happy about this, but we need a way how to serialize back the object for the management API. diff --git a/gateway/src/apicast/mapping_rule.lua b/gateway/src/apicast/mapping_rule.lua new file mode 100644 index 000000000..89d34eccf --- /dev/null +++ b/gateway/src/apicast/mapping_rule.lua @@ -0,0 +1,94 @@ +local setmetatable = setmetatable +local pairs = pairs +local error = error +local type = type +local re_match = ngx.re.match +local insert = table.insert + +local _M = {} + +local mt = { __index = _M } + +local function hash_to_array(hash) + local array = {} + + for k,v in pairs(hash or {}) do + insert(array, { k, v }) + end + + return array +end + +local function regexpify(path) + return path:gsub('?.*', ''):gsub("{.-}", '([\\w_.-]+)'):gsub("%.", "\\.") +end + +local regex_variable = '\\{[-\\w_]+\\}' + +local function check_querystring_params(params, args) + local match = true + + for i=1, #params do + local param = params[i][1] + local expected = params[i][2] + local m, err = re_match(expected, regex_variable, 'oj') + local value = args[param] + + if m then + if not value then -- regex variable have to have some value + ngx.log(ngx.DEBUG, 'check query params ', param, + ' value missing ', expected) + match = false + break + end + else + if err then ngx.log(ngx.ERR, 'check match error ', err) end + + -- if many values were passed use the last one + if type(value) == 'table' then + value = value[#value] + end + + if value ~= expected then -- normal variables have to have exact value + ngx.log(ngx.DEBUG, 'check query params does not match ', + param, ' value ' , value, ' == ', expected) + match = false + break + end + end + end + + return match +end + +function _M.new(http_method, pattern, params, querystring_params, metric, delta) + local self = setmetatable({}, mt) + + local querystring_parameters = hash_to_array(querystring_params) + + self.method = http_method + self.pattern = pattern + self.regexpified_pattern = regexpify(pattern) + self.parameters = params + self.system_name = metric or error('missing metric name of rule') + self.delta = delta + + self.querystring_params = function(args) + return check_querystring_params(querystring_parameters, args) + end + + return self +end + +function _M.from_proxy_rule(proxy_rule) + return _M.new( + proxy_rule.http_method, + proxy_rule.pattern, + proxy_rule.parameters, + proxy_rule.querystring_parameters, + proxy_rule.metric_system_name, + proxy_rule.delta + ) +end + +return _M