Search in sources :

Example 26 with ClientStreamTracer

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

the class ManagedChannelImplTest method informationPropagatedToNewStreamAndCallCredentials.

/**
 * Test that information such as the Call's context, MethodDescriptor, authority, executor are
 * propagated to newStream() and applyRequestMetadata().
 */
@Test
public void informationPropagatedToNewStreamAndCallCredentials() {
    createChannel();
    CallOptions callOptions = CallOptions.DEFAULT.withCallCredentials(creds);
    final Context.Key<String> testKey = Context.key("testing");
    Context ctx = Context.current().withValue(testKey, "testValue");
    final LinkedList<Context> credsApplyContexts = new LinkedList<>();
    final LinkedList<Context> newStreamContexts = new LinkedList<>();
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock in) throws Throwable {
            credsApplyContexts.add(Context.current());
            return null;
        }
    }).when(creds).applyRequestMetadata(any(RequestInfo.class), any(Executor.class), any(CallCredentials.MetadataApplier.class));
    // First call will be on delayed transport.  Only newCall() is run within the expected context,
    // so that we can verify that the context is explicitly attached before calling newStream() and
    // applyRequestMetadata(), which happens after we detach the context from the thread.
    Context origCtx = ctx.attach();
    assertEquals("testValue", testKey.get());
    ClientCall<String, Integer> call = channel.newCall(method, callOptions);
    ctx.detach(origCtx);
    assertNull(testKey.get());
    call.start(mockCallListener, new Metadata());
    // Simulate name resolution results
    EquivalentAddressGroup addressGroup = new EquivalentAddressGroup(socketAddress);
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    requestConnectionSafely(helper, subchannel);
    verify(mockTransportFactory).newClientTransport(same(socketAddress), eq(clientTransportOptions), any(ChannelLogger.class));
    MockClientTransportInfo transportInfo = transports.poll();
    final ConnectionClientTransport transport = transportInfo.transport;
    when(transport.getAttributes()).thenReturn(Attributes.EMPTY);
    doAnswer(new Answer<ClientStream>() {

        @Override
        public ClientStream answer(InvocationOnMock in) throws Throwable {
            newStreamContexts.add(Context.current());
            return mock(ClientStream.class);
        }
    }).when(transport).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
    verify(creds, never()).applyRequestMetadata(any(RequestInfo.class), any(Executor.class), any(CallCredentials.MetadataApplier.class));
    // applyRequestMetadata() is called after the transport becomes ready.
    transportInfo.listener.transportReady();
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    updateBalancingStateSafely(helper, READY, mockPicker);
    executor.runDueTasks();
    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
    ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
    verify(creds).applyRequestMetadata(infoCaptor.capture(), same(executor.getScheduledExecutorService()), applierCaptor.capture());
    assertEquals("testValue", testKey.get(credsApplyContexts.poll()));
    assertEquals(AUTHORITY, infoCaptor.getValue().getAuthority());
    assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel());
    verify(transport, never()).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
    // newStream() is called after apply() is called
    applierCaptor.getValue().apply(new Metadata());
    verify(transport).newStream(same(method), any(Metadata.class), same(callOptions), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertEquals("testValue", testKey.get(newStreamContexts.poll()));
    // The context should not live beyond the scope of newStream() and applyRequestMetadata()
    assertNull(testKey.get());
    // Second call will not be on delayed transport
    origCtx = ctx.attach();
    call = channel.newCall(method, callOptions);
    ctx.detach(origCtx);
    call.start(mockCallListener, new Metadata());
    verify(creds, times(2)).applyRequestMetadata(infoCaptor.capture(), same(executor.getScheduledExecutorService()), applierCaptor.capture());
    assertEquals("testValue", testKey.get(credsApplyContexts.poll()));
    assertEquals(AUTHORITY, infoCaptor.getValue().getAuthority());
    assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel());
    // This is from the first call
    verify(transport).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
    // Still, newStream() is called after apply() is called
    applierCaptor.getValue().apply(new Metadata());
    verify(transport, times(2)).newStream(same(method), any(Metadata.class), same(callOptions), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertEquals("testValue", testKey.get(newStreamContexts.poll()));
    assertNull(testKey.get());
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) RequestInfo(io.grpc.CallCredentials.RequestInfo) Executor(java.util.concurrent.Executor) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) ChannelLogger(io.grpc.ChannelLogger) Context(io.grpc.Context) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) MethodDescriptor(io.grpc.MethodDescriptor) LinkedList(java.util.LinkedList) InvocationOnMock(org.mockito.invocation.InvocationOnMock) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) Test(org.junit.Test)

Example 27 with ClientStreamTracer

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

the class ManagedChannelImplTest method updateBalancingState_withWrappedSubchannel.

@Test
public void updateBalancingState_withWrappedSubchannel() {
    ClientStream mockStream = mock(ClientStream.class);
    createChannel();
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, new Metadata());
    final Subchannel subchannel1 = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    requestConnectionSafely(helper, subchannel1);
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ManagedClientTransport.Listener transportListener = transportInfo.listener;
    when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
    transportListener.transportReady();
    Subchannel wrappedSubchannel1 = new ForwardingSubchannel() {

        @Override
        protected Subchannel delegate() {
            return subchannel1;
        }
    };
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(wrappedSubchannel1));
    updateBalancingStateSafely(helper, READY, mockPicker);
    executor.runDueTasks();
    verify(mockTransport).newStream(same(method), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
    verify(mockStream).start(any(ClientStreamListener.class));
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 28 with ClientStreamTracer

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

the class ManagedChannelImplTest method oobchannels.

@Test
public void oobchannels() {
    createChannel();
    ManagedChannel oob1 = helper.createOobChannel(Collections.singletonList(addressGroup), "oob1authority");
    ManagedChannel oob2 = helper.createOobChannel(Collections.singletonList(addressGroup), "oob2authority");
    verify(balancerRpcExecutorPool, times(2)).getObject();
    assertEquals("oob1authority", oob1.authority());
    assertEquals("oob2authority", oob2.authority());
    // OOB channels create connections lazily.  A new call will initiate the connection.
    Metadata headers = new Metadata();
    ClientCall<String, Integer> call = oob1.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, headers);
    verify(mockTransportFactory).newClientTransport(eq(socketAddress), eq(new ClientTransportOptions().setAuthority("oob1authority").setUserAgent(USER_AGENT)), isA(ChannelLogger.class));
    MockClientTransportInfo transportInfo = transports.poll();
    assertNotNull(transportInfo);
    assertEquals(0, balancerRpcExecutor.numPendingTasks());
    transportInfo.listener.transportReady();
    assertEquals(1, balancerRpcExecutor.runDueTasks());
    verify(transportInfo.transport).newStream(same(method), same(headers), same(CallOptions.DEFAULT), ArgumentMatchers.<ClientStreamTracer[]>any());
    // The transport goes away
    transportInfo.listener.transportShutdown(Status.UNAVAILABLE);
    transportInfo.listener.transportTerminated();
    // A new call will trigger a new transport
    ClientCall<String, Integer> call2 = oob1.newCall(method, CallOptions.DEFAULT);
    call2.start(mockCallListener2, headers);
    ClientCall<String, Integer> call3 = oob1.newCall(method, CallOptions.DEFAULT.withWaitForReady());
    call3.start(mockCallListener3, headers);
    verify(mockTransportFactory, times(2)).newClientTransport(eq(socketAddress), eq(new ClientTransportOptions().setAuthority("oob1authority").setUserAgent(USER_AGENT)), isA(ChannelLogger.class));
    transportInfo = transports.poll();
    assertNotNull(transportInfo);
    // This transport fails
    Status transportError = Status.UNAVAILABLE.withDescription("Connection refused");
    assertEquals(0, balancerRpcExecutor.numPendingTasks());
    transportInfo.listener.transportShutdown(transportError);
    assertTrue(balancerRpcExecutor.runDueTasks() > 0);
    // Fail-fast RPC will fail, while wait-for-ready RPC will still be pending
    verify(mockCallListener2).onClose(same(transportError), any(Metadata.class));
    verify(mockCallListener3, never()).onClose(any(Status.class), any(Metadata.class));
    // Shutdown
    assertFalse(oob1.isShutdown());
    assertFalse(oob2.isShutdown());
    oob1.shutdown();
    oob2.shutdownNow();
    assertTrue(oob1.isShutdown());
    assertTrue(oob2.isShutdown());
    assertTrue(oob2.isTerminated());
    verify(balancerRpcExecutorPool).returnObject(balancerRpcExecutor.getScheduledExecutorService());
    // New RPCs will be rejected.
    assertEquals(0, balancerRpcExecutor.numPendingTasks());
    ClientCall<String, Integer> call4 = oob1.newCall(method, CallOptions.DEFAULT);
    ClientCall<String, Integer> call5 = oob2.newCall(method, CallOptions.DEFAULT);
    call4.start(mockCallListener4, headers);
    call5.start(mockCallListener5, headers);
    assertTrue(balancerRpcExecutor.runDueTasks() > 0);
    verify(mockCallListener4).onClose(statusCaptor.capture(), any(Metadata.class));
    Status status4 = statusCaptor.getValue();
    assertEquals(Status.Code.UNAVAILABLE, status4.getCode());
    verify(mockCallListener5).onClose(statusCaptor.capture(), any(Metadata.class));
    Status status5 = statusCaptor.getValue();
    assertEquals(Status.Code.UNAVAILABLE, status5.getCode());
    // The pending RPC will still be pending
    verify(mockCallListener3, never()).onClose(any(Status.class), any(Metadata.class));
    // This will shutdownNow() the delayed transport, terminating the pending RPC
    assertEquals(0, balancerRpcExecutor.numPendingTasks());
    oob1.shutdownNow();
    assertTrue(balancerRpcExecutor.runDueTasks() > 0);
    verify(mockCallListener3).onClose(any(Status.class), any(Metadata.class));
    // Shut down the channel, and it will not terminated because OOB channel has not.
    channel.shutdown();
    assertFalse(channel.isTerminated());
    // Delayed transport has already terminated.  Terminating the transport terminates the
    // subchannel, which in turn terimates the OOB channel, which terminates the channel.
    assertFalse(oob1.isTerminated());
    verify(balancerRpcExecutorPool).returnObject(balancerRpcExecutor.getScheduledExecutorService());
    transportInfo.listener.transportTerminated();
    assertTrue(oob1.isTerminated());
    assertTrue(channel.isTerminated());
    verify(balancerRpcExecutorPool, times(2)).returnObject(balancerRpcExecutor.getScheduledExecutorService());
}
Also used : Status(io.grpc.Status) ClientStreamTracer(io.grpc.ClientStreamTracer) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) Metadata(io.grpc.Metadata) ManagedChannel(io.grpc.ManagedChannel) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) ChannelLogger(io.grpc.ChannelLogger) Test(org.junit.Test)

Example 29 with ClientStreamTracer

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

the class ManagedChannelImplTest method oobChannelHasNoChannelCallCredentials.

@Test
public void oobChannelHasNoChannelCallCredentials() {
    Metadata.Key<String> metadataKey = Metadata.Key.of("token", Metadata.ASCII_STRING_MARSHALLER);
    String channelCredValue = "channel-provided call cred";
    channelBuilder = new ManagedChannelImplBuilder(TARGET, InsecureChannelCredentials.create(), new FakeCallCredentials(metadataKey, channelCredValue), new UnsupportedClientTransportFactoryBuilder(), new FixedPortProvider(DEFAULT_PORT));
    channelBuilder.disableRetry();
    configureBuilder(channelBuilder);
    createChannel();
    // Verify that the normal channel has call creds, to validate configuration
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    requestConnectionSafely(helper, subchannel);
    MockClientTransportInfo transportInfo = transports.poll();
    assertNotNull(transportInfo);
    transportInfo.listener.transportReady();
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    updateBalancingStateSafely(helper, READY, mockPicker);
    String callCredValue = "per-RPC call cred";
    CallOptions callOptions = CallOptions.DEFAULT.withCallCredentials(new FakeCallCredentials(metadataKey, callCredValue));
    Metadata headers = new Metadata();
    ClientCall<String, Integer> call = channel.newCall(method, callOptions);
    call.start(mockCallListener, headers);
    verify(transportInfo.transport).newStream(same(method), same(headers), same(callOptions), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertThat(headers.getAll(metadataKey)).containsExactly(channelCredValue, callCredValue).inOrder();
    // Verify that the oob channel does not
    ManagedChannel oob = helper.createOobChannel(Collections.singletonList(addressGroup), "oobauthority");
    headers = new Metadata();
    call = oob.newCall(method, callOptions);
    call.start(mockCallListener2, headers);
    transportInfo = transports.poll();
    assertNotNull(transportInfo);
    transportInfo.listener.transportReady();
    balancerRpcExecutor.runDueTasks();
    verify(transportInfo.transport).newStream(same(method), same(headers), same(callOptions), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertThat(headers.getAll(metadataKey)).containsExactly(callCredValue);
    oob.shutdownNow();
    // Verify that resolving oob channel does not
    oob = helper.createResolvingOobChannelBuilder("oobauthority").nameResolverFactory(new FakeNameResolverFactory.Builder(URI.create("oobauthority")).build()).defaultLoadBalancingPolicy(MOCK_POLICY_NAME).idleTimeout(ManagedChannelImplBuilder.IDLE_MODE_MAX_TIMEOUT_DAYS, TimeUnit.DAYS).disableRetry().build();
    oob.getState(true);
    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(Helper.class);
    verify(mockLoadBalancerProvider, times(2)).newLoadBalancer(helperCaptor.capture());
    Helper oobHelper = helperCaptor.getValue();
    subchannel = createSubchannelSafely(oobHelper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    requestConnectionSafely(oobHelper, subchannel);
    transportInfo = transports.poll();
    assertNotNull(transportInfo);
    transportInfo.listener.transportReady();
    SubchannelPicker mockPicker2 = mock(SubchannelPicker.class);
    when(mockPicker2.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    updateBalancingStateSafely(oobHelper, READY, mockPicker2);
    headers = new Metadata();
    call = oob.newCall(method, callOptions);
    call.start(mockCallListener2, headers);
    // CallOptions may contain StreamTracerFactory for census that is added by default.
    verify(transportInfo.transport).newStream(same(method), same(headers), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertThat(headers.getAll(metadataKey)).containsExactly(callCredValue);
    oob.shutdownNow();
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions) Helper(io.grpc.LoadBalancer.Helper) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) FixedPortProvider(io.grpc.internal.ManagedChannelImplBuilder.FixedPortProvider) ManagedChannel(io.grpc.ManagedChannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) Test(org.junit.Test)

Example 30 with ClientStreamTracer

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

the class ManagedChannelImplTest method pickerReturnsStreamTracer_noDelay.

@Test
public void pickerReturnsStreamTracer_noDelay() {
    ClientStream mockStream = mock(ClientStream.class);
    final ClientStreamTracer tracer1 = new ClientStreamTracer() {
    };
    final ClientStreamTracer tracer2 = new ClientStreamTracer() {
    };
    ClientStreamTracer.Factory factory1 = new ClientStreamTracer.Factory() {

        @Override
        public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
            return tracer1;
        }
    };
    ClientStreamTracer.Factory factory2 = new ClientStreamTracer.Factory() {

        @Override
        public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
            return tracer2;
        }
    };
    createChannel();
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    requestConnectionSafely(helper, subchannel);
    MockClientTransportInfo transportInfo = transports.poll();
    transportInfo.listener.transportReady();
    ClientTransport mockTransport = transportInfo.transport;
    when(mockTransport.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel, factory2));
    updateBalancingStateSafely(helper, READY, mockPicker);
    CallOptions callOptions = CallOptions.DEFAULT.withStreamTracerFactory(factory1);
    ClientCall<String, Integer> call = channel.newCall(method, callOptions);
    call.start(mockCallListener, new Metadata());
    verify(mockPicker).pickSubchannel(any(PickSubchannelArgs.class));
    verify(mockTransport).newStream(same(method), any(Metadata.class), callOptionsCaptor.capture(), tracersCaptor.capture());
    assertThat(tracersCaptor.getValue()).isEqualTo(new ClientStreamTracer[] { tracer1, tracer2 });
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions) MethodDescriptor(io.grpc.MethodDescriptor) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) StreamInfo(io.grpc.ClientStreamTracer.StreamInfo) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Aggregations

ClientStreamTracer (io.grpc.ClientStreamTracer)57 Metadata (io.grpc.Metadata)54 Test (org.junit.Test)44 CallOptions (io.grpc.CallOptions)28 Subchannel (io.grpc.LoadBalancer.Subchannel)22 MockClientTransportInfo (io.grpc.internal.TestUtils.MockClientTransportInfo)21 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)19 ForwardingSubchannel (io.grpc.util.ForwardingSubchannel)18 MethodDescriptor (io.grpc.MethodDescriptor)16 Status (io.grpc.Status)14 ChannelLogger (io.grpc.ChannelLogger)11 ClientTransportOptions (io.grpc.internal.ClientTransportFactory.ClientTransportOptions)10 ProxiedSocketAddress (io.grpc.ProxiedSocketAddress)9 StreamInfo (io.grpc.ClientStreamTracer.StreamInfo)8 CallAttemptsTracerFactory (io.grpc.census.CensusTracingModule.CallAttemptsTracerFactory)8 SocketAddress (java.net.SocketAddress)8 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)7 Helper (io.grpc.LoadBalancer.Helper)7 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)7 ManagedChannel (io.grpc.ManagedChannel)7