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.
This commit is contained in:
罗泽轩 2020-10-10 23:43:00 +08:00 committed by GitHub
parent f05cba0145
commit ac38c299b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 82 deletions

76
apisix/api_router.lua Normal file
View File

@ -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

View File

@ -17,7 +17,6 @@
local require = require local require = require
local router = require("resty.radixtree") local router = require("resty.radixtree")
local core = require("apisix.core") local core = require("apisix.core")
local plugin = require("apisix.plugin")
local ipairs = ipairs local ipairs = ipairs
local type = type local type = type
local error = error local error = error
@ -113,19 +112,6 @@ local function create_radixtree_router(routes)
end end
-- create router: only_uri_router -- 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) only_uri_router = router.new(only_uri_routes)
return true return true
end end
@ -153,12 +139,7 @@ function _M.match(api_ctx)
end end
local ok = only_uri_router:dispatch(api_ctx.var.uri, match_opts, api_ctx) local ok = only_uri_router:dispatch(api_ctx.var.uri, match_opts, api_ctx)
if ok then return ok
return true
end
core.log.info("not find any matched route")
return true
end end

View File

@ -17,7 +17,6 @@
local require = require local require = require
local router = require("resty.radixtree") local router = require("resty.radixtree")
local core = require("apisix.core") local core = require("apisix.core")
local plugin = require("apisix.plugin")
local ipairs = ipairs local ipairs = ipairs
local type = type local type = type
local error = error local error = error
@ -34,19 +33,8 @@ local _M = {version = 0.2}
local function create_radixtree_router(routes) local function create_radixtree_router(routes)
routes = routes or {} routes = routes or {}
local api_routes = plugin.api_routes()
core.table.clear(uri_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 for _, route in ipairs(routes) do
if type(route) == "table" then if type(route) == "table" then
local filter_fun, err local filter_fun, err
@ -108,12 +96,7 @@ function _M.match(api_ctx)
match_opts.vars = api_ctx.var match_opts.vars = api_ctx.var
local ok = uri_router:dispatch(api_ctx.var.uri, match_opts, api_ctx) local ok = uri_router:dispatch(api_ctx.var.uri, match_opts, api_ctx)
if not ok then return ok
core.log.info("not find any matched route")
return true
end
return true
end end

View File

@ -366,17 +366,21 @@ function _M.http_access_phase()
end end
end end
router.router_http.match(api_ctx) local user_defined_route_matched = router.router_http.match(api_ctx)
if not user_defined_route_matched then
core.log.info("matched route: ", router.api.match(api_ctx)
core.json.delay_encode(api_ctx.matched_route, true)) end
local route = api_ctx.matched_route local route = api_ctx.matched_route
if not route then if not route then
core.log.info("not find any matched route")
return core.response.exit(404, return core.response.exit(404,
{error_msg = "404 Route Not Found"}) {error_msg = "404 Route Not Found"})
end end
core.log.info("matched route: ",
core.json.delay_encode(api_ctx.matched_route, true))
if route.value.service_protocol == "grpc" then if route.value.service_protocol == "grpc" then
return ngx.exec("@grpc_pass") return ngx.exec("@grpc_pass")
end end

View File

@ -197,45 +197,6 @@ function _M.load()
end 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) function _M.filter(user_route, plugins)
local user_plugin_conf = user_route.value.plugins local user_plugin_conf = user_route.value.plugins
if user_plugin_conf == nil or if user_plugin_conf == nil or

View File

@ -80,10 +80,12 @@ function _M.http_init_worker()
router_http.init_worker(filter) router_http.init_worker(filter)
_M.router_http = router_http _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() router_ssl.init_worker()
_M.router_ssl = router_ssl _M.router_ssl = router_ssl
_M.api = require("apisix.api_router")
local global_rules, err = core.config.new("/global_rules", { local global_rules, err = core.config.new("/global_rules", {
automatic = true, automatic = true,
item_schema = core.schema.global_rule item_schema = core.schema.global_rule