@@ -59,6 +59,10 @@ local expr_lrucache = core.lrucache.new({
5959local meta_pre_func_load_lrucache = core .lrucache .new ({
6060 ttl = 300 , count = 512
6161})
62+ local merge_global_rule_lrucache = core .lrucache .new ({
63+ ttl = 300 , count = 512
64+ })
65+
6266local local_conf
6367local check_plugin_metadata
6468
@@ -1263,7 +1267,45 @@ function _M.set_plugins_meta_parent(plugins, parent)
12631267end
12641268
12651269
1266- function _M .run_global_rules (api_ctx , global_rules , phase_name )
1270+ local function merge_global_rules (global_rules , conf_version )
1271+ -- First pass: identify duplicate plugins across all global rules
1272+ local plugins_hash = {}
1273+ local seen_plugin = {}
1274+ local values = global_rules
1275+ for _ , global_rule in config_util .iterate_values (values ) do
1276+ if global_rule .value and global_rule .value .plugins then
1277+ for plugin_name , plugin_conf in pairs (global_rule .value .plugins ) do
1278+ if seen_plugin [plugin_name ] then
1279+ core .log .error (" Found " , plugin_name ,
1280+ " configured across different global rules." ,
1281+ " Removing it from execution list" )
1282+ plugins_hash [plugin_name ] = nil
1283+ else
1284+ plugins_hash [plugin_name ] = plugin_conf
1285+ seen_plugin [plugin_name ] = true
1286+ end
1287+ end
1288+ end
1289+ end
1290+
1291+ local dummy_global_rule = {
1292+ key = " /apisix/global_rules/dummy" ,
1293+ value = {
1294+ updated_time = ngx .time (),
1295+ plugins = plugins_hash ,
1296+ created_time = ngx .time (),
1297+ id = 1 ,
1298+ },
1299+ createdIndex = conf_version ,
1300+ modifiedIndex = conf_version ,
1301+ clean_handlers = {},
1302+ }
1303+
1304+ return dummy_global_rule
1305+ end
1306+
1307+
1308+ function _M .run_global_rules (api_ctx , global_rules , conf_version , phase_name )
12671309 if global_rules and # global_rules > 0 then
12681310 local orig_conf_type = api_ctx .conf_type
12691311 local orig_conf_version = api_ctx .conf_version
@@ -1273,22 +1315,26 @@ function _M.run_global_rules(api_ctx, global_rules, phase_name)
12731315 api_ctx .global_rules = global_rules
12741316 end
12751317
1318+ local dummy_global_rule = merge_global_rule_lrucache (conf_version ,
1319+ global_rules ,
1320+ merge_global_rules ,
1321+ global_rules ,
1322+ conf_version )
1323+
12761324 local plugins = core .tablepool .fetch (" plugins" , 32 , 0 )
1277- local values = global_rules
12781325 local route = api_ctx .matched_route
1279- for _ , global_rule in config_util .iterate_values (values ) do
1280- api_ctx .conf_type = " global_rule"
1281- api_ctx .conf_version = global_rule .modifiedIndex
1282- api_ctx .conf_id = global_rule .value .id
1283-
1284- core .table .clear (plugins )
1285- plugins = _M .filter (api_ctx , global_rule , plugins , route )
1286- if phase_name == nil then
1287- _M .run_plugin (" rewrite" , plugins , api_ctx )
1288- _M .run_plugin (" access" , plugins , api_ctx )
1289- else
1290- _M .run_plugin (phase_name , plugins , api_ctx )
1291- end
1326+ api_ctx .conf_type = " global_rule"
1327+ api_ctx .conf_version = dummy_global_rule .modifiedIndex
1328+ api_ctx .conf_id = dummy_global_rule .value .id
1329+
1330+ core .table .clear (plugins )
1331+ plugins = _M .filter (api_ctx , dummy_global_rule , plugins , route )
1332+
1333+ if phase_name == nil then
1334+ _M .run_plugin (" rewrite" , plugins , api_ctx )
1335+ _M .run_plugin (" access" , plugins , api_ctx )
1336+ else
1337+ _M .run_plugin (phase_name , plugins , api_ctx )
12921338 end
12931339 core .tablepool .release (" plugins" , plugins )
12941340
0 commit comments