scripts/lua/management/lib/apis.lua (111 lines of code) (raw):

-- -- Licensed to the Apache Software Foundation (ASF) under one or more -- contributor license agreements. See the NOTICE file distributed with -- this work for additional information regarding copyright ownership. -- The ASF licenses this file to You under the Apache License, Version 2.0 -- (the "License"); you may not use this file except in compliance with -- the License. You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- --- @module apis -- Module for querying APIs local cjson = require "cjson" local utils = require "lib/utils" local request = require "lib/request" local resources = require "management/lib/resources" local MANAGEDURL_HOST = os.getenv("PUBLIC_MANAGEDURL_HOST") MANAGEDURL_HOST = (MANAGEDURL_HOST ~= nil and MANAGEDURL_HOST ~= '') and MANAGEDURL_HOST or "0.0.0.0" local MANAGEDURL_PORT = os.getenv("PUBLIC_MANAGEDURL_PORT") MANAGEDURL_PORT = (MANAGEDURL_PORT ~= nil and MANAGEDURL_PORT ~= '') and MANAGEDURL_PORT or "8080" local GATEWAY_URL = os.getenv("PUBLIC_GATEWAY_URL") GATEWAY_URL = (GATEWAY_URL ~= nil and GATEWAY_URL ~= '') and GATEWAY_URL or utils.concatStrings({"http://", MANAGEDURL_HOST, ":", MANAGEDURL_PORT}) local _M = {} --- Filter APIs based on query parameters -- @param apis list of apis -- @param queryParams query parameters to filter tenants local function filterAPIs(apis, queryParams) local basePath = queryParams['filter[where][basePath]'] basePath = basePath == nil and queryParams['basePath'] or basePath local name = queryParams['filter[where][name]'] name = name == nil and queryParams['title'] or name -- missing or invalid query parameters if (basePath == nil and name == nil) then return nil end -- filter tenants local apiList = {} for k, v in pairs(apis) do if k%2 == 0 then local api = cjson.decode(v) if (basePath ~= nil and name == nil and api.basePath == basePath) or (name ~= nil and basePath == nil and api.name == name) or (basePath ~= nil and name ~= nil and api.basePath == basePath and api.name == name) then apiList[#apiList+1] = api end end end return apiList end --- Get all APIs in redis -- @param ds dataStore.client -- @param queryParams object containing optional query parameters function _M.getAllAPIs(dataStore, queryParams) local apis = dataStore:getAllAPIs() local apiList if next(queryParams) ~= nil then apiList = filterAPIs(apis, queryParams); end if apiList == nil then apiList = {} for k, v in pairs(apis) do if k%2 == 0 then apiList[#apiList+1] = cjson.decode(v) end end end return apiList end --- Get API by its id -- @param ds dataStore.client -- @param id of API function _M.getAPI(dataStore, id) local api = dataStore:getAPI(id) if api == nil then request.err(404, utils.concatStrings({"Unknown api id ", id})) end return api end --- Get belongsTo relation tenant -- @param ds dataStore.client -- @param id id of API function _M.getAPITenant(dataStore, id) local api = dataStore:getAPI(id) if api == nil then request.err(404, utils.concatStrings({"Unknown api id ", id})) end local tenantId = api.tenantId local tenant = dataStore:getTenant(tenantId) if tenant == nil then request.err(404, utils.concatStrings({"Unknown tenant id ", tenantId})) end return tenant end --- Add API to redis -- @param ds dataStore.client -- @param decoded JSON body as a lua table -- @param existingAPI optional existing API for updates function _M.addAPI(dataStore, decoded, existingAPI) -- 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({GATEWAY_URL, "/api/", decoded.tenantId}) if basePath:sub(1,1) ~= '' then managedUrl = utils.concatStrings({managedUrl, "/", basePath}) end local tenantObj = dataStore:getTenant(decoded.tenantId) local managedUrlObj = { id = uuid, name = decoded.name, basePath = utils.concatStrings({"/", basePath}), tenantId = decoded.tenantId, tenantNamespace = tenantObj.namespace, tenantInstance = tenantObj.instance, resources = decoded.resources, managedUrl = managedUrl } -- Add API object to redis managedUrlObj = dataStore:addAPI(uuid, managedUrlObj, existingAPI) -- Add resources to redis for path, resource in pairs(decoded.resources) do local gatewayPath = utils.concatStrings({basePath, path}) gatewayPath = (gatewayPath:sub(1,1) == '/') and gatewayPath:sub(2) or gatewayPath resource.apiId = uuid print('creating resource: ' .. cjson.encode(resource) .. 'path: ' .. gatewayPath .. 'tenantobj' .. cjson.encode(tenantObj)) resources.addResource(dataStore, resource, gatewayPath, tenantObj) end return managedUrlObj end --- Delete API from gateway -- @param ds dataStore.client -- @param id id of API to delete function _M.deleteAPI(dataStore, id) local api = dataStore:getAPI(id) if api == nil then request.err(404, utils.concatStrings({"Unknown API id ", id})) end -- Delete API dataStore:deleteAPI(id) -- Delete all resources for the API local basePath = api.basePath:sub(2) for path in pairs(api.resources) do local gatewayPath = utils.concatStrings({basePath, path}) gatewayPath = (gatewayPath:sub(1,1) == '/') and gatewayPath:sub(2) or gatewayPath resources.deleteResource(dataStore, gatewayPath, api.tenantId) end return {} end return _M