Skip to content

Commit

Permalink
fix: grpc-transcode request support object array (apache#7231)
Browse files Browse the repository at this point in the history
Co-authored-by: jon.yu <jon.yu@ambergroup.io>
  • Loading branch information
2 people authored and Liu-Junlin committed Nov 4, 2022
1 parent c50c293 commit ae34887
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 69 deletions.
16 changes: 16 additions & 0 deletions apisix/plugins/grpc-transcode/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ function _M.map_message(field, default_values, request_table)
if ty ~= "enum" and field_type:sub(1, 1) == "." then
if request_table[name] == nil then
sub = default_values and default_values[name]
elseif core.table.isarray(request_table[name]) then
local sub_array = core.table.new(#request_table[name], 0)
for i, value in ipairs(request_table[name]) do
local sub_array_obj
if type(value) == "table" then
sub_array_obj, err = _M.map_message(field_type,
default_values and default_values[name], value)
if err then
return nil, err
end
else
sub_array_obj = value
end
sub_array[i] = sub_array_obj
end
sub = sub_array
else
sub, err = _M.map_message(field_type, default_values and default_values[name],
request_table[name])
Expand Down
25 changes: 25 additions & 0 deletions t/grpc_server_example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,31 @@ func (s *server) SayHelloBidirectionalStream(stream pb.Greeter_SayHelloBidirecti
}
}

// SayMultipleHello implements helloworld.GreeterServer
func (s *server) SayMultipleHello(ctx context.Context, in *pb.MultipleHelloRequest) (*pb.MultipleHelloReply, error) {
log.Printf("Received: %v", in.Name)
log.Printf("Enum Gender: %v", in.GetGenders())
msg := "Hello " + in.Name

persons := in.GetPersons()
if persons != nil {
for _, person := range persons {
if person.GetName() != "" {
msg += fmt.Sprintf(", name: %v", person.GetName())
}
if person.GetAge() != 0 {
msg += fmt.Sprintf(", age: %v", person.GetAge())
}
}
}

return &pb.MultipleHelloReply{
Message: msg,
Items: in.GetItems(),
Genders: in.GetGenders(),
}, nil
}

func (s *server) Run(ctx context.Context, in *pb.Request) (*pb.Response, error) {
return &pb.Response{Body: in.User.Name + " " + in.Body}, nil
}
Expand Down
321 changes: 256 additions & 65 deletions t/grpc_server_example/proto/helloworld.pb.go

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions t/grpc_server_example/proto/helloworld.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc Plus (PlusRequest) returns (PlusReply) {}
rpc SayHelloAfterDelay (HelloRequest) returns (HelloReply) {}
rpc SayMultipleHello(MultipleHelloRequest) returns (MultipleHelloReply) {}

// Server side streaming.
rpc SayHelloServerStream (HelloRequest) returns (stream HelloReply) {}
Expand All @@ -34,6 +35,7 @@ service Greeter {

// Bidirectional streaming.
rpc SayHelloBidirectionalStream (stream HelloRequest) returns (stream HelloReply) {}

}

enum Gender {
Expand Down Expand Up @@ -68,3 +70,16 @@ message PlusRequest {
message PlusReply {
int64 result = 1;
}

message MultipleHelloRequest {
string name = 1;
repeated string items = 2;
repeated Gender genders = 3;
repeated Person persons = 4;
}

message MultipleHelloReply{
string message = 1;
repeated string items = 2;
repeated Gender genders = 3;
}
40 changes: 40 additions & 0 deletions t/grpc_server_example/proto/helloworld_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions t/grpc_server_example/proto/import.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions t/grpc_server_example/proto/src.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions t/grpc_server_example/proto/src_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

124 changes: 124 additions & 0 deletions t/plugin/grpc-transcode3.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use t::APISIX 'no_plan';

no_long_string();
no_shuffle();
no_root_location();

add_block_preprocessor(sub {
my ($block) = @_;

if (!$block->request) {
$block->set_value("request", "GET /t");
}

if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
$block->set_value("no_error_log", "[error]");
}
});

run_tests;

__DATA__
=== TEST 1: set rule
--- 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 SayMultipleHello(MultipleHelloRequest) returns (MultipleHelloReply) {}
}
enum Gender {
GENDER_UNKNOWN = 0;
GENDER_MALE = 1;
GENDER_FEMALE = 2;
}
message Person {
string name = 1;
int32 age = 2;
}
message MultipleHelloRequest {
string name = 1;
repeated string items = 2;
repeated Gender genders = 3;
repeated Person persons = 4;
}
message MultipleHelloReply{
string message = 1;
}"
}]]
)
if code >= 300 then
ngx.say(body)
return
end
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"methods": ["POST"],
"uri": "/grpctest",
"plugins": {
"grpc-transcode": {
"proto_id": "1",
"service": "helloworld.Greeter",
"method": "SayMultipleHello"
}
},
"upstream": {
"scheme": "grpc",
"type": "roundrobin",
"nodes": {
"127.0.0.1:50051": 1
}
}
}]]
)
if code >= 300 then
ngx.say(body)
return
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 2: hit route
--- request
POST /grpctest
{"name":"world","persons":[{"name":"Joe","age":1},{"name":"Jake","age":2}]}
--- more_headers
Content-Type: application/json
--- response_body chomp
{"message":"Hello world, name: Joe, age: 1, name: Jake, age: 2"}

0 comments on commit ae34887

Please sign in to comment.