private void exportRpcResponse(Map<String, String> out, RequestLog log) { if (!log.isAvailable(RequestLogAvailability.RESPONSE_CONTENT)) { return; } final Object responseContent = log.responseContent(); if (responseContent instanceof RpcResponse) { final RpcResponse rpcRes = (RpcResponse) responseContent; if (builtIns.contains(RES_RPC_RESULT) && !rpcRes.isCompletedExceptionally()) { try { out.put(RES_RPC_RESULT.mdcKey, String.valueOf(rpcRes.get())); } catch (Exception e) { // Should never reach here because RpcResponse must be completed. throw new Error(e); } } } }
@Test public void compressedClient_compressedEndpoint() throws Exception { assertThat(blockingClient.staticUnaryCallSetsMessageCompression(REQUEST_MESSAGE)) .isEqualTo(RESPONSE_MESSAGE); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo( "armeria.grpc.testing.UnitTestService/StaticUnaryCallSetsMessageCompression"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void emptyUnary() throws Exception { assertThat(blockingStub.emptyCall(EMPTY)).isEqualTo(EMPTY); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.params()).containsExactly(EMPTY); assertThat(rpcRes.get()).isEqualTo(EMPTY); }); }
@Test public void unary_normal() throws Exception { assertThat(blockingClient.staticUnaryCall(REQUEST_MESSAGE)).isEqualTo(RESPONSE_MESSAGE); // Confirm gRPC paths are cached despite using serviceUnder assertThat(PathAndQuery.cachedPaths()) .contains("/armeria.grpc.testing.UnitTestService/StaticUnaryCall"); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StaticUnaryCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
private static void verifyOneWayInvocation(Class<?> expectedServiceType, String expectedParam) { await().untilAsserted(() -> { final RequestLog log = requestLogs.poll(); assertThat(log).isNotNull(); final RpcRequest req = (RpcRequest) log.requestContent(); final RpcResponse res = (RpcResponse) log.responseContent(); assertThat(req).isNotNull(); assertThat(req.serviceType()).isSameAs(expectedServiceType); assertThat(req.method()).isEqualTo("hello"); assertThat(req.params()).containsExactly(expectedParam); assertThat((Object) res).isNotNull(); assertThat(res.get()).isNull(); }); }
@Test public void streamedOutput_normal() throws Exception { final StreamRecorder<SimpleResponse> recorder = StreamRecorder.create(); streamingClient.staticStreamedOutputCall(REQUEST_MESSAGE, recorder); recorder.awaitCompletion(); assertThat(recorder.getValues()).containsExactly(RESPONSE_MESSAGE, RESPONSE_MESSAGE); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo( "armeria.grpc.testing.UnitTestService/StaticStreamedOutputCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void exchangeHeadersUnaryCall() throws Exception { final TestServiceBlockingStub stub = Clients.newDerivedClient( blockingStub, ClientOption.HTTP_HEADERS.newValue( HttpHeaders.of() .set(TestServiceImpl.EXTRA_HEADER_NAME, "dog"))); assertThat(stub.emptyCall(EMPTY)).isNotNull(); // Assert that our side channel object is echoed back in both headers and trailers assertThat(CLIENT_HEADERS_CAPTURE.get().get(TestServiceImpl.EXTRA_HEADER_NAME)).isEqualTo("dog"); assertThat(SERVER_TRAILERS_CAPTURE.get().get(TestServiceImpl.EXTRA_HEADER_NAME)).isEqualTo("dog"); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.params()).containsExactly(EMPTY); assertThat(rpcRes.get()).isEqualTo(EMPTY); }); }
@Test public void emptyStream() throws Exception { final StreamRecorder<StreamingOutputCallResponse> responseObserver = StreamRecorder.create(); final StreamObserver<StreamingOutputCallRequest> requestObserver = asyncStub.fullDuplexCall(responseObserver); requestObserver.onCompleted(); responseObserver.awaitCompletion(operationTimeoutMillis(), TimeUnit.MILLISECONDS); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.params()).isEmpty(); assertThat(rpcRes.get()).isNull(); }); }
@Test public void json() throws Exception { final AtomicReference<HttpHeaders> requestHeaders = new AtomicReference<>(); final UnitTestServiceBlockingStub jsonStub = new ClientBuilder(server.httpUri(GrpcSerializationFormats.JSON, "/")) .decorator(client -> new SimpleDecoratingClient<HttpRequest, HttpResponse>(client) { @Override public HttpResponse execute(ClientRequestContext ctx, HttpRequest req) throws Exception { requestHeaders.set(req.headers()); return delegate().execute(ctx, req); } }) .build(UnitTestServiceBlockingStub.class); final SimpleResponse response = jsonStub.staticUnaryCall(REQUEST_MESSAGE); assertThat(response).isEqualTo(RESPONSE_MESSAGE); assertThat(requestHeaders.get().get(HttpHeaderNames.CONTENT_TYPE)).isEqualTo("application/grpc+json"); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StaticUnaryCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void requestContextSet() throws Exception { final StreamRecorder<SimpleResponse> response = StreamRecorder.create(); final StreamObserver<SimpleRequest> request = streamingClient.checkRequestContext(response); request.onNext(REQUEST_MESSAGE); request.onNext(REQUEST_MESSAGE); request.onNext(REQUEST_MESSAGE); request.onCompleted(); response.awaitCompletion(); final SimpleResponse expectedResponse = SimpleResponse.newBuilder() .setPayload(Payload.newBuilder() .setBody(ByteString.copyFromUtf8("3"))) .build(); assertThat(response.getValues()).containsExactly(expectedResponse); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/CheckRequestContext"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(expectedResponse); }); }
@Test public void uncompressedClient_compressedEndpoint() throws Exception { final ManagedChannel nonDecompressingChannel = ManagedChannelBuilder.forAddress("127.0.0.1", server.httpPort()) .decompressorRegistry( DecompressorRegistry.emptyInstance() .with(Codec.Identity.NONE, false)) .usePlaintext() .build(); final UnitTestServiceBlockingStub client = UnitTestServiceGrpc.newBlockingStub(nonDecompressingChannel); assertThat(client.staticUnaryCallSetsMessageCompression(REQUEST_MESSAGE)) .isEqualTo(RESPONSE_MESSAGE); nonDecompressingChannel.shutdownNow(); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo( "armeria.grpc.testing.UnitTestService/StaticUnaryCallSetsMessageCompression"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void unframed() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticUnaryCallMethod().getFullMethodName()) .set(HttpHeaderNames.CONTENT_TYPE, "application/protobuf"), REQUEST_MESSAGE.toByteArray()).aggregate().get(); final SimpleResponse message = SimpleResponse.parseFrom(response.content().array()); assertThat(message).isEqualTo(RESPONSE_MESSAGE); assertThat(response.headers().getInt(HttpHeaderNames.CONTENT_LENGTH)) .isEqualTo(response.content().length()); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StaticUnaryCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void unframed_acceptEncoding() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticUnaryCallMethod().getFullMethodName()) .set(HttpHeaderNames.CONTENT_TYPE, "application/protobuf") .set(GrpcHeaderNames.GRPC_ACCEPT_ENCODING, "gzip,none"), REQUEST_MESSAGE.toByteArray()).aggregate().get(); final SimpleResponse message = SimpleResponse.parseFrom(response.content().array()); assertThat(message).isEqualTo(RESPONSE_MESSAGE); assertThat(response.headers().getInt(HttpHeaderNames.CONTENT_LENGTH)) .isEqualTo(response.content().length()); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StaticUnaryCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void veryLargeResponse() throws Exception { final SimpleRequest request = SimpleRequest.newBuilder() .setResponseSize(unaryPayloadLength()) .setResponseType(COMPRESSABLE) .build(); final SimpleResponse goldenResponse = SimpleResponse.newBuilder() .setPayload(Payload.newBuilder() .setType(COMPRESSABLE) .setBody(ByteString.copyFrom(new byte[unaryPayloadLength()]))) .build(); assertThat(blockingStub.unaryCall(request)).isEqualTo(goldenResponse); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.params()).containsExactly(request); assertThat(rpcRes.get()).isEqualTo(goldenResponse); }); }
@Test public void largeUnary() throws Exception { final SimpleRequest request = SimpleRequest.newBuilder() .setResponseSize(314159) .setResponseType(COMPRESSABLE) .setPayload(Payload.newBuilder() .setBody(ByteString.copyFrom(new byte[271828]))) .build(); final SimpleResponse goldenResponse = SimpleResponse.newBuilder() .setPayload(Payload.newBuilder() .setType(COMPRESSABLE) .setBody(ByteString.copyFrom(new byte[314159]))) .build(); assertThat(blockingStub.unaryCall(request)).isEqualTo(goldenResponse); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.params()).containsExactly(request); assertThat(rpcRes.get()).isEqualTo(goldenResponse); }); }
@Test(timeout = 10000) public void testMessageLogsForOneWay() throws Exception { final OnewayHelloService.Iface client = Clients.newClient(clientFactory(), getURI(Handlers.HELLO), Handlers.ONEWAYHELLO.iface(), clientOptions); recordMessageLogs = true; client.hello("trustin"); final RequestLog log = requestLogs.take(); assertThat(log.requestHeaders()).isInstanceOf(HttpHeaders.class); assertThat(log.requestContent()).isInstanceOf(RpcRequest.class); assertThat(log.rawRequestContent()).isInstanceOf(ThriftCall.class); final RpcRequest request = (RpcRequest) log.requestContent(); assertThat(request.serviceType()).isEqualTo(OnewayHelloService.Iface.class); assertThat(request.method()).isEqualTo("hello"); assertThat(request.params()).containsExactly("trustin"); final ThriftCall rawRequest = (ThriftCall) log.rawRequestContent(); assertThat(rawRequest.header().type).isEqualTo(TMessageType.ONEWAY); assertThat(rawRequest.header().name).isEqualTo("hello"); assertThat(rawRequest.args()).isInstanceOf(OnewayHelloService.hello_args.class); assertThat(((OnewayHelloService.hello_args) rawRequest.args()).getName()).isEqualTo("trustin"); assertThat(log.responseHeaders()).isInstanceOf(HttpHeaders.class); assertThat(log.responseContent()).isInstanceOf(RpcResponse.class); assertThat(log.rawResponseContent()).isNull(); final RpcResponse response = (RpcResponse) log.responseContent(); assertThat(response.get()).isNull(); }
assertThat(response.get()).isEqualTo("Hello, trustin!");
assertThat(response.get()).isEqualTo("Hello, Trustin!");
@Test public void veryLargeRequest() throws Exception { final SimpleRequest request = SimpleRequest.newBuilder() .setPayload(Payload.newBuilder() .setType(COMPRESSABLE) .setBody(ByteString.copyFrom(new byte[unaryPayloadLength()]))) .setResponseSize(10) .setResponseType(COMPRESSABLE) .build(); final SimpleResponse goldenResponse = SimpleResponse.newBuilder() .setPayload(Payload.newBuilder() .setType(COMPRESSABLE) .setBody(ByteString.copyFrom(new byte[10]))) .build(); assertThat(blockingStub.unaryCall(request)).isEqualTo(goldenResponse); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.params()).containsExactly(request); assertThat(rpcRes.get()).isEqualTo(goldenResponse); }); }
@Test public void grpcWeb() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticUnaryCallMethod().getFullMethodName()) .set(HttpHeaderNames.CONTENT_TYPE, "application/grpc-web"), GrpcTestUtil.uncompressedFrame(GrpcTestUtil.requestByteBuf())).aggregate().get(); final byte[] serializedStatusHeader = "grpc-status: 0\r\n".getBytes(StandardCharsets.US_ASCII); final byte[] serializedTrailers = Bytes.concat( new byte[] { ArmeriaServerCall.TRAILERS_FRAME_HEADER }, Ints.toByteArray(serializedStatusHeader.length), serializedStatusHeader); assertThat(response.content().array()).containsExactly( Bytes.concat( GrpcTestUtil.uncompressedFrame( GrpcTestUtil.protoByteBuf(RESPONSE_MESSAGE)), serializedTrailers)); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StaticUnaryCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }