This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new d97860530 fix(grpc-transcode): pb_option should be set on the route
(#7116)
d97860530 is described below
commit d978605302308e6a02acbb0a64d18b59df422b75
Author: 罗泽轩 <[email protected]>
AuthorDate: Wed May 25 12:45:41 2022 +0800
fix(grpc-transcode): pb_option should be set on the route (#7116)
Signed-off-by: spacewander <[email protected]>
---
apisix/plugins/grpc-transcode.lua | 6 +
apisix/plugins/grpc-transcode/request.lua | 7 +-
apisix/plugins/grpc-transcode/response.lua | 7 +-
apisix/plugins/grpc-transcode/util.lua | 37 +++++
t/plugin/grpc-transcode2.t | 233 +++++++++++++++++++++++++++++
5 files changed, 278 insertions(+), 12 deletions(-)
diff --git a/apisix/plugins/grpc-transcode.lua
b/apisix/plugins/grpc-transcode.lua
index 2f396df36..7da62a805 100644
--- a/apisix/plugins/grpc-transcode.lua
+++ b/apisix/plugins/grpc-transcode.lua
@@ -65,6 +65,12 @@ local schema = {
type = "array",
items = { type="string", anyOf = pb_option_def },
minItems = 1,
+ default = {
+ "enum_as_name",
+ "int64_as_number",
+ "auto_default_values",
+ "disable_hooks",
+ }
},
},
additionalProperties = true,
diff --git a/apisix/plugins/grpc-transcode/request.lua
b/apisix/plugins/grpc-transcode/request.lua
index 3af710e28..88d2fcfb9 100644
--- a/apisix/plugins/grpc-transcode/request.lua
+++ b/apisix/plugins/grpc-transcode/request.lua
@@ -22,7 +22,6 @@ local bit = require("bit")
local ngx = ngx
local string = string
local table = table
-local ipairs = ipairs
local pcall = pcall
local tonumber = tonumber
local req_read_body = ngx.req.read_body
@@ -37,11 +36,7 @@ return function (proto, service, method, pb_option,
deadline, default_values)
req_read_body()
- if pb_option then
- for _, opt in ipairs(pb_option) do
- pb.option(opt)
- end
- end
+ util.set_options(proto, pb_option)
local map_message = util.map_message(m.input_type, default_values or {})
local ok, encoded = pcall(pb.encode, m.input_type, map_message)
diff --git a/apisix/plugins/grpc-transcode/response.lua
b/apisix/plugins/grpc-transcode/response.lua
index f5ca7e2b4..ca39a3ccf 100644
--- a/apisix/plugins/grpc-transcode/response.lua
+++ b/apisix/plugins/grpc-transcode/response.lua
@@ -19,7 +19,6 @@ local core = require("apisix.core")
local pb = require("pb")
local ngx = ngx
local string = string
-local ipairs = ipairs
return function(ctx, proto, service, method, pb_option)
local buffer = core.response.hold_body_chunk(ctx)
@@ -43,11 +42,7 @@ return function(ctx, proto, service, method, pb_option)
buffer = string.sub(buffer, 6)
end
- if pb_option then
- for _, opt in ipairs(pb_option) do
- pb.option(opt)
- end
- end
+ util.set_options(proto, pb_option)
local decoded = pb.decode(m.output_type, buffer)
if not decoded then
diff --git a/apisix/plugins/grpc-transcode/util.lua
b/apisix/plugins/grpc-transcode/util.lua
index 2a7bfb648..de54cdb87 100644
--- a/apisix/plugins/grpc-transcode/util.lua
+++ b/apisix/plugins/grpc-transcode/util.lua
@@ -20,6 +20,8 @@ local json = core.json
local pb = require("pb")
local ngx = ngx
local string = string
+local table = table
+local ipairs = ipairs
local tonumber = tonumber
local type = type
@@ -51,6 +53,41 @@ function _M.find_method(proto, service, method)
end
+function _M.set_options(proto, options)
+ local cur_opts = proto.options
+ if cur_opts then
+ if cur_opts == options then
+ -- same route
+ return
+ end
+
+ local same = true
+ table.sort(options)
+ for i, v in ipairs(options) do
+ if cur_opts[i] ~= v then
+ same = false
+ break
+ end
+ end
+
+ if same then
+ -- Routes have the same configuration, usually the default one.
+ -- As this is a small optimization, we don't care about routes
have different
+ -- configuration but have the same effect eventually.
+ return
+ end
+ else
+ table.sort(options)
+ end
+
+ for _, opt in ipairs(options) do
+ pb.option(opt)
+ end
+
+ proto.options = options
+end
+
+
local function get_request_table()
local method = ngx.req.get_method()
local content_type = ngx.req.get_headers()["Content-Type"] or ""
diff --git a/t/plugin/grpc-transcode2.t b/t/plugin/grpc-transcode2.t
index 91be88408..e9c6c0396 100644
--- a/t/plugin/grpc-transcode2.t
+++ b/t/plugin/grpc-transcode2.t
@@ -567,3 +567,236 @@ GET /grpc_plus?a=1&b=2
qr/\{"result":3\}/
--- error_log eval
qr/request log: \{.*body":\"\{\\"result\\":3}/
+
+
+
+=== TEST 17: pb_option should be be set on the route level
+--- extra_init_by_lua
+ local pb = require("pb")
+ local old_f = pb.option
+ pb.option = function(o)
+ ngx.log(ngx.WARN, "set protobuf option: ", o)
+ return old_f(o)
+ end
+--- config
+ location /t {
+ content_by_lua_block {
+ local http = require "resty.http"
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/proto/1',
+ ngx.HTTP_PUT,
+ [[{
+ "content" : "syntax = \"proto3\";
+ package helloworld;
+ service Greeter {
+ rpc Plus (PlusRequest) returns (PlusReply) {}
+ }
+
+ message PlusRequest {
+ int64 a = 1;
+ int64 b = 2;
+ }
+ message PlusReply {
+ int64 result = 1;
+ }"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.say(body)
+ return
+ end
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "methods": ["GET"],
+ "uri": "/grpc_plus2",
+ "plugins": {
+ "grpc-transcode": {
+ "proto_id": "1",
+ "service": "helloworld.Greeter",
+ "method": "Plus"
+ }
+ },
+ "upstream": {
+ "scheme": "grpc",
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:50051": 1
+ }
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.say(body)
+ return
+ end
+
+ local code, body = t('/apisix/admin/routes/2',
+ ngx.HTTP_PUT,
+ [[{
+ "methods": ["GET"],
+ "uri": "/grpc_plus",
+ "plugins": {
+ "grpc-transcode": {
+ "proto_id": "1",
+ "service": "helloworld.Greeter",
+ "method": "Plus",
+ "pb_option":["int64_as_string", "enum_as_name"]
+ }
+ },
+ "upstream": {
+ "scheme": "grpc",
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:50051": 1
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.say(body)
+ return
+ end
+
+ for i = 1, 3 do
+ local uri = "http://127.0.0.1:" .. ngx.var.server_port ..
+ (i == 2 and "/grpc_plus2" or "/grpc_plus") ..
+ "?a=1&b=2251799813685260"
+ local httpc = http.new()
+ local res = assert(httpc:request_uri(uri, {keepalive = false}))
+ ngx.say(res.body)
+ end
+ }
+ }
+--- response_body
+{"result":"#2251799813685261"}
+{"result":2.2517998136853e+15}
+{"result":"#2251799813685261"}
+--- grep_error_log eval
+qr/set protobuf option: \w+/
+--- grep_error_log_out
+set protobuf option: enum_as_name
+set protobuf option: int64_as_string
+set protobuf option: auto_default_values
+set protobuf option: disable_hooks
+set protobuf option: enum_as_name
+set protobuf option: int64_as_number
+set protobuf option: enum_as_name
+set protobuf option: int64_as_string
+
+
+
+=== TEST 18: pb_option should be be set on the route level, two route have the
same options
+--- extra_init_by_lua
+ local pb = require("pb")
+ local old_f = pb.option
+ pb.option = function(o)
+ ngx.log(ngx.WARN, "set protobuf option: ", o)
+ return old_f(o)
+ end
+--- config
+ location /t {
+ content_by_lua_block {
+ local http = require "resty.http"
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/proto/1',
+ ngx.HTTP_PUT,
+ [[{
+ "content" : "syntax = \"proto3\";
+ package helloworld;
+ service Greeter {
+ rpc Plus (PlusRequest) returns (PlusReply) {}
+ }
+
+ message PlusRequest {
+ int64 a = 1;
+ int64 b = 2;
+ }
+ message PlusReply {
+ int64 result = 1;
+ }"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.say(body)
+ return
+ end
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "methods": ["GET"],
+ "uri": "/grpc_plus2",
+ "plugins": {
+ "grpc-transcode": {
+ "proto_id": "1",
+ "service": "helloworld.Greeter",
+ "method": "Plus"
+ }
+ },
+ "upstream": {
+ "scheme": "grpc",
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:50051": 1
+ }
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.say(body)
+ return
+ end
+
+ local code, body = t('/apisix/admin/routes/2',
+ ngx.HTTP_PUT,
+ [[{
+ "methods": ["GET"],
+ "uri": "/grpc_plus",
+ "plugins": {
+ "grpc-transcode": {
+ "proto_id": "1",
+ "service": "helloworld.Greeter",
+ "method": "Plus"
+ }
+ },
+ "upstream": {
+ "scheme": "grpc",
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:50051": 1
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.say(body)
+ return
+ end
+
+ for i = 1, 3 do
+ local uri = "http://127.0.0.1:" .. ngx.var.server_port ..
+ (i == 2 and "/grpc_plus2" or "/grpc_plus") ..
+ "?a=1&b=2251799813685260"
+ local httpc = http.new()
+ local res = assert(httpc:request_uri(uri, {keepalive = false}))
+ ngx.say(res.body)
+ end
+ }
+ }
+--- response_body
+{"result":2.2517998136853e+15}
+{"result":2.2517998136853e+15}
+{"result":2.2517998136853e+15}
+--- grep_error_log eval
+qr/set protobuf option: \w+/
+--- grep_error_log_out
+set protobuf option: auto_default_values
+set protobuf option: disable_hooks
+set protobuf option: enum_as_name
+set protobuf option: int64_as_number