ArmeriaServerCall extends ServerCall<I, O> implements ArmeriaMessageDeframer.Listener, TransportStatusListener { @Override public void messageRead(DeframedMessage message) { final I request; final ByteBuf buf = message.buf(); boolean success = false; try { if (messageReceived && method.getType() == MethodType.UNARY) { closeListener(Status.INTERNAL.withDescription( "More than one request messages for unary call or server streaming call")); return; } messageReceived = true; if (isCancelled()) { return; } success = true; } finally { if (buf != null && !success) { buf.release(); } } final boolean grpcWebText = GrpcSerializationFormats.isGrpcWebText(serializationFormat); try { request = marshaller.deserializeRequest(message, grpcWebText); } catch (IOException e) { throw new UncheckedIOException(e); } if (!ctx.log().isAvailable(RequestLogProperty.REQUEST_CONTENT)) { ctx.logBuilder().requestContent(GrpcLogUtil.rpcRequest(method, request), null); } if (unsafeWrapRequestBuffers && buf != null && !grpcWebText) { GrpcUnsafeBufferUtil.storeBuffer(buf, request, ctx); } if (blockingExecutor != null) { blockingExecutor.execute(() -> invokeOnMessage(request)); } else { invokeOnMessage(request); } } ArmeriaServerCall(HttpHeaders clientHeaders,
                      MethodDescriptor<I, O> method,
                      CompressorRegistry compressorRegistry,
                      DecompressorRegistry decompressorRegistry,
                      HttpResponseWriter res,
                      int maxInboundMessageSizeBytes,
                      int maxOutboundMessageSizeBytes,
                      ServiceRequestContext ctx,
                      SerializationFormat serializationFormat,
                      @Nullable GrpcJsonMarshaller jsonMarshaller,
                      boolean unsafeWrapRequestBuffers,
                      boolean useBlockingTaskExecutor,
                      ResponseHeaders defaultHeaders); @Override void request(int numMessages); @Override void sendHeaders(Metadata metadata); @Override void sendMessage(O message); @Override boolean isReady(); @Override void close(Status status, Metadata metadata); @Override boolean isCancelled(); @Override synchronized void setMessageCompression(boolean messageCompression); @Override synchronized void setCompression(String compressorName); @Override MethodDescriptor<I, O> getMethodDescriptor(); @Override void messageRead(DeframedMessage message); @Override void endOfStream(); @Override void transportReportStatus(Status status, Metadata unused);  }
@Test public void messageRead_notWrappedByteBuf() { final ByteBuf buf = GrpcTestUtil.requestByteBuf(); call.messageRead(new DeframedMessage(buf, 0)); verifyNoMoreInteractions(buffersAttr); }
@Test public void messageRead_wrappedByteBuf() { tearDown(); call = new ArmeriaServerCall<>( HttpHeaders.of(), TestServiceGrpc.getUnaryCallMethod(), CompressorRegistry.getDefaultInstance(), DecompressorRegistry.getDefaultInstance(), res, MAX_MESSAGE_BYTES, MAX_MESSAGE_BYTES, ctx, GrpcSerializationFormats.PROTO, new DefaultJsonMarshaller(MessageMarshaller.builder().build()), true, false, ResponseHeaders.builder(HttpStatus.OK) .contentType(GrpcSerializationFormats.PROTO.mediaType()) .build()); final ByteBuf buf = GrpcTestUtil.requestByteBuf(); call.messageRead(new DeframedMessage(buf, 0)); verify(buffersAttr).put(any(), same(buf)); }