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

Reply via email to