This is an automated email from the ASF dual-hosted git repository.

shuyangw 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 9db2dd2  fix(grpc-transcode): handle enum type (#4706)
9db2dd2 is described below

commit 9db2dd2399c3970df1e1b7fa0f8b7dcd92d26b1c
Author: 罗泽轩 <spacewander...@gmail.com>
AuthorDate: Sun Aug 1 04:27:11 2021 +0800

    fix(grpc-transcode): handle enum type (#4706)
    
    Signed-off-by: spacewander <spacewander...@gmail.com>
---
 apisix/plugins/grpc-transcode.lua         |   6 +-
 apisix/plugins/grpc-transcode/request.lua |   9 +-
 apisix/plugins/grpc-transcode/util.lua    |   3 +-
 ci/common.sh                              |   2 +-
 t/plugin/grpc-transcode.t                 | 154 ++++++++++++++++++++++++++++++
 5 files changed, 165 insertions(+), 9 deletions(-)

diff --git a/apisix/plugins/grpc-transcode.lua 
b/apisix/plugins/grpc-transcode.lua
index 98dd3f9..b9ed7ab 100644
--- a/apisix/plugins/grpc-transcode.lua
+++ b/apisix/plugins/grpc-transcode.lua
@@ -120,11 +120,11 @@ function _M.access(conf, ctx)
         return
     end
 
-    local ok, err = request(proto_obj, conf.service,
-                            conf.method, conf.pb_option, conf.deadline)
+    local ok, err, err_code = request(proto_obj, conf.service,
+                                      conf.method, conf.pb_option, 
conf.deadline)
     if not ok then
         core.log.error("transform request error: ", err)
-        return
+        return err_code
     end
 
     ctx.proto_obj = proto_obj
diff --git a/apisix/plugins/grpc-transcode/request.lua 
b/apisix/plugins/grpc-transcode/request.lua
index 0775321..3af710e 100644
--- a/apisix/plugins/grpc-transcode/request.lua
+++ b/apisix/plugins/grpc-transcode/request.lua
@@ -23,6 +23,7 @@ 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
 
@@ -31,7 +32,7 @@ return function (proto, service, method, pb_option, deadline, 
default_values)
     local m = util.find_method(proto, service, method)
     if not m then
         return false, "Undefined service method: " .. service .. "/" .. method
-                      .. " end"
+                      .. " end", 503
     end
 
     req_read_body()
@@ -43,10 +44,10 @@ return function (proto, service, method, pb_option, 
deadline, default_values)
     end
 
     local map_message = util.map_message(m.input_type, default_values or {})
-    local encoded = pb.encode(m.input_type, map_message)
+    local ok, encoded = pcall(pb.encode, m.input_type, map_message)
 
-    if not encoded then
-        return false, "failed to encode request data to protobuf"
+    if not ok or not encoded then
+        return false, "failed to encode request data to protobuf", 400
     end
 
     local size = #encoded
diff --git a/apisix/plugins/grpc-transcode/util.lua 
b/apisix/plugins/grpc-transcode/util.lua
index da76426..faffecc 100644
--- a/apisix/plugins/grpc-transcode/util.lua
+++ b/apisix/plugins/grpc-transcode/util.lua
@@ -100,7 +100,8 @@ function _M.map_message(field, default_values)
     local sub, err
     local request_table = get_request_table()
     for name, _, field_type in pb.fields(field) do
-        if field_type:sub(1, 1) == "." then
+        local _, _, ty = pb.type(field_type)
+        if ty ~= "enum" and field_type:sub(1, 1) == "." then
             sub, err = _M.map_message(field_type, default_values)
             if err then
                 return nil, err
diff --git a/ci/common.sh b/ci/common.sh
index a6b7814..56f2d33 100644
--- a/ci/common.sh
+++ b/ci/common.sh
@@ -31,4 +31,4 @@ create_lua_deps() {
     # luarocks install luacov-coveralls --tree=deps --local > build.log 2>&1 
|| (cat build.log && exit 1)
 }
 
-GRPC_SERVER_EXAMPLE_VER=20210417
+GRPC_SERVER_EXAMPLE_VER=20210730
diff --git a/t/plugin/grpc-transcode.t b/t/plugin/grpc-transcode.t
index c87ba56..78baac0 100644
--- a/t/plugin/grpc-transcode.t
+++ b/t/plugin/grpc-transcode.t
@@ -661,3 +661,157 @@ passed
 GET /t
 --- no_error_log
 [error]
+
+
+
+=== TEST 23: set proto with enum
+--- config
+    location /t {
+        content_by_lua_block {
+            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 SayHello (HelloRequest) returns (HelloReply) {}
+                      }
+                      enum Gender {
+                        GENDER_UNKNOWN = 0;
+                        GENDER_MALE = 1;
+                        GENDER_FEMALE = 2;
+                      }
+                      message HelloRequest {
+                          string name = 1;
+                          repeated string items = 2;
+                          Gender gender = 3;
+                      }
+                      message HelloReply {
+                          string message = 1;
+                          repeated string items = 2;
+                          Gender gender = 3;
+                      }"
+                   }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 24: hit route, no gender
+--- request
+POST /grpctest
+{"name":"world"}
+--- more_headers
+Content-Type: application/json
+--- response_body eval
+qr/"gender":"GENDER_UNKNOWN"/
+--- no_error_log
+[error]
+
+
+
+=== TEST 25: hit route, gender is a value
+--- request
+POST /grpctest
+{"name":"world","gender":2}
+--- more_headers
+Content-Type: application/json
+--- response_body eval
+qr/"gender":"GENDER_FEMALE"/
+--- no_error_log
+[error]
+
+
+
+=== TEST 26: hit route, gender is a name
+--- request
+POST /grpctest
+{"name":"world","gender":"GENDER_MALE"}
+--- more_headers
+Content-Type: application/json
+--- response_body eval
+qr/"gender":"GENDER_MALE"/
+--- no_error_log
+[error]
+
+
+
+=== TEST 27: hit route, bad gender
+--- request
+POST /grpctest
+{"name":"world","gender":"GENDER_MA"}
+--- more_headers
+Content-Type: application/json
+--- error_code: 400
+--- error_log
+failed to encode request data to protobuf
+
+
+
+=== TEST 28: set routes(decode enum as value)
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "methods": ["GET", "POST"],
+                    "uri": "/grpctest",
+                    "service_protocol": "grpc",
+                    "plugins": {
+                        "grpc-transcode": {
+                            "proto_id": "1",
+                            "service": "helloworld.Greeter",
+                            "method": "SayHello",
+                            "pb_option":["enum_as_value"]
+                        }
+                    },
+                    "upstream": {
+                        "scheme": "grpc",
+                        "type": "roundrobin",
+                        "nodes": {
+                            "127.0.0.1:50051": 1
+                        }
+                    }
+                }]]
+            )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 29: hit route
+--- request
+POST /grpctest
+{"name":"world","gender":2}
+--- more_headers
+Content-Type: application/json
+--- response_body eval
+qr/"gender":2/
+--- no_error_log
+[error]

Reply via email to