Implement new path parameter mapping
diff --git a/README.md b/README.md
index 4fe1392..2a59f2f 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@
 
 This command starts an API Gateway that subscribes to the Redis instance with the specified host and port. The `REDIS_PASS` variable is optional and is required only when redis needs authentication. 
 
-On startup, the API Gateway looks for pre-existing resources in redis, whose keys are defined as `resources:<namespace>:<resource>`, and creates nginx conf files associated with those resources. Then, it listens for any resource key changes in redis and updates nginx conf files appropriately. These conf files are stored in the running docker container at `/etc/api-gateway/managed_confs/<namespace>/<resource>.conf`.
+On startup, the API Gateway subscribes to redis and listens for changes in keys that are defined as `resources:<namespace>:<resourcePath>`.
 
 ## Routes
 See [here](doc/routes.md) for the management interface for creating tenants/APIs. For detailed API policy definitions, see [here](doc/policies.md).
@@ -50,12 +50,7 @@
   make docker-run PUBLIC_MANAGEDURL_HOST=<mangedurl_host> PUBLIC_MANAGEDURL_PORT=<managedurl_port> \
     REDIS_HOST=<redis_host> REDIS_PORT=<redis_port> REDIS_PASS=<redis_pass>
  ```
- 
- The main API Gateway process is exposed to port `80`. To test that the Gateway works see its `health-check`:
- ```
-  $ curl http://<docker_host_ip>/health-check
-    API-Platform is running!
- ```
+
  
 ### Testing
 
diff --git a/api-gateway-config/conf.d/managed_endpoints.conf b/api-gateway-config/conf.d/managed_endpoints.conf
index 8d459db..37a5ed5 100644
--- a/api-gateway-config/conf.d/managed_endpoints.conf
+++ b/api-gateway-config/conf.d/managed_endpoints.conf
@@ -58,7 +58,7 @@
         ';
     }
 
-    location ~ ^/api/([a-zA-Z0-9\-]+)/([a-zA-Z0-9\-\/\-\_\{\}]+)(\\b) {
+    location ~ "^/api/([a-zA-Z0-9\-]+)/([a-zA-Z0-9\-\/\-\_\{\} ]+)(\\b)" {
         set $upstream https://172.17.0.1;
         set $tenant $1;
         set $backendUrl '';
diff --git a/api-gateway-config/scripts/lua/lib/redis.lua b/api-gateway-config/scripts/lua/lib/redis.lua
index dfdcb7a..2007b14 100644
--- a/api-gateway-config/scripts/lua/lib/redis.lua
+++ b/api-gateway-config/scripts/lua/lib/redis.lua
@@ -42,7 +42,7 @@
 -- @param timeout redis timeout in milliseconds
 function _M.init(host, port, password, timeout)
   local redis = require "resty.redis"
-  local red   = redis:new()
+  local red = redis:new()
   red:set_timeout(timeout)
   -- Connect to Redis server
   local retryCount = 4
@@ -213,18 +213,19 @@
   return resourceObj
 end
 
---- Get all resource keys in redis
+--- Get all resource keys for a tenant in redis
 -- @param red redis client instance
-function getAllResourceKeys(red)
+-- @param tenantId tenant id
+function _M.getAllResourceKeys(red, tenantId)
   -- Find all resourceKeys in redis
-  local resources, err = red:scan(0, "match", "resources:*:*")
+  local resources, err = red:scan(0, "match", utils.concatStrings({"resources:", tenantId, ":*"}))
   if not resources then
     request.err(500, util.concatStrings({"Failed to retrieve resource keys: ", err}))
   end
   local cursor = resources[1]
   local resourceKeys = resources[2]
   while cursor ~= "0" do
-    resources, err = red:scan(cursor, "match", "resources:*:*")
+    resources, err = red:scan(cursor, "match", utils.concatStrings({"resources:", tenantId, ":*"}))
     if not resources then
       request.err(500, util.concatStrings({"Failed to retrieve resource keys: ", err}))
     end
@@ -355,7 +356,6 @@
 ------- Pub/Sub with Redis --------
 -----------------------------------
 
-local gatewayReady = false
 --- Subscribe to redis
 -- @param redisSubClient the redis client that is listening for the redis key changes
 -- @param redisGetClient the redis client that gets the changed resource to update the conf file
@@ -371,7 +371,6 @@
     request.err(500, utils.concatStrings({"Failed to subscribe to redis: ", err}))
   end
   while true do
-    gatewayReady = true
     local res, err = redisSubClient:read_reply()
     if not res then
       if err ~= "timeout" then
@@ -383,13 +382,13 @@
       local redisKey = utils.concatStrings({resourcePrefix, ":", tenant, ":", gatewayPath})
       -- Don't allow single quotes in the gateway path
       if string.match(gatewayPath, "'") then
-        logger.debug(utils.concatStrings({"Redis key \"", redisKey, "\" contains illegal character \"'\"."}))
+        logger.info(utils.concatStrings({"Redis key \"", redisKey, "\" contains illegal character \"'\"."}))
       else
         local resourceObj = _M.getResource(redisGetClient, redisKey, REDIS_FIELD)
         if resourceObj == nil then
-          logger.debug(utils.concatStrings({"Redis key deleted: ", redisKey}))
+          logger.info(utils.concatStrings({"Redis key deleted: ", redisKey}))
         else
-          logger.debug(utils.concatStrings({"Redis key updated: ", redisKey}))
+          logger.info(utils.concatStrings({"Redis key updated: ", redisKey}))
         end
       end
     end
@@ -398,11 +397,7 @@
 
 --- Get gateway sync status
 function _M.healthCheck()
-  if gatewayReady == false then
-    request.success(503, "Status: Gateway starting up.")
-  else
-    request.success(200, "Status: Gateway ready.")
-  end
+  request.success(200,  "Status: Gateway ready.")
 end
 
 return _M
\ No newline at end of file
diff --git a/api-gateway-config/scripts/lua/lib/utils.lua b/api-gateway-config/scripts/lua/lib/utils.lua
index cdaec4e..d757c39 100644
--- a/api-gateway-config/scripts/lua/lib/utils.lua
+++ b/api-gateway-config/scripts/lua/lib/utils.lua
@@ -84,10 +84,23 @@
   end)
 end
 
+--- Check if element exists in table as value
+-- @param table table to check
+-- @param element element to check in table
+function tableContains(table, element)
+  for i, value in pairs(table) do
+    if value == element then
+      return true
+    end
+  end
+  return false
+end
+
 _Utils.concatStrings = concatStrings
 _Utils.serializeTable = serializeTable
 _Utils.convertTemplatedPathParam = convertTemplatedPathParam
 _Utils.uuid = uuid
+_Utils.tableContains = tableContains
 
 return _Utils
 
diff --git a/api-gateway-config/scripts/lua/management.lua b/api-gateway-config/scripts/lua/management.lua
index a720883..8108598 100644
--- a/api-gateway-config/scripts/lua/management.lua
+++ b/api-gateway-config/scripts/lua/management.lua
@@ -44,7 +44,7 @@
 --------------------------
 
 --- Add an api to the Gateway
--- PUT /APIs
+-- PUT /v1/apis
 -- body:
 -- {
 --    "name": *(String) name of API
@@ -83,6 +83,7 @@
   end
   -- Format basePath
   local basePath = decoded.basePath:sub(1,1) == '/' and decoded.basePath:sub(2) or decoded.basePath
+  basePath = basePath:sub(-1) == '/' and basePath:sub(1, -2) or basePath
   -- Create managedUrl object
   local uuid = existingAPI ~= nil and existingAPI.id or utils.uuid()
   local managedUrl = utils.concatStrings({"http://", MANAGEDURL_HOST, ":", MANAGEDURL_PORT, "/api/", decoded.tenantId})
@@ -101,7 +102,8 @@
   managedUrlObj = redis.addAPI(red, uuid, managedUrlObj, existingAPI)
   -- Add resources to redis
   for path, resource in pairs(decoded.resources) do
-    local gatewayPath = utils.concatStrings({basePath, ngx.escape_uri(path)})
+    local gatewayPath = utils.concatStrings({basePath, path})
+    gatewayPath = (gatewayPath:sub(1,1) == '/') and gatewayPath:sub(2) or gatewayPath
     addResource(red, resource, gatewayPath, decoded.tenantId)
   end
   redis.close(red)
@@ -229,7 +231,7 @@
 -- @param tenantId
 function addResource(red, resource, gatewayPath, tenantId)
   -- Create resource object and add to redis
-  local redisKey = utils.concatStrings({"resources", ":", tenantId, ":", ngx.unescape_uri(gatewayPath)})
+  local redisKey = utils.concatStrings({"resources", ":", tenantId, ":", gatewayPath})
   local apiId
   local operations
   for k, v in pairs(resource) do
@@ -244,7 +246,7 @@
 end
 
 --- Get one or all APIs from the gateway
--- GET /APIs
+-- GET /v1/apis
 function _M.getAPIs()
   local uri = string.gsub(ngx.var.request_uri, "?.*", "")
   local id
@@ -321,7 +323,7 @@
 end
 
 --- Delete API from gateway
--- DELETE /APIs/<id>
+-- DELETE /v1/apis/<id>
 function _M.deleteAPI()
   local uri = string.gsub(ngx.var.request_uri, "?.*", "")
   local index = 1
@@ -345,7 +347,8 @@
   -- Delete all resources for the API
   local basePath = api.basePath:sub(2)
   for path, v in pairs(api.resources) do
-    local gatewayPath = utils.concatStrings({basePath, ngx.escape_uri(path)})
+    local gatewayPath = utils.concatStrings({basePath, path})
+    gatewayPath = (gatewayPath:sub(1,1) == '/') and gatewayPath:sub(2) or gatewayPath
     deleteResource(red, gatewayPath, api.tenantId)
   end
   redis.close(red)
@@ -357,7 +360,7 @@
 -- @param gatewayPath path in gateway
 -- @param tenantId tenant id
 function deleteResource(red, gatewayPath, tenantId)
-  local redisKey = utils.concatStrings({"resources:", tenantId, ":", ngx.unescape_uri(gatewayPath)})
+  local redisKey = utils.concatStrings({"resources:", tenantId, ":", gatewayPath})
   redis.deleteResource(red, redisKey, REDIS_FIELD)
 end
 
@@ -366,7 +369,7 @@
 -----------------------------
 
 --- Add a tenant to the Gateway
--- PUT /Tenants
+-- PUT /v1/tenants
 -- body:
 -- {
 --    "namespace": *(String) tenant namespace
@@ -414,7 +417,7 @@
 end
 
 --- Get one or all tenants from the gateway
--- GET /Tenants
+-- GET /v1/tenants
 function _M.getTenants()
   local uri = string.gsub(ngx.var.request_uri, "?.*", "")
   local id
@@ -493,7 +496,7 @@
 end
 
 --- Delete tenant from gateway
--- DELETE /Tenants/<id>
+-- DELETE /v1/tenants/<id>
 function _M.deleteTenant()
   local uri = string.gsub(ngx.var.request_uri, "?.*", "")
   local index = 1
@@ -521,7 +524,6 @@
 -- GET /v1/sync
 function _M.sync()
   local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 10000)
-  logger.info(utils.concatStrings({"Connected to redis at ", REDIS_HOST, ":", REDIS_PORT}))
   redis.syncWithRedis(red)
   ngx.exit(200)
 end
@@ -531,6 +533,7 @@
 function _M.subscribe()
   local redisGetClient = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 10000)
   local redisSubClient = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
+  logger.info(utils.concatStrings({"Connected to redis at ", REDIS_HOST, ":", REDIS_PORT}))
   redis.subscribe(redisSubClient, redisGetClient)
   ngx.exit(200)
 end
diff --git a/api-gateway-config/scripts/lua/policies/mapping.lua b/api-gateway-config/scripts/lua/policies/mapping.lua
index 6748fe3..97f7c71 100644
--- a/api-gateway-config/scripts/lua/policies/mapping.lua
+++ b/api-gateway-config/scripts/lua/policies/mapping.lua
@@ -70,7 +70,7 @@
 --- Insert parameter value to header, body, or query params into request
 -- @param m Parameter value to add to request
 function insertParam(m)
-  local v = nil
+  local v
   local k = m.to.name
   if m.from.value ~= nil then
     v = m.from.value
@@ -81,7 +81,7 @@
   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})]
+    v = ngx.ctx[m.from.name]
   end
   -- determine to where
   if m.to.location == 'header' then
@@ -208,8 +208,8 @@
 
 function insertPath(k, v)
   v = ngx.unescape_uri(v)
-  local primedUri = path:gsub("%{(%w*)%}", v)
-  ngx.req.set_uri(primedUri)
+  path = path:gsub(utils.concatStrings({"%{", k ,"%}"}), v)
+  ngx.req.set_uri(path)
 end
 
 function removeHeader(k)
diff --git a/api-gateway-config/scripts/lua/routing.lua b/api-gateway-config/scripts/lua/routing.lua
index ab62bb7..1b896dd 100644
--- a/api-gateway-config/scripts/lua/routing.lua
+++ b/api-gateway-config/scripts/lua/routing.lua
@@ -31,6 +31,7 @@
 local security = require "policies/security"
 local mapping = require "policies/mapping"
 local rateLimit = require "policies/rateLimit"
+local logger = require "lib/logger"
 
 local REDIS_HOST = os.getenv("REDIS_HOST")
 local REDIS_PORT = os.getenv("REDIS_PORT")
@@ -40,12 +41,17 @@
 
 --- Main function that handles parsing of invocation details and carries out implementation
 function processCall()
-  -- Handle path parameters
-  ngx.var.gatewayPath = ngx.unescape_uri(ngx.var.gatewayPath):gsub("%{(%w*)%}", utils.convertTemplatedPathParam)
   -- Get resource object from redis
   local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 10000)
   local redisKey = utils.concatStrings({"resources:", ngx.var.tenant, ":", ngx.var.gatewayPath})
   local obj = redis.getResource(red, redisKey, "resources")
+  -- Check for path parameters
+  if obj == nil then
+    obj = checkForPathParams(red)
+    if obj == nil then
+      return request.err(404, 'API doesn\'t exist.')
+    end
+  end
   obj = cjson.decode(obj)
   local found = false
   for verb, opFields in pairs(obj.operations) do
@@ -82,6 +88,33 @@
   end
 end
 
+--- Check redis for path parameters
+-- @param red redis client instance
+function checkForPathParams(red)
+  local resourceKeys = redis.getAllResourceKeys(red, ngx.var.tenant)
+  for i, key in pairs(resourceKeys) do
+    local res = {string.match(key, "([^,]+):([^,]+):([^,]+)")}
+    local path = res[3] -- gatewayPath portion of redis key
+    local pathParamVars = {}
+    for w in string.gfind(path, "({%w+})") do
+      w = string.gsub(w, "{", "")
+      w = string.gsub(w, "}", "")
+      pathParamVars[#pathParamVars + 1] = w
+    end
+    if next(pathParamVars) ~= nil then
+      local pathPattern, count = string.gsub(path, "%{(%w*)%}", "([^,]+)")
+      local obj = {string.match(ngx.var.gatewayPath, pathPattern)}
+      if (#obj == count) then
+        for i, v in pairs(obj) do
+          ngx.ctx[pathParamVars[i]] = v
+        end
+        return redis.getResource(red, key, "resources")
+      end
+    end
+  end
+  return nil
+end
+
 --- Function to read the list of policies and send implementation to the correct backend
 -- @param obj List of policies containing a type and value field. This function reads the type field and routes it appropriately.
 -- @param apiKey optional subscription api key
@@ -98,34 +131,24 @@
 --- Given a verb, transforms the backend request to use that method
 -- @param v Verb to set on the backend request
 function setVerb(v)
-  if (string.lower(v) == 'post') then
-    ngx.req.set_method(ngx.HTTP_POST)
-  elseif (string.lower(v) == 'put') then
-    ngx.req.set_method(ngx.HTTP_PUT)
-  elseif (string.lower(v) == 'delete') then
-    ngx.req.set_method(ngx.HTTP_DELETE)
-  elseif (string.lower(v) == 'patch') then
-    ngx.req.set_method(ngx.HTTP_PATCH)
-  elseif (string.lower(v) == 'head') then
-    ngx.req.set_method(ngx.HTTP_HEAD)
-  elseif (string.lower(v) == 'options') then
-    ngx.req.set_method(ngx.HTTP_OPTIONS)
+  local allowedVerbs = {'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'}
+  local verb = string.upper(v)
+  if(utils.tableContains(allowedVerbs, verb)) then
+    ngx.req.set_method(ngx[utils.concatStrings({"HTTP_", verb})])
   else
     ngx.req.set_method(ngx.HTTP_GET)
   end
 end
 
 function getUriPath(backendPath)
-  local uriPath
-  local i, j = ngx.var.uri:find(ngx.var.gatewayPath)
+  local i, j = ngx.var.uri:find(ngx.unescape_uri(ngx.var.gatewayPath))
   local incomingPath = ((j and ngx.var.uri:sub(j + 1)) or nil)
   -- Check for backendUrl path
-  if backendPath == nil or backendPath== '' or backendPath== '/' then
-    uriPath = (incomingPath and incomingPath ~= '') and incomingPath or '/'
+  if backendPath == nil or backendPath == '' or backendPath == '/' then
+    return (incomingPath and incomingPath ~= '') and incomingPath or '/'
   else
-    uriPath = utils.concatStrings({backendPath, incomingPath})
+    return utils.concatStrings({backendPath, incomingPath})
   end
-  return uriPath
 end
 
 _M.processCall = processCall