Merge pull request #25 from apimesh/pathParam
Path param
diff --git a/api-gateway-config/scripts/lua/lib/filemgmt.lua b/api-gateway-config/scripts/lua/lib/filemgmt.lua
index 95a506e..7c0ed03 100644
--- a/api-gateway-config/scripts/lua/lib/filemgmt.lua
+++ b/api-gateway-config/scripts/lua/lib/filemgmt.lua
@@ -35,16 +35,18 @@
-- @param resourceObj object containing different operations/policies for the resource
-- @return fileLocation location of created/updated conf file
function _M.createResourceConf(baseConfDir, tenant, gatewayPath, resourceObj)
+ resourceObj = utils.serializeTable(cjson.decode(resourceObj))
local decoded = cjson.decode(resourceObj)
- resourceObj = utils.serializeTable(decoded)
+
local prefix = utils.concatStrings({"\tinclude /etc/api-gateway/conf.d/commons/common-headers.conf;\n",
"\tset $upstream https://172.17.0.1;\n",
"\tset $tenant ", tenant, ";\n",
- "\tset $gatewayPath ", gatewayPath, ";\n"})
+ "\tset $gatewayPath ", utils.concatStrings({"\"", ngx.unescape_uri(gatewayPath),
+ "\""}), ";\n\n"})
if decoded.apiId ~= nil then
prefix = utils.concatStrings({prefix, "\tset $apiId ", decoded.apiId, ";\n"})
end
- -- Set route headers and mapping by calling routing.processCall()
+ -- Set resource headers and mapping by calling routing.processCall()
local outgoingResource = utils.concatStrings({"\taccess_by_lua_block {\n",
"\t\tlocal routing = require \"routing\"\n",
"\t\trouting.processCall(", resourceObj, ")\n",
@@ -57,7 +59,10 @@
if not file then
request.err(500, utils.concatStrings({"Error adding to endpoint conf file: ", err}))
end
- local location = utils.concatStrings({"location /api/", tenant, "/", ngx.unescape_uri(gatewayPath), " {\n",
+
+ local updatedPath = ngx.unescape_uri(gatewayPath):gsub("%{(%w*)%}", utils.convertTemplatedPathParam)
+
+ local location = utils.concatStrings({"location ~ ^/api/", tenant, "/", updatedPath, " {\n",
prefix,
outgoingResource,
"}\n"})
diff --git a/api-gateway-config/scripts/lua/lib/utils.lua b/api-gateway-config/scripts/lua/lib/utils.lua
index 1ed2897..a064037 100644
--- a/api-gateway-config/scripts/lua/lib/utils.lua
+++ b/api-gateway-config/scripts/lua/lib/utils.lua
@@ -22,6 +22,7 @@
--
-- @author Alex Song (songs), Cody Walker (cmwalker)
+local cjson = require "cjson"
local _Utils = {}
--- Concatenate a list of strings into a single string. This is more efficient than concatenating
@@ -65,7 +66,36 @@
return table.concat(tt)
end
+--- Concatenate the path param name into string variable to be replaced by the path param value
+-- at time of being called by the user
+-- @param m where m is the string "{pathParam}"
+-- @return concatenated string of (?<path_pathParam>(\\w+))
+function convertTemplatedPathParam(m)
+ local x = m:gsub("{", ""):gsub("}", "")
+ return concatStrings({"(?<path_" , x , ">([a-zA-Z0-9\\-\\s\\_\\%]*))"})
+end
+
+
+--- Convert JSON body to Lua table using the cjson module
+-- @param args Lua table with its key as the string representation of a JSON body
+-- @return Lua table representation of JSON
+function convertJSONBody(args)
+ local jsonStringList = {}
+ for key, value in pairs(args) do
+ table.insert(jsonStringList, key)
+ -- Handle case where the "=" character is inside any of the strings in the json body
+ if(value ~= true) then
+ table.insert(jsonStringList, concatStrings({"=", value}))
+ end
+ end
+ return cjson.decode(concatStrings(jsonStringList))
+end
+
+
+_Utils.convertJSONBody = convertJSONBody
_Utils.concatStrings = concatStrings
_Utils.serializeTable = serializeTable
+_Utils.convertTemplatedPathParam = convertTemplatedPathParam
return _Utils
+
diff --git a/api-gateway-config/scripts/lua/management.lua b/api-gateway-config/scripts/lua/management.lua
index acb2a16..08b9276 100644
--- a/api-gateway-config/scripts/lua/management.lua
+++ b/api-gateway-config/scripts/lua/management.lua
@@ -60,7 +60,8 @@
request.err(400, "Missing Request body")
end
-- Convert json into Lua table
- local decoded = convertJSONBody(args)
+ local decoded = utils.convertJSONBody(args)
+
-- Error handling for required fields in the request body
local gatewayMethod = decoded.gatewayMethod
if not gatewayMethod then
@@ -272,22 +273,8 @@
if not list[1] or not list[2] then
request.err(400, "Request path should be \"/resources/<tenant>/<url-encoded-resource>\"")
end
- return list --prefix, tenant, gatewayPath
-end
---- Convert JSON body to Lua table using the cjson module
--- @param args Lua table with its key as the string representation of a JSON body
--- @return Lua table representation of JSON
-function convertJSONBody(args)
- local jsonStringList = {}
- for key, value in pairs(args) do
- table.insert(jsonStringList, key)
- -- Handle case where the "=" character is inside any of the strings in the json body
- if(value ~= true) then
- table.insert(jsonStringList, utils.concatStrings({"=", value}))
- end
- end
- return cjson.decode(utils.concatStrings(jsonStringList))
+ return list --prefix, tenant, gatewayPath, apiKey
end
return _M
\ No newline at end of file
diff --git a/api-gateway-config/scripts/lua/policies/mapping.lua b/api-gateway-config/scripts/lua/policies/mapping.lua
index 9272c63..0ad97e3 100644
--- a/api-gateway-config/scripts/lua/policies/mapping.lua
+++ b/api-gateway-config/scripts/lua/policies/mapping.lua
@@ -24,12 +24,14 @@
local logger = require "lib/logger"
local utils = require "lib/utils"
local cjson = require "cjson"
+local url = require "url"
local _M = {}
local body = nil
local query = nil
local headers = nil
+local path = nil
--- Implementation for the mapping policy.
-- @param map The mapping object that contains details about request tranformations
@@ -51,12 +53,14 @@
--- Get request body, params, and headers from incoming requests
function getRequestParams()
- body = ngx.req.get_body_data()
- if body == nil then
- body = {}
+ ngx.req.read_body()
+ body = ngx.req.get_post_args()
+ if next(body) then
+ body = utils.convertJSONBody(body)
end
query = ngx.req.get_uri_args()
- headers = ngx.resp.get_headers()
+ headers = ngx.req.get_headers()
+ path = ngx.var.uri
end
--- Insert parameter value to header, body, or query params into request
@@ -72,6 +76,8 @@
v = query[m.from.name]
elseif m.from.location == 'body' then
v = body[m.from.name]
+ elseif m.from.location == 'path' then
+ v = ngx.var[utils.concatStrings({'path_', m.from.name})]
end
-- determine to where
if m.to.location == 'header' then
@@ -80,6 +86,8 @@
insertQuery(k, v)
elseif m.to.location == 'body' then
insertBody(k, v)
+ elseif m.to.location == 'path' then
+ insertPath(k,v)
end
end
@@ -148,13 +156,24 @@
insertParam(t)
removeParam(t)
end
+ elseif s == 'path' then
+ for k, v in pairs(path) do
+ local t = {}
+ t.from = {}
+ t.from.name = k
+ t.from.location = s
+ t.to = {}
+ t.to.name = k
+ t.to.location = d
+ insertParam(t)
+ removeParam(t)
+ end
end
end
function finalize()
local bodyJson = cjson.encode(body)
ngx.req.set_body_data(bodyJson)
- ngx.req.set_uri_args(query)
end
function insertHeader(k, v)
@@ -163,12 +182,19 @@
function insertQuery(k, v)
query[k] = v
+ ngx.req.set_uri_args(query)
end
function insertBody(k, v)
body[k] = v
end
+function insertPath(k, v)
+ v = ngx.unescape_uri(v)
+ local primedUri = path:gsub("%{(%w*)%}", v)
+ ngx.req.set_uri(primedUri)
+end
+
function removeHeader(k)
ngx.req.clear_header(k)
end