Skip to content

Commit

Permalink
fix(grpc-transcode): handle enum type
Browse files Browse the repository at this point in the history
Signed-off-by: spacewander <spacewanderlzx@gmail.com>
  • Loading branch information
spacewander committed Jul 30, 2021
1 parent 273b8b3 commit 4720279
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 9 deletions.
6 changes: 3 additions & 3 deletions apisix/plugins/grpc-transcode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions apisix/plugins/grpc-transcode/request.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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()
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion apisix/plugins/grpc-transcode/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion ci/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
154 changes: 154 additions & 0 deletions t/plugin/grpc-transcode.t
Original file line number Diff line number Diff line change
Expand Up @@ -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]

0 comments on commit 4720279

Please sign in to comment.