From ac38c299b4162c6a68a12925d2f3707effc006be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Sat, 10 Oct 2020 23:43:00 +0800 Subject: [PATCH] change: refactor router (#2367) 1. rename http/router/radixtree_sni -> ssl/router/radixtree_sni 2. extract API router out from the host/uri router so that we can hide the implementation details and reduce duplicate code. --- apisix/api_router.lua | 76 +++++++++++++++++++ apisix/http/router/radixtree_host_uri.lua | 21 +---- apisix/http/router/radixtree_uri.lua | 19 +---- apisix/init.lua | 12 ++- apisix/plugin.lua | 39 ---------- apisix/router.lua | 4 +- apisix/{http => ssl}/router/radixtree_sni.lua | 0 7 files changed, 89 insertions(+), 82 deletions(-) create mode 100644 apisix/api_router.lua rename apisix/{http => ssl}/router/radixtree_sni.lua (100%) diff --git a/apisix/api_router.lua b/apisix/api_router.lua new file mode 100644 index 00000000..b18e823a --- /dev/null +++ b/apisix/api_router.lua @@ -0,0 +1,76 @@ +-- +-- 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. +-- +local require = require +local router = require("resty.radixtree") +local plugin = require("apisix.plugin") +local core = require("apisix.core") +local ipairs = ipairs + + +local _M = {} +local match_opts = {} + + +local fetch_api_router +do + local routes = {} +function fetch_api_router() + core.table.clear(routes) + + for _, plugin in ipairs(plugin.plugins) do + local api_fun = plugin.api + if api_fun then + local api_routes = api_fun() + core.log.debug("fetched api routes: ", + core.json.delay_encode(api_routes, true)) + for _, route in ipairs(api_routes) do + core.table.insert(routes, { + methods = route.methods, + paths = route.uri, + handler = function (...) + local code, body = route.handler(...) + if code or body then + core.response.exit(code, body) + end + end + }) + end + end + end + + return router.new(routes) +end + +end -- do + + +function _M.match(api_ctx) + local api_router = core.lrucache.global("api_router", plugin.load_times, fetch_api_router) + if not api_router then + core.log.error("failed to fetch valid api router") + return false + end + + core.table.clear(match_opts) + match_opts.method = api_ctx.var.request_method + + local ok = api_router:dispatch(api_ctx.var.uri, match_opts, api_ctx) + return ok +end + + +return _M diff --git a/apisix/http/router/radixtree_host_uri.lua b/apisix/http/router/radixtree_host_uri.lua index 8b2841ce..ab3ad155 100644 --- a/apisix/http/router/radixtree_host_uri.lua +++ b/apisix/http/router/radixtree_host_uri.lua @@ -17,7 +17,6 @@ local require = require local router = require("resty.radixtree") local core = require("apisix.core") -local plugin = require("apisix.plugin") local ipairs = ipairs local type = type local error = error @@ -113,19 +112,6 @@ local function create_radixtree_router(routes) end -- create router: only_uri_router - local api_routes = plugin.api_routes() - core.log.info("api_routes", core.json.delay_encode(api_routes, true)) - - for _, route in ipairs(api_routes) do - if type(route) == "table" then - core.table.insert(only_uri_routes, { - paths = route.uris or route.uri, - handler = route.handler, - method = route.methods, - }) - end - end - only_uri_router = router.new(only_uri_routes) return true end @@ -153,12 +139,7 @@ function _M.match(api_ctx) end local ok = only_uri_router:dispatch(api_ctx.var.uri, match_opts, api_ctx) - if ok then - return true - end - - core.log.info("not find any matched route") - return true + return ok end diff --git a/apisix/http/router/radixtree_uri.lua b/apisix/http/router/radixtree_uri.lua index dfcd654e..fe6dfbd5 100644 --- a/apisix/http/router/radixtree_uri.lua +++ b/apisix/http/router/radixtree_uri.lua @@ -17,7 +17,6 @@ local require = require local router = require("resty.radixtree") local core = require("apisix.core") -local plugin = require("apisix.plugin") local ipairs = ipairs local type = type local error = error @@ -34,19 +33,8 @@ local _M = {version = 0.2} local function create_radixtree_router(routes) routes = routes or {} - local api_routes = plugin.api_routes() core.table.clear(uri_routes) - for _, route in ipairs(api_routes) do - if type(route) == "table" then - core.table.insert(uri_routes, { - paths = route.uris or route.uri, - methods = route.methods, - handler = route.handler, - }) - end - end - for _, route in ipairs(routes) do if type(route) == "table" then local filter_fun, err @@ -108,12 +96,7 @@ function _M.match(api_ctx) match_opts.vars = api_ctx.var local ok = uri_router:dispatch(api_ctx.var.uri, match_opts, api_ctx) - if not ok then - core.log.info("not find any matched route") - return true - end - - return true + return ok end diff --git a/apisix/init.lua b/apisix/init.lua index 5d773ab3..3beec459 100644 --- a/apisix/init.lua +++ b/apisix/init.lua @@ -366,17 +366,21 @@ function _M.http_access_phase() end end - router.router_http.match(api_ctx) - - core.log.info("matched route: ", - core.json.delay_encode(api_ctx.matched_route, true)) + local user_defined_route_matched = router.router_http.match(api_ctx) + if not user_defined_route_matched then + router.api.match(api_ctx) + end local route = api_ctx.matched_route if not route then + core.log.info("not find any matched route") return core.response.exit(404, {error_msg = "404 Route Not Found"}) end + core.log.info("matched route: ", + core.json.delay_encode(api_ctx.matched_route, true)) + if route.value.service_protocol == "grpc" then return ngx.exec("@grpc_pass") end diff --git a/apisix/plugin.lua b/apisix/plugin.lua index 8c498831..f992dc30 100644 --- a/apisix/plugin.lua +++ b/apisix/plugin.lua @@ -197,45 +197,6 @@ function _M.load() end -local fetch_api_routes -do - local routes = {} -function fetch_api_routes() - core.table.clear(routes) - - for _, plugin in ipairs(_M.plugins) do - local api_fun = plugin.api - if api_fun then - local api_routes = api_fun() - core.log.debug("fetched api routes: ", - core.json.delay_encode(api_routes, true)) - for _, route in ipairs(api_routes) do - core.table.insert(routes, { - methods = route.methods, - uri = route.uri, - handler = function (...) - local code, body = route.handler(...) - if code or body then - core.response.exit(code, body) - end - end - }) - end - end - end - - return routes -end - -end -- do - - -function _M.api_routes() - return core.lrucache.global("plugin_routes", _M.load_times, - fetch_api_routes) -end - - function _M.filter(user_route, plugins) local user_plugin_conf = user_route.value.plugins if user_plugin_conf == nil or diff --git a/apisix/router.lua b/apisix/router.lua index b94be0c4..87c46625 100644 --- a/apisix/router.lua +++ b/apisix/router.lua @@ -80,10 +80,12 @@ function _M.http_init_worker() router_http.init_worker(filter) _M.router_http = router_http - local router_ssl = require("apisix.http.router." .. router_ssl_name) + local router_ssl = require("apisix.ssl.router." .. router_ssl_name) router_ssl.init_worker() _M.router_ssl = router_ssl + _M.api = require("apisix.api_router") + local global_rules, err = core.config.new("/global_rules", { automatic = true, item_schema = core.schema.global_rule diff --git a/apisix/http/router/radixtree_sni.lua b/apisix/ssl/router/radixtree_sni.lua similarity index 100% rename from apisix/http/router/radixtree_sni.lua rename to apisix/ssl/router/radixtree_sni.lua