Class Http3GrpcBidiStreamHandler

java.lang.Object
org.mockserver.netty.http3.Http3GrpcBidiStreamHandler

public class Http3GrpcBidiStreamHandler extends Object
Drives true bidirectional gRPC streaming over a single QUIC bidirectional stream (HTTP/3). It is the HTTP/3 analogue of GrpcBidiStreamHandler but, instead of being a Netty pipeline handler, it is a plain helper driven by Http3MockServerHandler (which already extends Netty's Http3RequestStreamInboundHandler and receives frames incrementally via channelRead / channelInputClosed).

A QUIC stream is full-duplex, so the server can write response frames while the client is still sending request frames. The lifecycle is:

  • start() -- write the initial response HEADERS (:status=200, content-type=application/grpc, plus any configured headers) and any EAGER messages from the GrpcBidiResponse (honouring per-message delays);
  • onData(byte[]) -- feed inbound bytes to the incremental gRPC frame decoder; for each complete inbound message, convert protobuf to JSON, evaluate rules in order, and emit the first matching rule's responses as DATA frames;
  • onInputClosed() -- the client half-closed (FIN); once all scheduled response writes have drained, write the trailing HEADERS carrying grpc-status and shut the QUIC stream output;
  • onChannelInactive() -- the stream/connection was torn down; clears responseInProgress on the matched expectation via the completion callback.

All methods run on the QUIC stream's single event-loop thread, so the activeChains counter that orders the trailing HEADERS after all (possibly delayed) response writes needs no synchronization. The completion callback is guarded by an AtomicBoolean so it runs exactly once across every terminal path.

  • Constructor Details

  • Method Details

    • start

      public void start()
      Write the initial response HEADERS and any eager messages. The top-level action delay (Action.getDelay()), if configured, delays the eager message stream (the HEADERS are sent promptly so inbound DATA frames never race ahead of them).
    • onData

      public void onData(byte[] bytes)
      Feed inbound request bytes: decode complete gRPC frames, convert each to JSON, and emit the first matching rule's responses.
    • onInputClosed

      public void onInputClosed()
      The client half-closed (END_STREAM). Finish once all scheduled responses have drained.
    • onChannelInactive

      public void onChannelInactive()
      The QUIC stream / connection was torn down. Clear responseInProgress so a times-limited expectation is not left stuck when a bidi stream is abandoned without a clean END_STREAM.