Search in sources :

Example 21 with ServerCall

use of io.grpc.ServerCall in project grpc-java by grpc.

the class ServerImplTest method basicExchangeSuccessful.

@Test
public void basicExchangeSuccessful() throws Exception {
    createAndStartServer(NO_FILTERS);
    final Metadata.Key<String> metadataKey = Metadata.Key.of("inception", Metadata.ASCII_STRING_MARSHALLER);
    final Metadata.Key<StatsContext> statsHeaderKey = StatsTraceContext.createStatsHeader(statsCtxFactory);
    final AtomicReference<ServerCall<String, Integer>> callReference = new AtomicReference<ServerCall<String, Integer>>();
    MethodDescriptor<String, Integer> method = MethodDescriptor.<String, Integer>newBuilder().setType(MethodDescriptor.MethodType.UNKNOWN).setFullMethodName("Waiter/serve").setRequestMarshaller(STRING_MARSHALLER).setResponseMarshaller(INTEGER_MARSHALLER).build();
    mutableFallbackRegistry.addService(ServerServiceDefinition.builder(new ServiceDescriptor("Waiter", method)).addMethod(method, new ServerCallHandler<String, Integer>() {

        @Override
        public ServerCall.Listener<String> startCall(ServerCall<String, Integer> call, Metadata headers) {
            assertEquals("Waiter/serve", call.getMethodDescriptor().getFullMethodName());
            assertNotNull(call);
            assertNotNull(headers);
            assertEquals("value", headers.get(metadataKey));
            callReference.set(call);
            return callListener;
        }
    }).build());
    ServerTransportListener transportListener = transportServer.registerNewServerTransport(new SimpleServerTransport());
    Metadata requestHeaders = new Metadata();
    requestHeaders.put(metadataKey, "value");
    StatsContext statsContextOnClient = statsCtxFactory.getDefault().with(StatsTestUtils.EXTRA_TAG, TagValue.create("extraTagValue"));
    requestHeaders.put(statsHeaderKey, statsContextOnClient);
    StatsTraceContext statsTraceCtx = transportListener.methodDetermined("Waiter/serve", requestHeaders);
    assertNotNull(statsTraceCtx);
    when(stream.statsTraceContext()).thenReturn(statsTraceCtx);
    transportListener.streamCreated(stream, "Waiter/serve", requestHeaders);
    verify(stream).setListener(streamListenerCaptor.capture());
    ServerStreamListener streamListener = streamListenerCaptor.getValue();
    assertNotNull(streamListener);
    verify(stream, atLeast(1)).statsTraceContext();
    assertEquals(1, executor.runDueTasks());
    ServerCall<String, Integer> call = callReference.get();
    assertNotNull(call);
    verify(stream).getAuthority();
    String order = "Lots of pizza, please";
    streamListener.messageRead(STRING_MARSHALLER.stream(order));
    assertEquals(1, executor.runDueTasks());
    verify(callListener).onMessage(order);
    Metadata responseHeaders = new Metadata();
    responseHeaders.put(metadataKey, "response value");
    call.sendHeaders(responseHeaders);
    verify(stream).writeHeaders(responseHeaders);
    verify(stream).setCompressor(isA(Compressor.class));
    call.sendMessage(314);
    ArgumentCaptor<InputStream> inputCaptor = ArgumentCaptor.forClass(InputStream.class);
    verify(stream).writeMessage(inputCaptor.capture());
    verify(stream).flush();
    assertEquals(314, INTEGER_MARSHALLER.parse(inputCaptor.getValue()).intValue());
    // All full; no dessert.
    streamListener.halfClosed();
    assertEquals(1, executor.runDueTasks());
    verify(callListener).onHalfClose();
    call.sendMessage(50);
    verify(stream, times(2)).writeMessage(inputCaptor.capture());
    verify(stream, times(2)).flush();
    assertEquals(50, INTEGER_MARSHALLER.parse(inputCaptor.getValue()).intValue());
    Metadata trailers = new Metadata();
    trailers.put(metadataKey, "another value");
    Status status = Status.OK.withDescription("A okay");
    call.close(status, trailers);
    verify(stream).close(status, trailers);
    streamListener.closed(Status.OK);
    assertEquals(1, executor.runDueTasks());
    verify(callListener).onComplete();
    verify(stream, atLeast(1)).statsTraceContext();
    verifyNoMoreInteractions(stream);
    verifyNoMoreInteractions(callListener);
    // Check stats
    StatsTestUtils.MetricsRecord record = statsCtxFactory.pollRecord();
    assertNotNull(record);
    TagValue methodTag = record.tags.get(RpcConstants.RPC_SERVER_METHOD);
    assertNotNull(methodTag);
    assertEquals("Waiter/serve", methodTag.toString());
    TagValue statusTag = record.tags.get(RpcConstants.RPC_STATUS);
    assertNotNull(statusTag);
    assertEquals(Status.Code.OK.toString(), statusTag.toString());
    TagValue extraTag = record.tags.get(StatsTestUtils.EXTRA_TAG);
    assertNotNull(extraTag);
    assertEquals("extraTagValue", extraTag.toString());
    assertNull(record.getMetric(RpcConstants.RPC_CLIENT_REQUEST_BYTES));
    assertNull(record.getMetric(RpcConstants.RPC_CLIENT_RESPONSE_BYTES));
    assertNull(record.getMetric(RpcConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES));
    assertNull(record.getMetric(RpcConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES));
    // The test doesn't invoke MessageFramer and MessageDeframer which keep the sizes.
    // Thus the sizes reported to stats would be zero.
    assertEquals(0, record.getMetricAsLongOrFail(RpcConstants.RPC_SERVER_REQUEST_BYTES));
    assertEquals(0, record.getMetricAsLongOrFail(RpcConstants.RPC_SERVER_RESPONSE_BYTES));
    assertEquals(0, record.getMetricAsLongOrFail(RpcConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES));
    assertEquals(0, record.getMetricAsLongOrFail(RpcConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES));
}
Also used : JumpToApplicationThreadServerStreamListener(io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener) StatsTestUtils(io.grpc.internal.testing.StatsTestUtils) Metadata(io.grpc.Metadata) ServerCall(io.grpc.ServerCall) ServiceDescriptor(io.grpc.ServiceDescriptor) StatsContext(com.google.instrumentation.stats.StatsContext) TagValue(com.google.instrumentation.stats.TagValue) Status(io.grpc.Status) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Compressor(io.grpc.Compressor) AtomicReference(java.util.concurrent.atomic.AtomicReference) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) JumpToApplicationThreadServerStreamListener(io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener) Test(org.junit.Test)

Example 22 with ServerCall

use of io.grpc.ServerCall in project grpc-java by grpc.

the class ServerImplTest method testClientCancelTriggersContextCancellation.

@Test
public void testClientCancelTriggersContextCancellation() throws Exception {
    createAndStartServer(NO_FILTERS);
    final AtomicBoolean contextCancelled = new AtomicBoolean(false);
    callListener = new ServerCall.Listener<String>() {

        @Override
        public void onReady() {
            Context.current().addListener(new Context.CancellationListener() {

                @Override
                public void cancelled(Context context) {
                    contextCancelled.set(true);
                }
            }, MoreExecutors.directExecutor());
        }
    };
    final AtomicReference<ServerCall<String, Integer>> callReference = new AtomicReference<ServerCall<String, Integer>>();
    MethodDescriptor<String, Integer> method = MethodDescriptor.<String, Integer>newBuilder().setType(MethodDescriptor.MethodType.UNKNOWN).setFullMethodName("Waiter/serve").setRequestMarshaller(STRING_MARSHALLER).setResponseMarshaller(INTEGER_MARSHALLER).build();
    mutableFallbackRegistry.addService(ServerServiceDefinition.builder(new ServiceDescriptor("Waiter", method)).addMethod(method, new ServerCallHandler<String, Integer>() {

        @Override
        public ServerCall.Listener<String> startCall(ServerCall<String, Integer> call, Metadata headers) {
            callReference.set(call);
            return callListener;
        }
    }).build());
    ServerTransportListener transportListener = transportServer.registerNewServerTransport(new SimpleServerTransport());
    Metadata requestHeaders = new Metadata();
    StatsTraceContext statsTraceCtx = transportListener.methodDetermined("Waiter/serve", requestHeaders);
    assertNotNull(statsTraceCtx);
    when(stream.statsTraceContext()).thenReturn(statsTraceCtx);
    transportListener.streamCreated(stream, "Waiter/serve", requestHeaders);
    verify(stream).setListener(streamListenerCaptor.capture());
    ServerStreamListener streamListener = streamListenerCaptor.getValue();
    assertNotNull(streamListener);
    streamListener.onReady();
    streamListener.closed(Status.CANCELLED);
    assertEquals(1, executor.runDueTasks());
    assertTrue(contextCancelled.get());
}
Also used : Context(io.grpc.Context) StatsContext(com.google.instrumentation.stats.StatsContext) JumpToApplicationThreadServerStreamListener(io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener) Metadata(io.grpc.Metadata) AtomicReference(java.util.concurrent.atomic.AtomicReference) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ServerCall(io.grpc.ServerCall) ServiceDescriptor(io.grpc.ServiceDescriptor) JumpToApplicationThreadServerStreamListener(io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener) Test(org.junit.Test)

Example 23 with ServerCall

use of io.grpc.ServerCall in project grpc-java by grpc.

the class ServerCallsTest method cannotDisableAutoFlowControlAfterServiceInvocation.

@Test
public void cannotDisableAutoFlowControlAfterServiceInvocation() throws Exception {
    final AtomicReference<ServerCallStreamObserver<Integer>> callObserver = new AtomicReference<ServerCallStreamObserver<Integer>>();
    ServerCallHandler<Integer, Integer> callHandler = ServerCalls.asyncBidiStreamingCall(new ServerCalls.BidiStreamingMethod<Integer, Integer>() {

        @Override
        public StreamObserver<Integer> invoke(StreamObserver<Integer> responseObserver) {
            callObserver.set((ServerCallStreamObserver<Integer>) responseObserver);
            return new ServerCalls.NoopStreamObserver<Integer>();
        }
    });
    ServerCall.Listener<Integer> callListener = callHandler.startCall(serverCall, new Metadata());
    callListener.onMessage(1);
    try {
        callObserver.get().disableAutoInboundFlowControl();
        fail("Cannot set onCancel handler after service invocation");
    } catch (IllegalStateException expected) {
    // Expected
    }
}
Also used : Metadata(io.grpc.Metadata) AtomicReference(java.util.concurrent.atomic.AtomicReference) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ServerCall(io.grpc.ServerCall) Test(org.junit.Test)

Example 24 with ServerCall

use of io.grpc.ServerCall in project grpc-java by grpc.

the class ServerCalls method asyncUnaryRequestCall.

/**
   * Creates a {@code ServerCallHandler} for a unary request call method of the service.
   *
   * @param method an adaptor to the actual method on the service implementation.
   */
private static <ReqT, RespT> ServerCallHandler<ReqT, RespT> asyncUnaryRequestCall(final UnaryRequestMethod<ReqT, RespT> method) {
    return new ServerCallHandler<ReqT, RespT>() {

        @Override
        public ServerCall.Listener<ReqT> startCall(final ServerCall<ReqT, RespT> call, Metadata headers) {
            final ServerCallStreamObserverImpl<ReqT, RespT> responseObserver = new ServerCallStreamObserverImpl<ReqT, RespT>(call);
            // We expect only 1 request, but we ask for 2 requests here so that if a misbehaving client
            // sends more than 1 requests, ServerCall will catch it. Note that disabling auto
            // inbound flow control has no effect on unary calls.
            call.request(2);
            return new EmptyServerCallListener<ReqT>() {

                ReqT request;

                @Override
                public void onMessage(ReqT request) {
                    // We delay calling method.invoke() until onHalfClose() to make sure the client
                    // half-closes.
                    this.request = request;
                }

                @Override
                public void onHalfClose() {
                    if (request != null) {
                        method.invoke(request, responseObserver);
                        responseObserver.freeze();
                        if (call.isReady()) {
                            // Since we are calling invoke in halfClose we have missed the onReady
                            // event from the transport so recover it here.
                            onReady();
                        }
                    } else {
                        call.close(Status.INTERNAL.withDescription("Half-closed without a request"), new Metadata());
                    }
                }

                @Override
                public void onCancel() {
                    responseObserver.cancelled = true;
                    if (responseObserver.onCancelHandler != null) {
                        responseObserver.onCancelHandler.run();
                    }
                }

                @Override
                public void onReady() {
                    if (responseObserver.onReadyHandler != null) {
                        responseObserver.onReadyHandler.run();
                    }
                }
            };
        }
    };
}
Also used : ServerCallHandler(io.grpc.ServerCallHandler) ServerCall(io.grpc.ServerCall) Metadata(io.grpc.Metadata)

Example 25 with ServerCall

use of io.grpc.ServerCall in project pravega by pravega.

the class RPCTracingHelpersTest method testInterceptors.

@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testInterceptors() {
    String requestDescriptor = "createStream-myScope-myStream";
    long requestId = 1234L;
    ClientInterceptor clientInterceptor = RPCTracingHelpers.getClientInterceptor();
    RequestTracker requestTracker = new RequestTracker(true);
    // Mocking RPC elements.
    MethodDescriptor.Marshaller<Object> mockMarshaller = Mockito.mock(MethodDescriptor.Marshaller.class);
    ClientCall.Listener<Object> listener = Mockito.mock(ClientCall.Listener.class);
    ServerCall serverCall = Mockito.mock(ServerCall.class);
    ServerCallHandler serverCallHandler = Mockito.mock(ServerCallHandler.class);
    @Cleanup("shutdown") ManagedChannel channel = NettyChannelBuilder.forTarget("localhost").build();
    MethodDescriptor method = MethodDescriptor.newBuilder().setFullMethodName("createStream").setType(MethodDescriptor.MethodType.UNARY).setRequestMarshaller(mockMarshaller).setResponseMarshaller(mockMarshaller).build();
    Mockito.when(serverCall.getMethodDescriptor()).thenReturn(method);
    // Actual elements to work with.
    CallOptions callOptions = CallOptions.DEFAULT;
    Metadata headers = new Metadata();
    // Test that headers do not contain tracing-related key/values, as call options are not set.
    clientInterceptor.interceptCall(method, callOptions, channel).start(listener, headers);
    assertFalse(headers.containsKey(RPCTracingHelpers.DESCRIPTOR_HEADER));
    assertFalse(headers.containsKey(RPCTracingHelpers.ID_HEADER));
    // Check that the server interceptor handles clients not sending tracing headers and that the cache remains clean.
    ServerInterceptor serverInterceptor = RPCTracingHelpers.getServerInterceptor(requestTracker);
    serverInterceptor.interceptCall(serverCall, headers, serverCallHandler);
    assertEquals(0, requestTracker.getNumDescriptors());
    // Add call options and check that headers are correctly set.
    callOptions = callOptions.withOption(RPCTracingHelpers.REQUEST_DESCRIPTOR_CALL_OPTION, requestDescriptor).withOption(RPCTracingHelpers.REQUEST_ID_CALL_OPTION, String.valueOf(requestId));
    clientInterceptor.interceptCall(method, callOptions, channel).start(listener, headers);
    assertEquals(requestDescriptor, headers.get(RPCTracingHelpers.DESCRIPTOR_HEADER));
    assertEquals(requestId, Long.parseLong(headers.get(RPCTracingHelpers.ID_HEADER)));
    // Test that the server interceptor correctly sets these headers in the cache for further tracking.
    serverInterceptor.interceptCall(serverCall, headers, serverCallHandler);
    assertEquals(1, requestTracker.getNumDescriptors());
    assertEquals(requestId, requestTracker.getRequestIdFor(requestDescriptor));
}
Also used : ServerCallHandler(io.grpc.ServerCallHandler) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) RequestTracker(io.pravega.common.tracing.RequestTracker) MethodDescriptor(io.grpc.MethodDescriptor) Cleanup(lombok.Cleanup) ServerCall(io.grpc.ServerCall) ClientCall(io.grpc.ClientCall) ServerInterceptor(io.grpc.ServerInterceptor) ClientInterceptor(io.grpc.ClientInterceptor) ManagedChannel(io.grpc.ManagedChannel) Test(org.junit.Test)

Aggregations

ServerCall (io.grpc.ServerCall)52 Metadata (io.grpc.Metadata)48 Test (org.junit.Test)42 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)26 AtomicReference (java.util.concurrent.atomic.AtomicReference)19 ServerCallHandler (io.grpc.ServerCallHandler)14 Status (io.grpc.Status)14 Context (io.grpc.Context)11 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)11 JumpToApplicationThreadServerStreamListener (io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener)10 Server (io.grpc.Server)9 ServerInterceptor (io.grpc.ServerInterceptor)9 ServiceDescriptor (io.grpc.ServiceDescriptor)9 IOException (java.io.IOException)8 ExecutionException (java.util.concurrent.ExecutionException)8 StatusException (io.grpc.StatusException)7 TimeoutException (java.util.concurrent.TimeoutException)7 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)7 Listener (io.grpc.ServerCall.Listener)6 StatusRuntimeException (io.grpc.StatusRuntimeException)5