From 1b247c8e1ebd324efe66abbe33d5647a93f0426e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Tue, 3 Aug 2021 12:20:44 +0800 Subject: [PATCH] feat(ext-plugin): send the idempotent key when preparing conf (#4736) --- apisix/core/lrucache.lua | 18 +++++- apisix/plugins/ext-plugin/init.lua | 9 ++- rockspec/apisix-master-0.rockspec | 2 +- t/lib/ext-plugin.lua | 7 +++ t/plugin/ext-plugin/sanity.t | 96 +++++++++++++++++++++++++++++- 5 files changed, 125 insertions(+), 7 deletions(-) diff --git a/apisix/core/lrucache.lua b/apisix/core/lrucache.lua index c2eb8fca..9bc5c6fc 100644 --- a/apisix/core/lrucache.lua +++ b/apisix/core/lrucache.lua @@ -139,15 +139,16 @@ end global_lru_fun = new_lru_fun() -local plugin_ctx +local plugin_ctx, plugin_ctx_id do local key_buf = { nil, nil, nil, + nil, } - function plugin_ctx(lrucache, api_ctx, extra_key, create_obj_func, ...) + local function plugin_ctx_key_and_ver(api_ctx, extra_key) key_buf[1] = api_ctx.conf_type key_buf[2] = api_ctx.conf_id @@ -159,7 +160,17 @@ do key = concat(key_buf, "#", 1, 2) end - return lrucache(key, api_ctx.conf_version, create_obj_func, ...) + return key, api_ctx.conf_version + end + + function plugin_ctx(lrucache, api_ctx, extra_key, create_obj_func, ...) + local key, ver = plugin_ctx_key_and_ver(api_ctx, extra_key) + return lrucache(key, ver, create_obj_func, ...) + end + + function plugin_ctx_id(api_ctx, extra_key) + local key, ver = plugin_ctx_key_and_ver(api_ctx, extra_key) + return key .. "#" .. ver end end @@ -169,6 +180,7 @@ local _M = { new = new_lru_fun, global = global_lru_fun, plugin_ctx = plugin_ctx, + plugin_ctx_id = plugin_ctx_id, } diff --git a/apisix/plugins/ext-plugin/init.lua b/apisix/plugins/ext-plugin/init.lua index e80006ad..d4392a43 100644 --- a/apisix/plugins/ext-plugin/init.lua +++ b/apisix/plugins/ext-plugin/init.lua @@ -254,9 +254,11 @@ end local rpc_call local rpc_handlers = { nil, - function (conf, ctx, sock) + function (conf, ctx, sock, unique_key) builder:Clear() + local key = builder:CreateString(unique_key) + local conf_vec if conf.conf then local len = #conf.conf @@ -278,6 +280,7 @@ local rpc_handlers = { end prepare_conf_req.Start(builder) + prepare_conf_req.AddKey(builder, key) if conf_vec then prepare_conf_req.AddConf(builder, conf_vec) end @@ -306,8 +309,10 @@ local rpc_handlers = { return token end, function (conf, ctx, sock, entry) + local lrucache_id = core.lrucache.plugin_ctx_id(ctx, entry) local token, err = core.lrucache.plugin_ctx(lrucache, ctx, entry, rpc_call, - constants.RPC_PREPARE_CONF, conf, ctx) + constants.RPC_PREPARE_CONF, conf, ctx, + lrucache_id) if not token then return nil, err end diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index 8e416e7a..4658f83d 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -66,7 +66,7 @@ dependencies = { "luasec = 0.9-1", "lua-resty-consul = 0.3-2", "penlight = 1.9.2-1", - "ext-plugin-proto = 0.1.1", + "ext-plugin-proto = 0.2.1", } build = { diff --git a/t/lib/ext-plugin.lua b/t/lib/ext-plugin.lua index ee2f997f..38f379f1 100644 --- a/t/lib/ext-plugin.lua +++ b/t/lib/ext-plugin.lua @@ -75,6 +75,13 @@ function _M.go(case) assert(pc:ConfLength() == 0) end + if case.expect_key_pattern then + local m = ngx.re.find(pc:Key(), case.expect_key_pattern, "jo") + assert(m ~= nil, pc:Key()) + else + assert(pc:Key() ~= "") + end + prepare_conf_resp.Start(builder) prepare_conf_resp.AddConfToken(builder, 233) local req = prepare_conf_req.End(builder) diff --git a/t/plugin/ext-plugin/sanity.t b/t/plugin/ext-plugin/sanity.t index 7e33b53a..75b01f98 100644 --- a/t/plugin/ext-plugin/sanity.t +++ b/t/plugin/ext-plugin/sanity.t @@ -328,7 +328,7 @@ hello world content_by_lua_block { local ext = require("lib.ext-plugin") - ext.go({with_conf = true}) + ext.go({with_conf = true, expect_key_pattern = [[^route#1#ext-plugin-pre-req#]]}) } } --- error_log eval @@ -475,3 +475,97 @@ MY_ENV_VAR foo location /t { return 200; } + + + +=== TEST 16: prepare conf with global rule +--- config + location /t { + content_by_lua_block { + local json = require("toolkit.json") + local t = require("lib.test_admin") + + local code, message, res = t.test('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/hello", + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + } + }]] + ) + + if code >= 300 then + ngx.say(message) + return + end + + local code, message, res = t.test('/apisix/admin/global_rules/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "ext-plugin-post-req": { + "conf": [ + {"name":"foo", "value":"bar"}, + {"name":"cat", "value":"dog"} + ] + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(message) + return + end + + ngx.say(message) + } + } +--- response_body +passed + + + +=== TEST 17: hit +--- request +GET /hello +--- response_body +hello world +--- extra_stream_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock; + + content_by_lua_block { + local ext = require("lib.ext-plugin") + ext.go({with_conf = true, expect_key_pattern = [[^global_rule#1#ext-plugin-post-req#]]}) + } + } +--- error_log eval +qr/get conf token: 233 conf: \[(\{"value":"bar","name":"foo"\}|\{"name":"foo","value":"bar"\}),(\{"value":"dog","name":"cat"\}|\{"name":"cat","value":"dog"\})\]/ +--- no_error_log +[error] + + + +=== TEST 18: clean global rule +--- config + location /t { + content_by_lua_block { + local json = require("toolkit.json") + local t = require("lib.test_admin") + + local code, message, res = t.test('/apisix/admin/global_rules/1', + ngx.HTTP_DELETE) + + if code >= 300 then + ngx.status = code + ngx.say(message) + return + end + } + }