Search in sources :

Example 16 with ClientInterceptor

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

the class ManagedChannelImplTest method newCallWithConfigSelector.

@Test
public void newCallWithConfigSelector() {
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(ImmutableList.of(addressGroup)).build();
    channelBuilder.nameResolverFactory(nameResolverFactory);
    channel = new ManagedChannelImpl(channelBuilder, mockTransportFactory, new FakeBackoffPolicyProvider(), balancerRpcExecutorPool, timer.getStopwatchSupplier(), Collections.<ClientInterceptor>emptyList(), timer.getTimeProvider());
    nameResolverFactory.nextConfigOrError.set(ConfigOrError.fromConfig(ManagedChannelServiceConfig.empty()));
    final Metadata.Key<String> metadataKey = Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER);
    final CallOptions.Key<String> callOptionsKey = CallOptions.Key.create("test");
    InternalConfigSelector configSelector = new InternalConfigSelector() {

        @Override
        public Result selectConfig(final PickSubchannelArgs args) {
            return Result.newBuilder().setConfig(ManagedChannelServiceConfig.empty()).setInterceptor(// An interceptor that mutates CallOptions based on headers value.
            new ClientInterceptor() {

                String value = args.getHeaders().get(metadataKey);

                @Override
                public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
                    callOptions = callOptions.withOption(callOptionsKey, value);
                    return next.newCall(method, callOptions);
                }
            }).build();
        }
    };
    nameResolverFactory.nextAttributes.set(Attributes.newBuilder().set(InternalConfigSelector.KEY, configSelector).build());
    channel.getState(true);
    Metadata headers = new Metadata();
    headers.put(metadataKey, "fooValue");
    ClientStream mockStream = mock(ClientStream.class);
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, headers);
    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
    verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
    helper = helperCaptor.getValue();
    // Make the transport available
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    requestConnectionSafely(helper, subchannel);
    verify(mockTransportFactory).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ManagedClientTransport.Listener transportListener = transportInfo.listener;
    when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
    transportListener.transportReady();
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    updateBalancingStateSafely(helper, READY, mockPicker);
    executor.runDueTasks();
    ArgumentCaptor<CallOptions> callOptionsCaptor = ArgumentCaptor.forClass(null);
    verify(mockTransport).newStream(same(method), same(headers), callOptionsCaptor.capture(), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertThat(callOptionsCaptor.getValue().getOption(callOptionsKey)).isEqualTo("fooValue");
    verify(mockStream).start(streamListenerCaptor.capture());
    // Clean up as much as possible to allow the channel to terminate.
    shutdownSafely(helper, subchannel);
    timer.forwardNanos(TimeUnit.SECONDS.toNanos(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS));
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) ClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) Helper(io.grpc.LoadBalancer.Helper) ClientInterceptor(io.grpc.ClientInterceptor) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) ChannelLogger(io.grpc.ChannelLogger) ProxiedSocketAddress(io.grpc.ProxiedSocketAddress) SocketAddress(java.net.SocketAddress) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) ManagedChannel(io.grpc.ManagedChannel) Channel(io.grpc.Channel) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) MethodDescriptor(io.grpc.MethodDescriptor) InternalConfigSelector(io.grpc.InternalConfigSelector) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) Test(org.junit.Test)

Example 17 with ClientInterceptor

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

the class ManagedChannelImplTest method startCallBeforeNameResolution.

@Test
public void startCallBeforeNameResolution() throws Exception {
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(ImmutableList.of(addressGroup)).build();
    channelBuilder.nameResolverFactory(nameResolverFactory);
    channel = new ManagedChannelImpl(channelBuilder, mockTransportFactory, new FakeBackoffPolicyProvider(), balancerRpcExecutorPool, timer.getStopwatchSupplier(), Collections.<ClientInterceptor>emptyList(), timer.getTimeProvider());
    Map<String, Object> rawServiceConfig = parseConfig("{\"methodConfig\":[{" + "\"name\":[{\"service\":\"service\"}]," + "\"waitForReady\":true}]}");
    ManagedChannelServiceConfig managedChannelServiceConfig = createManagedChannelServiceConfig(rawServiceConfig, null);
    nameResolverFactory.nextConfigOrError.set(ConfigOrError.fromConfig(managedChannelServiceConfig));
    Metadata headers = new Metadata();
    ClientStream mockStream = mock(ClientStream.class);
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, headers);
    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
    verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
    helper = helperCaptor.getValue();
    // Make the transport available
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    verify(mockTransportFactory, never()).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
    requestConnectionSafely(helper, subchannel);
    verify(mockTransportFactory).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ManagedClientTransport.Listener transportListener = transportInfo.listener;
    when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
    transportListener.transportReady();
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    updateBalancingStateSafely(helper, READY, mockPicker);
    executor.runDueTasks();
    ArgumentCaptor<CallOptions> callOptionsCaptor = ArgumentCaptor.forClass(null);
    verify(mockTransport).newStream(same(method), same(headers), callOptionsCaptor.capture(), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertThat(callOptionsCaptor.getValue().isWaitForReady()).isTrue();
    verify(mockStream).start(streamListenerCaptor.capture());
    // Clean up as much as possible to allow the channel to terminate.
    shutdownSafely(helper, subchannel);
    timer.forwardNanos(TimeUnit.SECONDS.toNanos(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS));
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) ClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) Helper(io.grpc.LoadBalancer.Helper) ClientInterceptor(io.grpc.ClientInterceptor) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) ChannelLogger(io.grpc.ChannelLogger) ProxiedSocketAddress(io.grpc.ProxiedSocketAddress) SocketAddress(java.net.SocketAddress) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) Test(org.junit.Test)

Example 18 with ClientInterceptor

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

the class ManagedChannelImplTest method binaryLogInstalled.

@Test
public void binaryLogInstalled() throws Exception {
    final SettableFuture<Boolean> intercepted = SettableFuture.create();
    channelBuilder.binlog = new BinaryLog() {

        @Override
        public void close() throws IOException {
        // noop
        }

        @Override
        public <ReqT, RespT> ServerMethodDefinition<?, ?> wrapMethodDefinition(ServerMethodDefinition<ReqT, RespT> oMethodDef) {
            return oMethodDef;
        }

        @Override
        public Channel wrapChannel(Channel channel) {
            return ClientInterceptors.intercept(channel, new ClientInterceptor() {

                @Override
                public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
                    intercepted.set(true);
                    return next.newCall(method, callOptions);
                }
            });
        }
    };
    createChannel();
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, new Metadata());
    assertTrue(intercepted.get());
}
Also used : ManagedChannel(io.grpc.ManagedChannel) Channel(io.grpc.Channel) Metadata(io.grpc.Metadata) IOException(java.io.IOException) CallOptions(io.grpc.CallOptions) MethodDescriptor(io.grpc.MethodDescriptor) BinaryLog(io.grpc.BinaryLog) ServerMethodDefinition(io.grpc.ServerMethodDefinition) ClientInterceptor(io.grpc.ClientInterceptor) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.junit.Test)

Example 19 with ClientInterceptor

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

the class FaultFilter method buildClientInterceptor.

@Nullable
@Override
public ClientInterceptor buildClientInterceptor(FilterConfig config, @Nullable FilterConfig overrideConfig, PickSubchannelArgs args, final ScheduledExecutorService scheduler) {
    checkNotNull(config, "config");
    if (overrideConfig != null) {
        config = overrideConfig;
    }
    FaultConfig faultConfig = (FaultConfig) config;
    Long delayNanos = null;
    Status abortStatus = null;
    if (faultConfig.maxActiveFaults() == null || activeFaultCounter.get() < faultConfig.maxActiveFaults()) {
        Metadata headers = args.getHeaders();
        if (faultConfig.faultDelay() != null) {
            delayNanos = determineFaultDelayNanos(faultConfig.faultDelay(), headers);
        }
        if (faultConfig.faultAbort() != null) {
            abortStatus = determineFaultAbortStatus(faultConfig.faultAbort(), headers);
        }
    }
    if (delayNanos == null && abortStatus == null) {
        return null;
    }
    final Long finalDelayNanos = delayNanos;
    final Status finalAbortStatus = getAbortStatusWithDescription(abortStatus);
    final class FaultInjectionInterceptor implements ClientInterceptor {

        @Override
        public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(final MethodDescriptor<ReqT, RespT> method, final CallOptions callOptions, final Channel next) {
            Executor callExecutor = callOptions.getExecutor();
            if (callExecutor == null) {
                // This should never happen in practice because
                // ManagedChannelImpl.ConfigSelectingClientCall always provides CallOptions with
                // a callExecutor.
                // TODO(https://github.com/grpc/grpc-java/issues/7868)
                callExecutor = MoreExecutors.directExecutor();
            }
            if (finalDelayNanos != null) {
                Supplier<? extends ClientCall<ReqT, RespT>> callSupplier;
                if (finalAbortStatus != null) {
                    callSupplier = Suppliers.ofInstance(new FailingClientCall<ReqT, RespT>(finalAbortStatus, callExecutor));
                } else {
                    callSupplier = new Supplier<ClientCall<ReqT, RespT>>() {

                        @Override
                        public ClientCall<ReqT, RespT> get() {
                            return next.newCall(method, callOptions);
                        }
                    };
                }
                final DelayInjectedCall<ReqT, RespT> delayInjectedCall = new DelayInjectedCall<>(finalDelayNanos, callExecutor, scheduler, callOptions.getDeadline(), callSupplier);
                final class DeadlineInsightForwardingCall extends ForwardingClientCall<ReqT, RespT> {

                    @Override
                    protected ClientCall<ReqT, RespT> delegate() {
                        return delayInjectedCall;
                    }

                    @Override
                    public void start(Listener<RespT> listener, Metadata headers) {
                        Listener<RespT> finalListener = new SimpleForwardingClientCallListener<RespT>(listener) {

                            @Override
                            public void onClose(Status status, Metadata trailers) {
                                if (status.getCode().equals(Code.DEADLINE_EXCEEDED)) {
                                    // TODO(zdapeng:) check effective deadline locally, and
                                    // do the following only if the local deadline is exceeded.
                                    // (If the server sends DEADLINE_EXCEEDED for its own deadline, then the
                                    // injected delay does not contribute to the error, because the request is
                                    // only sent out after the delay. There could be a race between local and
                                    // remote, but it is rather rare.)
                                    String description = String.format("Deadline exceeded after up to %d ns of fault-injected delay", finalDelayNanos);
                                    if (status.getDescription() != null) {
                                        description = description + ": " + status.getDescription();
                                    }
                                    status = Status.DEADLINE_EXCEEDED.withDescription(description).withCause(status.getCause());
                                    // Replace trailers to prevent mixing sources of status and trailers.
                                    trailers = new Metadata();
                                }
                                delegate().onClose(status, trailers);
                            }
                        };
                        delegate().start(finalListener, headers);
                    }
                }
                return new DeadlineInsightForwardingCall();
            } else {
                return new FailingClientCall<>(finalAbortStatus, callExecutor);
            }
        }
    }
    return new FaultInjectionInterceptor();
}
Also used : SimpleForwardingClientCallListener(io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener) ForwardingClientCall(io.grpc.ForwardingClientCall) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) Executor(java.util.concurrent.Executor) DelayedClientCall(io.grpc.internal.DelayedClientCall) ClientCall(io.grpc.ClientCall) ForwardingClientCall(io.grpc.ForwardingClientCall) ClientInterceptor(io.grpc.ClientInterceptor) Status(io.grpc.Status) Channel(io.grpc.Channel) MethodDescriptor(io.grpc.MethodDescriptor) AtomicLong(java.util.concurrent.atomic.AtomicLong) SimpleForwardingClientCallListener(io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener) Nullable(javax.annotation.Nullable)

Example 20 with ClientInterceptor

use of io.grpc.ClientInterceptor in project jetcd by coreos.

the class ClientConnectionManagerTest method testHeaders.

@Test
public void testHeaders() throws InterruptedException, ExecutionException {
    final CountDownLatch latch = new CountDownLatch(1);
    final ClientBuilder builder = TestUtil.client(cluster).header("MyHeader1", "MyHeaderVal1").header("MyHeader2", "MyHeaderVal2").interceptor(new ClientInterceptor() {

        @Override
        public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
            return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {

                @Override
                public void start(Listener<RespT> responseListener, Metadata headers) {
                    super.start(responseListener, headers);
                    assertThat(headers.get(Metadata.Key.of("MyHeader1", Metadata.ASCII_STRING_MARSHALLER))).isEqualTo("MyHeaderVal1");
                    assertThat(headers.get(Metadata.Key.of("MyHeader2", Metadata.ASCII_STRING_MARSHALLER))).isEqualTo("MyHeaderVal2");
                    latch.countDown();
                }
            };
        }
    });
    try (Client client = builder.build()) {
        CompletableFuture<PutResponse> future = client.getKVClient().put(bytesOf("sample_key"), bytesOf("sample_key"));
        latch.await(1, TimeUnit.MINUTES);
        future.get();
    }
}
Also used : Channel(io.grpc.Channel) ForwardingClientCall(io.grpc.ForwardingClientCall) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) CountDownLatch(java.util.concurrent.CountDownLatch) PutResponse(io.etcd.jetcd.kv.PutResponse) ClientCall(io.grpc.ClientCall) ForwardingClientCall(io.grpc.ForwardingClientCall) ClientInterceptor(io.grpc.ClientInterceptor) Client(io.etcd.jetcd.Client) ClientBuilder(io.etcd.jetcd.ClientBuilder) Test(org.junit.jupiter.api.Test)

Aggregations

ClientInterceptor (io.grpc.ClientInterceptor)34 CallOptions (io.grpc.CallOptions)23 Metadata (io.grpc.Metadata)22 Channel (io.grpc.Channel)18 MethodDescriptor (io.grpc.MethodDescriptor)15 ManagedChannel (io.grpc.ManagedChannel)14 Test (org.junit.Test)13 ClientCall (io.grpc.ClientCall)11 SimpleForwardingClientCall (io.grpc.ForwardingClientCall.SimpleForwardingClientCall)8 ChannelFactoryBuilder (com.navercorp.pinpoint.grpc.client.ChannelFactoryBuilder)5 DefaultChannelFactoryBuilder (com.navercorp.pinpoint.grpc.client.DefaultChannelFactoryBuilder)5 UnaryCallDeadlineInterceptor (com.navercorp.pinpoint.grpc.client.UnaryCallDeadlineInterceptor)5 ClientOption (com.navercorp.pinpoint.grpc.client.config.ClientOption)5 Status (io.grpc.Status)5 SslOption (com.navercorp.pinpoint.grpc.client.config.SslOption)4 ForwardingClientCall (io.grpc.ForwardingClientCall)4 SimpleForwardingClientCallListener (io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener)4 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)4 SocketAddress (java.net.SocketAddress)4 AtomicLong (java.util.concurrent.atomic.AtomicLong)4