apache/apisix-java-plugin-runner

request help: I want to check in ext-plugin-post-resp plugin according to upstream response status.

Cheol-Soon-Choi opened this issue · 2 comments

Issue description

When the upstream response status is 400 or 500, the postfilter cannot check the status.

my post filter is

    @Override
    public void postFilter(PostRequest request, PostResponse response, PluginFilterChain chain) {
        log.info("--------------------post filter start------------11111111");
        log.info(request.getUpstreamHeaders().toString());
        log.info(request.getUpstreamStatusCode().toString());
        log.info(request.getBody());
        chain.postFilter(request, response);
    }

When the upstream responds with 200, the log is

--------------------post filter start------------11111111
{Keep-Alive=timeout=60, Transfer-Encoding=chunked, test=1234, Connection=keep-alive, Date=Fri, 14 Jul 2023 02:12:15 GMT, Content-Type=application/json}
200
{"createdDate":null,"modifiedDate":null,"id":null,"name":"ccs","apiCode":"abcd"}

but, 400 or 500

--------------------post filter start------------11111111
{}
0
{"createdDate":null,"modifiedDate":null,"id":null,"name":"ccs","apiCode":"abcd"}

I want to process logic based on the upstream response status(200, 400, 500)
can u check this problems?
@nic-chen

and one more thing..
In about half of all calls, postfilter throws java.lang.IndexOutOfBoundsException: null.
error.log is

2023/07/14 11:35:23 [warn] 6638#6638: *17534332 [lua] init.lua:953: 2023-07-14 11:35:23.257  INFO 6652 --- [tLoopGroup-34-5] c.d.p.F.TestFilter                       : --------------------post filter start------------11111111
, context: ngx.timer
2023/07/14 11:35:23 [warn] 6638#6638: *17534332 [lua] init.lua:953: 2023-07-14 11:35:23.257 ERROR 6652 --- [tLoopGroup-34-5] o.a.a.p.r.h.RpcCallHandler               : handle request error:

java.lang.IndexOutOfBoundsException: null
        at java.nio.Buffer.checkIndex(Buffer.java:693) ~[?:?]
        at java.nio.DirectByteBuffer.getInt(DirectByteBuffer.java:758) ~[?:?]
        at com.google.flatbuffers.Table.__vector_len(Table.java:125) ~[flatbuffers-java-2.0.0.jar!/:?]
        at io.github.api7.A6.HTTPRespCall.Req.headersLength(Req.java:22) ~[A6-0.6.0-RELEASE.jar!/:?]
        at org.apache.apisix.plugin.runner.PostRequest.getUpstreamHeaders(PostRequest.java:81) ~[apisix-runner-plugin-sdk-0.4.0.jar!/:0.4.0]
        at com.platform.Filter.TestFilter.postFilter(TestFilter.java:127) ~[classes!/:1.0.0]
        at org.apache.apisix.plugin.runner.filter.PluginFilterChain.postFilter(PluginFilterChain.java:64) ~[apisix-runner-plugin-sdk-0.4.0.jar!/:0.4.0]
        at org.apache.apisix.plugin.runner.handler.RpcCallHandler.doPostFilter(RpcCallHandler.java:211) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at org.apache.apisix.plugin.runner.handler.RpcCallHandler.handleExtraInfo(RpcCallHandler.java:243) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at org.apache.apisix.plugin.runner.handler.RpcCallHandler.channelRead0(RpcCallHandler.java:92) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at org.apache.apisix.plugin.runner.handler.RpcCallHandler.channelRead0(RpcCallHandler.java:54) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at org.apache.apisix.plugin.runner.handler.PrepareConfHandler.channelRead0(PrepareConfHandler.java:57) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at org.apache.apisix.plugin.runner.handler.PrepareConfHandler.channelRead0(PrepareConfHandler.java:45) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at org.apache.apisix.plugin.runner.handler.PayloadDecoder.channelRead0(PayloadDecoder.java:45) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at org.apache.apisix.plugin.runner.handler.PayloadDecoder.channelRead0(PayloadDecoder.java:38) ~[apisix-runner-core-0.4.0.jar!/:0.4.0]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[nett, context: ngx.timer
2023/07/14 11:35:23 [warn] 6638#6638: *17534332 [lua] init.lua:953: y-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327) ~[netty-codec-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299) ~[netty-codec-4.1., context: ngx.timer
2023/07/14 11:35:23 [warn] 6638#6638: *17534332 [lua] init.lua:953: 78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:280) ~[netty-handler-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) ~[netty-transport-classes-epoll-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.epoll.EpollDomainSocketChannel$EpollDomainUnsafe.epollInReady(EpollDomainSocketChannel.java:138) ~[netty-transport-classes-epoll-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:487) ~[netty-transport-classes-epoll-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:385) ~[netty-transport-classes-epoll-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.78.Final.jar!/:4.1.78.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.78.Final.jar!/:4.1.78.Final]
        at java.lang.Thread.run(Thread.java:829) ~[?:?]

TestFilter.java:127 line is 'log.info(request.getUpstreamHeaders().toString())'

thx in advance

Environment

apisix 3.2.0, 3.2.1
apisix-java-plugin-runner 0.4.0

hi @Cheol-Soon-Choi

Could you provide a minimal usable repro case? Based on the information you have provided so far, it is difficult for me to reproduce, Thanks!

my Route info

{
  "uri": "/bodybody*",
  "name": "test1234",
  "methods": [
    "GET",
    "POST"
  ],
  "plugins": {
    "ext-plugin-post-resp": {
      "_meta": {
        "disable": false
      },
      "allow_degradation": false,
      "conf": [
        {
          "name": "Test_Gateway",
          "value": "{\"rejected_body2\":\"failed\",\"rejected_code2\":\"403\"}"
        }
      ]
    }
  },
  "upstream": {
    "nodes": [
      {
        "host": "127.0.0.1",
        "port": 8080,
        "weight": 1
      }
    ],
    "timeout": {
      "connect": 6,
      "send": 6,
      "read": 6
    },
    "type": "roundrobin",
    "scheme": "http",
    "pass_host": "pass",
    "keepalive_pool": {
      "idle_timeout": 60,
      "requests": 1000,
      "size": 320
    }
  },
  "status": 1
}

my filter info

    @Override
    public void filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
        // get conf of current filter
        String configStr = request.getConfig(this);
        Gson gson = new Gson();
        Map<String, Object> conf = new HashMap<>();
        // convert according to the actual configured conf type
        conf = gson.fromJson(configStr, conf.getClass());
        String k1 = request.getVars("uri");
        String endP = k1.split("/")[1];
        log.info("nginx_uri: " + k1);
        log.info("is_args: " + request.getVars("is_args"));
        chain.filter(request, response);
    }

    @Override
    public void postFilter(PostRequest request, PostResponse response, PluginFilterChain chain) {
        log.info("--------------------post filter start------------11111111");
//        log.info(request.getUpstreamHeaders().toString());
        log.info(request.getUpstreamStatusCode().toString());
        log.info(request.getBody());
        log.info("--------------------post filter end------------11111111");

        chain.postFilter(request, response);
    }

    @Override
    public List<String> requiredVars() {
        List<String> vars = new ArrayList<>();
        return vars;
    }

    @Override
    public Boolean requiredBody() {
        return true;
    }

    @Override
    public Boolean requiredRespBody() {
        return true;
    }

my upstream(127.0.0.1:8080) info

    @GetMapping("/bodybody*")
    public ResponseEntity fea2A2s2sbcd22d31222212d(@RequestHeader Map<String, String> headers) throws Exception {

        for (Map.Entry<String, String> entry : headers.entrySet()) {
            System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
        }

        HttpHeaders aaHeaders = new HttpHeaders();
        aaHeaders.add("test", "1234");

            if (headers.get("error") != null & headers.get("error").equals("400")) {
            return new ResponseEntity(user, aaHeaders, HttpStatus.BAD_REQUEST);
        } else if (headers.get("error") != null & headers.get("error").equals("100")) {
            throw new Exception();
        }

        return new ResponseEntity(aaHeaders, HttpStatus.OK);
    }

when upstream throws an exception, log status value is 0.
u can repro with my info @nic-chen