From d4fe27c0da4f651183bb7102422b1eefeaa2169b Mon Sep 17 00:00:00 2001 From: kingluo Date: Wed, 12 Apr 2023 10:47:57 +0800 Subject: [PATCH 1/2] fix: batch-requests: read trailer headers if exist --- apisix/plugins/batch-requests.lua | 9 +- t/plugin/batch-requests-grpc.t | 205 ++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 t/plugin/batch-requests-grpc.t diff --git a/apisix/plugins/batch-requests.lua b/apisix/plugins/batch-requests.lua index 54dfba07d488..fe04ac753811 100644 --- a/apisix/plugins/batch-requests.lua +++ b/apisix/plugins/batch-requests.lua @@ -275,7 +275,14 @@ local function batch_requests(ctx) headers = resp.headers, } if resp.has_body then - sub_resp.body = resp:read_body() + local err + sub_resp.body, err = resp:read_body() + if err then + sub_resp.read_body_err = err + core.log.error("read_body: ", err) + elseif resp.read_trailers then + resp:read_trailers() + end end core.table.insert(aggregated_resp, sub_resp) end diff --git a/t/plugin/batch-requests-grpc.t b/t/plugin/batch-requests-grpc.t new file mode 100644 index 000000000000..4acd5005434c --- /dev/null +++ b/t/plugin/batch-requests-grpc.t @@ -0,0 +1,205 @@ +# +# 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'; + +repeat_each(1); +no_long_string(); +no_root_location(); + +add_block_preprocessor(sub { + my ($block) = @_; + + if (!$block->request) { + $block->set_value("request", "GET /t"); + } + + if (!$block->no_error_log && !$block->error_log) { + $block->set_value("no_error_log", "[error]\n[alert]"); + } + + my $extra_yaml_config = <<_EOC_; +plugins: + - grpc-transcode + - public-api + - batch-requests +_EOC_ + + $block->set_value("extra_yaml_config", $extra_yaml_config); +}); + +run_tests; + +__DATA__ + +=== TEST 1: pre-create public API route +--- 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, + [[{ + "plugins": { + "public-api": {} + }, + "uri": "/apisix/batch-requests" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 2: set proto(id: 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local etcd = require("apisix.core.etcd") + local code, body = t('/apisix/admin/protos/1', + ngx.HTTP_PUT, + [[{ + "content" : "syntax = \"proto3\"; + package helloworld; + service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply) {} + } + message HelloRequest { + string name = 1; + } + message HelloReply { + string message = 1; + }" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 3: set routes(id: 2) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/2', + ngx.HTTP_PUT, + [[{ + "methods": ["GET", "POST"], + "uri": "/grpctest", + "plugins": { + "grpc-transcode": { + "proto_id": "1", + "service": "helloworld.Greeter", + "method": "SayHello" + } + }, + "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 + + + +=== TEST 4: hit route +--- request +GET /grpctest?name=world +--- response_body eval +qr/\{"message":"Hello world"\}/ + + + +=== TEST 5: successful batch-requests for both grpc and http +--- config + location = /aggregate { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin").test + local code, body = t('/apisix/batch-requests', + ngx.HTTP_POST, + [=[{ + "headers": { + "Content-Type":"application/json" + }, + "pipeline":[ + { + "method":"GET", + "path":"/grpctest" + }, + { + "method":"GET", + "path":"/get" + } + ] + }]=], + [=[[ + { + "status": 200, + "body":"{\"message\":\"Hello \"}" + }, + { + "status": 200, + "body":"hello" + } + ]]=]) + + ngx.status = code + ngx.say(body) + } + } + + location = /get { + content_by_lua_block { + ngx.print("hello") + } + } +--- request +GET /aggregate +--- response_body +passed From 4df5a6bba0552e7252b29b91a6af8c47ecfd191f Mon Sep 17 00:00:00 2001 From: kingluo Date: Fri, 14 Apr 2023 11:03:05 +0800 Subject: [PATCH 2/2] fix PR --- apisix/plugins/batch-requests.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apisix/plugins/batch-requests.lua b/apisix/plugins/batch-requests.lua index fe04ac753811..a1b574307ef6 100644 --- a/apisix/plugins/batch-requests.lua +++ b/apisix/plugins/batch-requests.lua @@ -279,8 +279,8 @@ local function batch_requests(ctx) sub_resp.body, err = resp:read_body() if err then sub_resp.read_body_err = err - core.log.error("read_body: ", err) - elseif resp.read_trailers then + core.log.error("read pipeline response body failed: ", err) + else resp:read_trailers() end end