Skip to content

Commit c2324a5

Browse files
authored
feat: support _meta.pre_function to execute custom logic before execution of each phase (#11793)
1 parent 0cb7d9a commit c2324a5

File tree

5 files changed

+380
-8
lines changed

5 files changed

+380
-8
lines changed

apisix/plugin.lua

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ local type = type
3434
local local_plugins = core.table.new(32, 0)
3535
local tostring = tostring
3636
local error = error
37+
-- make linter happy to avoid error: getting the Lua global "load"
38+
-- luacheck: globals load, ignore lua_load
39+
local lua_load = load
3740
local is_http = ngx.config.subsystem == "http"
3841
local local_plugins_hash = core.table.new(0, 32)
3942
local stream_local_plugins = core.table.new(32, 0)
@@ -49,6 +52,9 @@ local merged_stream_route = core.lrucache.new({
4952
local expr_lrucache = core.lrucache.new({
5053
ttl = 300, count = 512
5154
})
55+
local meta_pre_func_load_lrucache = core.lrucache.new({
56+
ttl = 300, count = 512
57+
})
5258
local local_conf
5359
local check_plugin_metadata
5460

@@ -906,10 +912,23 @@ local function check_single_plugin_schema(name, plugin_conf, schema_type, skip_d
906912
.. name .. " err: " .. err
907913
end
908914

909-
if plugin_conf._meta and plugin_conf._meta.filter then
910-
ok, err = expr.new(plugin_conf._meta.filter)
911-
if not ok then
912-
return nil, "failed to validate the 'vars' expression: " .. err
915+
if plugin_conf._meta then
916+
if plugin_conf._meta.filter then
917+
ok, err = expr.new(plugin_conf._meta.filter)
918+
if not ok then
919+
return nil, "failed to validate the 'vars' expression: " .. err
920+
end
921+
end
922+
923+
if plugin_conf._meta.pre_function then
924+
local pre_function, err = meta_pre_func_load_lrucache(plugin_conf._meta.pre_function
925+
, "",
926+
lua_load,
927+
plugin_conf._meta.pre_function, "meta pre_function")
928+
if not pre_function then
929+
return nil, "failed to load _meta.pre_function in plugin " .. name .. ": "
930+
.. err
931+
end
913932
end
914933
end
915934
end
@@ -1130,6 +1149,17 @@ function _M.stream_plugin_checker(item, in_cp)
11301149
return true
11311150
end
11321151

1152+
local function run_meta_pre_function(conf, api_ctx, name)
1153+
if conf._meta and conf._meta.pre_function then
1154+
local _, pre_function = pcall(meta_pre_func_load_lrucache(conf._meta.pre_function, "",
1155+
lua_load,
1156+
conf._meta.pre_function, "meta pre_function"))
1157+
local ok, err = pcall(pre_function, conf, api_ctx)
1158+
if not ok then
1159+
core.log.error("pre_function execution for plugin ", name, " failed: ", err)
1160+
end
1161+
end
1162+
end
11331163

11341164
function _M.run_plugin(phase, plugins, api_ctx)
11351165
local plugin_run = false
@@ -1169,6 +1199,7 @@ function _M.run_plugin(phase, plugins, api_ctx)
11691199
goto CONTINUE
11701200
end
11711201

1202+
run_meta_pre_function(conf, api_ctx, plugins[i]["name"])
11721203
plugin_run = true
11731204
api_ctx._plugin_name = plugins[i]["name"]
11741205
local code, body = phase_func(conf, api_ctx)
@@ -1207,6 +1238,7 @@ function _M.run_plugin(phase, plugins, api_ctx)
12071238
local conf = plugins[i + 1]
12081239
if phase_func and meta_filter(api_ctx, plugins[i]["name"], conf) then
12091240
plugin_run = true
1241+
run_meta_pre_function(conf, api_ctx, plugins[i]["name"])
12101242
api_ctx._plugin_name = plugins[i]["name"]
12111243
phase_func(conf, api_ctx)
12121244
api_ctx._plugin_name = nil

apisix/plugins/example-plugin.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ function _M.access(conf, ctx)
107107
return
108108
end
109109

110+
function _M.header_filter(conf, ctx)
111+
core.log.warn("plugin header_filter phase, conf: ", core.json.encode(conf))
112+
end
113+
110114

111115
function _M.body_filter(conf, ctx)
112116
core.log.warn("plugin body_filter phase, eof: ", ngx.arg[2],
@@ -119,6 +123,10 @@ function _M.delayed_body_filter(conf, ctx)
119123
", conf: ", core.json.encode(conf))
120124
end
121125

126+
function _M.log(conf, ctx)
127+
core.log.warn("plugin log phase, conf: ", core.json.encode(conf))
128+
end
129+
122130

123131
local function hello()
124132
local args = ngx.req.get_uri_args()

apisix/schema_def.lua

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,8 +1032,15 @@ _M.plugin_injected_schema = {
10321032
description = "filter determines whether the plugin "..
10331033
"needs to be executed at runtime",
10341034
type = "array",
1035-
}
1036-
}
1035+
},
1036+
pre_function = {
1037+
description = "function to be executed in each phase " ..
1038+
"before execution of plugins. The pre_function will have access " ..
1039+
"to two arguments: `conf` and `ctx`.",
1040+
type = "string",
1041+
},
1042+
},
1043+
additionalProperties = false,
10371044
}
10381045
}
10391046

t/admin/plugins.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ plugins:
281281
}
282282
}
283283
--- response_body eval
284-
qr/\{"metadata_schema":\{"properties":\{"ikey":\{"minimum":0,"type":"number"\},"skey":\{"type":"string"\}\},"required":\["ikey","skey"\],"type":"object"\},"priority":0,"schema":\{"\$comment":"this is a mark for our injected plugin schema","properties":\{"_meta":\{"properties":\{"disable":\{"type":"boolean"\},"error_response":\{"oneOf":\[\{"type":"string"\},\{"type":"object"\}\]\},"filter":\{"description":"filter determines whether the plugin needs to be executed at runtime","type":"array"\},"priority":\{"description":"priority of plugins by customized order","type":"integer"\}\},"type":"object"\},"i":\{"minimum":0,"type":"number"\},"ip":\{"type":"string"\},"port":\{"type":"integer"\},"s":\{"type":"string"\},"t":\{"minItems":1,"type":"array"\}\},"required":\["i"\],"type":"object"\},"version":0.1\}/
284+
qr/\{"metadata_schema":\{"properties":\{"ikey":\{"minimum":0,"type":"number"\},"skey":\{"type":"string"\}\},"required":\["ikey","skey"\],"type":"object"\},"priority":0,"schema":\{"\$comment":"this is a mark for our injected plugin schema","properties":\{"_meta":\{"additionalProperties":false,"properties":\{"disable":\{"type":"boolean"\},"error_response":\{"oneOf":\[\{"type":"string"\},\{"type":"object"\}\]\},"filter":\{"description":"filter determines whether the plugin needs to be executed at runtime","type":"array"\},"pre_function":\{"description":"function to be executed in each phase before execution of plugins. The pre_function will have access to two arguments: `conf` and `ctx`.","type":"string"\},"priority":\{"description":"priority of plugins by customized order","type":"integer"\}\},"type":"object"\},"i":\{"minimum":0,"type":"number"\},"ip":\{"type":"string"\},"port":\{"type":"integer"\},"s":\{"type":"string"\},"t":\{"minItems":1,"type":"array"\}\},"required":\["i"\],"type":"object"\},"version":0.1\}/
285285
286286
287287
@@ -382,7 +382,7 @@ qr/\{"encrypt_fields":\["password"\],"properties":\{"password":\{"type":"string"
382382
}
383383
}
384384
--- response_body
385-
{"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"_meta":{"properties":{"disable":{"type":"boolean"},"error_response":{"oneOf":[{"type":"string"},{"type":"object"}]},"filter":{"description":"filter determines whether the plugin needs to be executed at runtime","type":"array"},"priority":{"description":"priority of plugins by customized order","type":"integer"}},"type":"object"},"burst":{"minimum":0,"type":"integer"},"conn":{"exclusiveMinimum":0,"type":"integer"},"default_conn_delay":{"exclusiveMinimum":0,"type":"number"},"key":{"type":"string"},"key_type":{"default":"var","enum":["var","var_combination"],"type":"string"},"only_use_default_delay":{"default":false,"type":"boolean"}},"required":["conn","burst","default_conn_delay","key"],"type":"object"},"version":0.1}
385+
{"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"_meta":{"additionalProperties":false,"properties":{"disable":{"type":"boolean"},"error_response":{"oneOf":[{"type":"string"},{"type":"object"}]},"filter":{"description":"filter determines whether the plugin needs to be executed at runtime","type":"array"},"pre_function":{"description":"function to be executed in each phase before execution of plugins. The pre_function will have access to two arguments: `conf` and `ctx`.","type":"string"},"priority":{"description":"priority of plugins by customized order","type":"integer"}},"type":"object"},"burst":{"minimum":0,"type":"integer"},"conn":{"exclusiveMinimum":0,"type":"integer"},"default_conn_delay":{"exclusiveMinimum":0,"type":"number"},"key":{"type":"string"},"key_type":{"default":"var","enum":["var","var_combination"],"type":"string"},"only_use_default_delay":{"default":false,"type":"boolean"}},"required":["conn","burst","default_conn_delay","key"],"type":"object"},"version":0.1}
386386
387387
388388

0 commit comments

Comments
 (0)