Refactor management interface error handling
diff --git a/api-gateway-config/scripts/lua/management.lua b/api-gateway-config/scripts/lua/management.lua
index 05cb3d3..a720883 100644
--- a/api-gateway-config/scripts/lua/management.lua
+++ b/api-gateway-config/scripts/lua/management.lua
@@ -133,63 +133,95 @@
       return false, { statusCode = 404, message = utils.concatStrings({"Unknown tenant id ", object }) }
     end
   end
-  -- Additional checks for resource object
   if field == "resources" then
-    local resources = object
-    if next(object) == nil then
-      return false, { statusCode = 400, message = "Empty resources object." }
-    end
-    for path, resource in pairs(resources) do
-      -- Check resource path for illegal characters
-      if string.match(path, "'") then
-        return false, { statusCode = 400, message = "resource path contains illegal character \"'\"." }
-      end
-      -- Check that resource path begins with slash
-      if path:sub(1,1) ~= '/' then
-        return false, { statusCode = 400, message = "Resource path must begin with '/'." }
-      end
-      -- Check operations object
-      if not resource.operations or next(resource.operations) == nil then
-        return false, { statusCode = 400, message = "Missing or empty field 'operations' or in resource path object." }
-      end
-      for verb, verbObj in pairs(resource.operations) do
-        local allowedVerbs = {GET=true, POST=true, PUT=true, DELETE=true, PATCH=true, HEAD=true, OPTIONS=true}
-        if allowedVerbs[verb:upper()] == nil then
-          return false, { statusCode = 400, message = utils.concatStrings({"Resource verb '", verb, "' not supported."}) }
-        end
-        -- Check required fields
-        local requiredFields = {"backendMethod", "backendUrl"}
-        for k, v in pairs(requiredFields) do
-          if verbObj[v] == nil then
-            return false, { statusCode = 400, message = utils.concatStrings({"Missing field '", v, "' for '", verb, "' operation."}) }
-          end
-          if v == "backendMethod" then
-            local backendMethod = verbObj[v]
-            if allowedVerbs[backendMethod:upper()] == nil then
-              return false, { statusCode = 400, message = utils.concatStrings({"backendMethod '", backendMethod, "' not supported."}) }
-            end
-          end
-        end
-        -- Check optional fields
-        local policies = verbObj.policies
-        if policies then
-          for k, v in pairs(policies) do
-            if v.type == nil then
-              return false, { statusCode = 400, message = "Missing field 'type' in policy object." }
-            end
-          end
-        end
-        local security = verbObj.security
-        if security and security.type == nil then
-          return false, { statusCode = 400, message = "Missing field 'type' in security object." }
-        end
-      end
+    local res, err = checkResources(object)
+    if res ~= nil and res == false then
+      return res, err
     end
   end
   -- All error checks passed
   return true
 end
 
+--- Error checking for resources
+-- @param resources resources object
+function checkResources(resources)
+  if next(resources) == nil then
+    return false, { statusCode = 400, message = "Empty resources object." }
+  end
+  for path, resource in pairs(resources) do
+    -- Check resource path for illegal characters
+    if string.match(path, "'") then
+      return false, { statusCode = 400, message = "resource path contains illegal character \"'\"." }
+    end
+    -- Check that resource path begins with slash
+    if path:sub(1,1) ~= '/' then
+      return false, { statusCode = 400, message = "Resource path must begin with '/'." }
+    end
+    -- Check operations object
+    local res, err = checkOperations(resource.operations)
+    if res ~= nil and res == false then
+      return res, err
+    end
+  end
+end
+
+--- Error checking for operations
+-- @param operations operations object
+function checkOperations(operations)
+  if not operations or next(operations) == nil then
+    return false, { statusCode = 400, message = "Missing or empty field 'operations' or in resource path object." }
+  end
+  local allowedVerbs = {GET=true, POST=true, PUT=true, DELETE=true, PATCH=true, HEAD=true, OPTIONS=true}
+  for verb, verbObj in pairs(operations) do
+    if allowedVerbs[verb:upper()] == nil then
+      return false, { statusCode = 400, message = utils.concatStrings({"Resource verb '", verb, "' not supported."}) }
+    end
+    -- Check required fields
+    local requiredFields = {"backendMethod", "backendUrl"}
+    for k, v in pairs(requiredFields) do
+      if verbObj[v] == nil then
+        return false, { statusCode = 400, message = utils.concatStrings({"Missing field '", v, "' for '", verb, "' operation."}) }
+      end
+      if v == "backendMethod" then
+        local backendMethod = verbObj[v]
+        if allowedVerbs[backendMethod:upper()] == nil then
+          return false, { statusCode = 400, message = utils.concatStrings({"backendMethod '", backendMethod, "' not supported."}) }
+        end
+      end
+    end
+    -- Check optional fields
+    local res, err = checkOptionalPolicies(verbObj.policies, verbObj.security)
+    if res ~= nil and res == false then
+      return res, err
+    end
+  end
+end
+
+--- Error checking for policies and security
+-- @param policies policies object
+-- @param security security object
+function checkOptionalPolicies(policies, security)
+  if policies then
+    for k, v in pairs(policies) do
+      local validTypes = {reqMapping = true, rateLimit = true}
+      if (v.type == nil or v.value == nil) then
+        return false, { statusCode = 400, message = "Missing field in policy object. Need \"type\" and \"scope\"." }
+      elseif validTypes[v.type] == nil then
+        return false, { statusCode = 400, message = "Invalid type in policy object. Valid: \"reqMapping\", \"rateLimit\"" }
+      end
+    end
+  end
+  if security then
+    local validScopes = {tenant=true, api=true, resource=true}
+    if (security.type == nil or security.scope == nil) then
+      return false, { statusCode = 400, message = "Missing field in security object. Need \"type\" and \"scope\"." }
+    elseif validScopes[security.scope] == nil then
+      return false, { statusCode = 400, message = "Invalid scope in security object. Valid: \"tenant\", \"api\", \"resource\"." }
+    end
+  end
+end
+
 --- Helper function for adding a resource to redis and creating an nginx conf file
 -- @param red
 -- @param resource
@@ -518,9 +550,9 @@
 -- {
 --    key: *(String) key for tenant/api/resource
 --    scope: *(String) tenant or api or resource
---    tenant: *(String) tenant id
+--    tenantId: *(String) tenant id
 --    resource: (String) url-encoded resource path
---    api: (String) api id
+--    apiId: (String) api id
 -- }
 function _M.addSubscription()
   -- Validate body and create redisKey
@@ -539,9 +571,9 @@
 -- {
 --    key: *(String) key for tenant/api/resource
 --    scope: *(String) tenant or api or resource
---    tenant: *(String) tenant id
+--    tenantId: *(String) tenant id
 --    resource: (String) url-encoded resource path
---    api: (String) api id
+--    apiId: (String) api id
 -- }
 function _M.deleteSubscription()
   -- Validate body and create redisKey
@@ -560,19 +592,14 @@
 function validateSubscriptionBody()
   -- Read in the PUT JSON Body
   ngx.req.read_body()
-  local args = ngx.req.get_post_args()
+  local args = ngx.req.get_body_data()
   if not args then
     request.err(400, "Missing request body.")
   end
   -- Convert json into Lua table
-  local decoded
-  if next(args) then
-    decoded = utils.convertJSONBody(args)
-  else
-    request.err(400, "Request body required.")
-  end
+  local decoded = cjson.decode(args)
   -- Check required fields
-  local requiredFieldList = {"key", "scope", "tenant"}
+  local requiredFieldList = {"key", "scope", "tenantId"}
   for i, field in ipairs(requiredFieldList) do
     if not decoded[field] then
       request.err(400, utils.concatStrings({"\"", field, "\" missing from request body."}))
@@ -582,7 +609,7 @@
   local resource = decoded.resource
   local apiId = decoded.apiId
   local redisKey
-  local prefix = utils.concatStrings({"subscriptions:tenant:", decoded.tenant})
+  local prefix = utils.concatStrings({"subscriptions:tenant:", decoded.tenantId})
   if decoded.scope == "tenant" then
     redisKey = prefix
   elseif decoded.scope == "resource" then
diff --git a/doc/routes.md b/doc/routes.md
index 33887d0..dc9a2a5 100644
--- a/doc/routes.md
+++ b/doc/routes.md
@@ -245,9 +245,9 @@
 {
   "key": *(string) The api key to store to redis.
   "scope": *(string) The scope to use the api key. "tenant", "resource", or "api".
-  "tenant": *(string) Tenant guid.
+  "tenantId": *(string) Tenant guid.
   "resource": (string) Resource path. Required if scope is "resource".
-  "api": (string) API Guid. Required if scope is "API".
+  "apiId": (string) API Guid. Required if scope is "API".
 }
 ```
 
@@ -264,9 +264,9 @@
 {
   "key": *(string) The api key to delete.
   "scope": *(string) The scope to use the api key. "tenant", "resource", or "api".
-  "tenant": *(string) Tenant guid.
+  "tenantId": *(string) Tenant guid.
   "resource": (string) Resource path. Required if scope is "resource".
-  "api": (string) API Guid. Required if scope is "API".
+  "apiId": (string) API Guid. Required if scope is "API".
 }
 ```