private void exportRpcRequest(Map<String, String> out, RequestLog log) { if (!log.isAvailable(RequestLogAvailability.REQUEST_CONTENT)) { return; } final Object requestContent = log.requestContent(); if (requestContent instanceof RpcRequest) { final RpcRequest rpcReq = (RpcRequest) requestContent; if (builtIns.contains(REQ_RPC_METHOD)) { out.put(REQ_RPC_METHOD.mdcKey, rpcReq.method()); } if (builtIns.contains(REQ_RPC_PARAMS)) { out.put(REQ_RPC_PARAMS.mdcKey, String.valueOf(rpcReq.params())); } } }
@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 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 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 error_withMessage() throws Exception { final StatusRuntimeException t = (StatusRuntimeException) catchThrowable( () -> blockingClient.errorWithMessage(REQUEST_MESSAGE)); assertThat(t.getStatus().getCode()).isEqualTo(Code.ABORTED); assertThat(t.getStatus().getDescription()).isEqualTo("aborted call"); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/ErrorWithMessage"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(grpcStatus).isNotNull(); assertThat(grpcStatus.getCode()).isEqualTo(Code.ABORTED); assertThat(grpcStatus.getDescription()).isEqualTo("aborted call"); }); }
@Override public RpcResponse serve(ServiceRequestContext ctx, RpcRequest req) throws Exception { ctx.setRequestTimeoutMillis(((Number) req.params().get(0)).longValue() + ctx.requestTimeoutMillis()); return delegate().serve(ctx, req); } }
@Override public RpcResponse execute(ClientRequestContext ctx, RpcRequest req) throws Exception { ctx.setResponseTimeoutMillis(((Number) req.params().get(0)).longValue() + ctx.responseTimeoutMillis()); return delegate().execute(ctx, req); } }
@Test public void error_thrown_unary() throws Exception { final StatusRuntimeException t = (StatusRuntimeException) catchThrowable( () -> blockingClient.unaryThrowsError(REQUEST_MESSAGE)); assertThat(t.getStatus().getCode()).isEqualTo(Code.ABORTED); assertThat(t.getStatus().getDescription()).isEqualTo("call aborted"); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/UnaryThrowsError"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(grpcStatus).isNotNull(); assertThat(grpcStatus.getCode()).isEqualTo(Code.ABORTED); assertThat(grpcStatus.getDescription()).isEqualTo("call aborted"); }); }
@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); }); }
/** Sends an rpc to an unimplemented method within TestService. */ @Test public void unimplementedMethod() throws Exception { final Throwable t = catchThrowable(() -> blockingStub.unimplementedCall(Empty.getDefaultInstance())); assertThat(t).isInstanceOf(StatusRuntimeException.class); assertThat(((StatusRuntimeException) t).getStatus().getCode()) .isEqualTo(Status.UNIMPLEMENTED.getCode()); checkRequestLogError((headers, rpcReq, cause) -> { assertThat(rpcReq).isNotNull(); assertThat(rpcReq.params()).containsExactly(Empty.getDefaultInstance()); assertThat(headers.get(GrpcHeaderNames.GRPC_STATUS)).isEqualTo( String.valueOf(Status.UNIMPLEMENTED.getCode().value())); }); }
@Test public void error_thrown_streamMessage() throws Exception { final StreamRecorder<SimpleResponse> response = StreamRecorder.create(); final StreamObserver<SimpleRequest> request = streamingClient.streamThrowsError(response); request.onNext(REQUEST_MESSAGE); response.awaitCompletion(); final StatusRuntimeException t = (StatusRuntimeException) response.getError(); assertThat(t.getStatus().getCode()).isEqualTo(Code.ABORTED); assertThat(t.getStatus().getDescription()).isEqualTo("bad streaming message"); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StreamThrowsError"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(grpcStatus).isNotNull(); assertThat(grpcStatus.getCode()).isEqualTo(Code.ABORTED); assertThat(grpcStatus.getDescription()).isEqualTo("bad streaming message"); }); }
@Test public void error_noMessage() throws Exception { final StatusRuntimeException t = (StatusRuntimeException) catchThrowable( () -> blockingClient.errorNoMessage(REQUEST_MESSAGE)); assertThat(t.getStatus().getCode()).isEqualTo(Code.ABORTED); assertThat(t.getStatus().getDescription()).isNull(); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/ErrorNoMessage"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(grpcStatus).isNotNull(); assertThat(grpcStatus.getCode()).isEqualTo(Code.ABORTED); assertThat(grpcStatus.getDescription()).isNull(); }); }
@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 unimplementedService() throws Exception { final UnimplementedServiceGrpc.UnimplementedServiceBlockingStub stub = UnimplementedServiceGrpc.newBlockingStub(asyncStub.getChannel()); final Throwable t = catchThrowable(() -> stub.unimplementedCall(Empty.getDefaultInstance())); assertThat(t).isInstanceOf(StatusRuntimeException.class); assertThat(((StatusRuntimeException) t).getStatus().getCode()) .isEqualTo(Status.UNIMPLEMENTED.getCode()); checkRequestLogError((headers, rpcReq, cause) -> { // rpcReq may be null depending on timing. if (rpcReq != null) { assertThat(rpcReq.params()).containsExactly(Empty.getDefaultInstance()); } assertThat(headers.get(GrpcHeaderNames.GRPC_STATUS)).isEqualTo( String.valueOf(Status.UNIMPLEMENTED.getCode().value())); }); }
@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); }); }