Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(grpc-transcode): handle enum type #4706

Merged
merged 1 commit into from
Jul 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]