Search in sources :

Example 46 with Subchannel

use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.

the class HealthCheckingLoadBalancerFactoryTest method serviceConfigChangesServiceNameWhenRpcInactive.

@Test
public void serviceConfigChangesServiceNameWhenRpcInactive() {
    Attributes resolutionAttrs = attrsWithHealthCheckService("TeeService");
    ResolvedAddresses result1 = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(resolutionAttrs).build();
    hcLbEventDelivery.handleResolvedAddresses(result1);
    verify(origLb).handleResolvedAddresses(result1);
    verifyNoMoreInteractions(origLb);
    Subchannel subchannel = createSubchannel(0, Attributes.EMPTY);
    SubchannelStateListener mockListener = mockStateListeners[0];
    assertThat(unwrap(subchannel)).isSameInstanceAs(subchannels[0]);
    InOrder inOrder = inOrder(origLb, mockListener);
    HealthImpl healthImpl = healthImpls[0];
    // Underlying subchannel is not READY initially
    ConnectivityStateInfo underlyingErrorState = ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("connection refused"));
    deliverSubchannelState(0, underlyingErrorState);
    inOrder.verify(mockListener).onSubchannelState(same(underlyingErrorState));
    inOrder.verifyNoMoreInteractions();
    // Service config returns with the same health check name.
    hcLbEventDelivery.handleResolvedAddresses(result1);
    // It's delivered to origLb, but nothing else happens
    inOrder.verify(origLb).handleResolvedAddresses(result1);
    assertThat(healthImpl.calls).isEmpty();
    verifyNoMoreInteractions(origLb);
    // Service config returns a different health check name.
    resolutionAttrs = attrsWithHealthCheckService("FooService");
    ResolvedAddresses result2 = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(resolutionAttrs).build();
    hcLbEventDelivery.handleResolvedAddresses(result2);
    inOrder.verify(origLb).handleResolvedAddresses(result2);
    // Underlying subchannel is now ready
    deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
    // Concluded CONNECTING state
    inOrder.verify(mockListener).onSubchannelState(eq(ConnectivityStateInfo.forNonError(CONNECTING)));
    // Health check RPC is started
    assertThat(healthImpl.calls).hasSize(1);
    // with the new service name
    assertThat(healthImpl.calls.poll().request).isEqualTo(makeRequest("FooService"));
    verifyNoMoreInteractions(origLb, mockListener);
}
Also used : SubchannelStateListener(io.grpc.LoadBalancer.SubchannelStateListener) InOrder(org.mockito.InOrder) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) Subchannel(io.grpc.LoadBalancer.Subchannel) Attributes(io.grpc.Attributes) ResolvedAddresses(io.grpc.LoadBalancer.ResolvedAddresses) Test(org.junit.Test)

Example 47 with Subchannel

use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.

the class HealthCheckingLoadBalancerFactoryTest method serviceConfigDisablesHealthCheckWhenRpcInactive.

@Test
public void serviceConfigDisablesHealthCheckWhenRpcInactive() {
    Attributes resolutionAttrs = attrsWithHealthCheckService("TeeService");
    ResolvedAddresses result1 = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(resolutionAttrs).build();
    hcLbEventDelivery.handleResolvedAddresses(result1);
    verify(origLb).handleResolvedAddresses(result1);
    verifyNoMoreInteractions(origLb);
    Subchannel subchannel = createSubchannel(0, Attributes.EMPTY);
    assertThat(unwrap(subchannel)).isSameInstanceAs(subchannels[0]);
    InOrder inOrder = inOrder(origLb, mockStateListeners[0]);
    // Underlying subchannel is not READY initially
    ConnectivityStateInfo underlyingErrorState = ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("connection refused"));
    deliverSubchannelState(0, underlyingErrorState);
    inOrder.verify(mockStateListeners[0]).onSubchannelState(same(underlyingErrorState));
    inOrder.verifyNoMoreInteractions();
    // NameResolver gives an update without service config, thus health check will be disabled
    ResolvedAddresses result2 = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(Attributes.EMPTY).build();
    hcLbEventDelivery.handleResolvedAddresses(result2);
    inOrder.verify(origLb).handleResolvedAddresses(result2);
    // Underlying subchannel is now ready
    deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
    // Since health check is disabled, READY state is propagated directly.
    inOrder.verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));
    // and there is no health check activity.
    assertThat(healthImpls[0].calls).isEmpty();
    verifyNoMoreInteractions(origLb, mockStateListeners[0]);
}
Also used : InOrder(org.mockito.InOrder) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) Subchannel(io.grpc.LoadBalancer.Subchannel) Attributes(io.grpc.Attributes) ResolvedAddresses(io.grpc.LoadBalancer.ResolvedAddresses) Test(org.junit.Test)

Example 48 with Subchannel

use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.

the class HealthCheckingLoadBalancerFactoryTest method balancerShutdown.

@Test
public void balancerShutdown() {
    Attributes resolutionAttrs = attrsWithHealthCheckService("TeeService");
    ResolvedAddresses result = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(resolutionAttrs).build();
    hcLbEventDelivery.handleResolvedAddresses(result);
    verify(origLb).handleResolvedAddresses(result);
    verifyNoMoreInteractions(origLb);
    ServerSideCall[] serverCalls = new ServerSideCall[NUM_SUBCHANNELS];
    final Subchannel[] wrappedSubchannels = new Subchannel[NUM_SUBCHANNELS];
    for (int i = 0; i < NUM_SUBCHANNELS; i++) {
        Subchannel subchannel = createSubchannel(i, Attributes.EMPTY);
        wrappedSubchannels[i] = subchannel;
        SubchannelStateListener mockListener = mockStateListeners[i];
        assertThat(unwrap(subchannel)).isSameInstanceAs(subchannels[i]);
        // Trigger the health check
        deliverSubchannelState(i, ConnectivityStateInfo.forNonError(READY));
        HealthImpl healthImpl = healthImpls[i];
        assertThat(healthImpl.calls).hasSize(1);
        serverCalls[i] = healthImpl.calls.poll();
        assertThat(serverCalls[i].cancelled).isFalse();
        verify(mockListener).onSubchannelState(eq(ConnectivityStateInfo.forNonError(CONNECTING)));
    }
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) {
            for (int i = 0; i < NUM_SUBCHANNELS; i++) {
                wrappedSubchannels[i].shutdown();
            }
            return null;
        }
    }).when(origLb).shutdown();
    // Shut down the balancer
    hcLbEventDelivery.shutdown();
    verify(origLb).shutdown();
    // Health check stream should be cancelled
    for (int i = 0; i < NUM_SUBCHANNELS; i++) {
        assertThat(serverCalls[i].cancelled).isTrue();
        verifyNoMoreInteractions(origLb);
        verify(mockStateListeners[i]).onSubchannelState(ConnectivityStateInfo.forNonError(SHUTDOWN));
        // No more health check call is made or scheduled
        assertThat(healthImpls[i].calls).isEmpty();
    }
    assertThat(clock.getPendingTasks()).isEmpty();
}
Also used : SubchannelStateListener(io.grpc.LoadBalancer.SubchannelStateListener) Attributes(io.grpc.Attributes) Subchannel(io.grpc.LoadBalancer.Subchannel) InvocationOnMock(org.mockito.invocation.InvocationOnMock) ResolvedAddresses(io.grpc.LoadBalancer.ResolvedAddresses) Test(org.junit.Test)

Example 49 with Subchannel

use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.

the class HealthCheckingLoadBalancerFactoryTest method serviceConfigDisablesHealthCheckWhenRetryPending.

@Test
public void serviceConfigDisablesHealthCheckWhenRetryPending() {
    Attributes resolutionAttrs = attrsWithHealthCheckService("TeeService");
    ResolvedAddresses result = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(resolutionAttrs).build();
    hcLbEventDelivery.handleResolvedAddresses(result);
    verify(origLb).handleResolvedAddresses(result);
    verifyNoMoreInteractions(origLb);
    Subchannel subchannel = createSubchannel(0, Attributes.EMPTY);
    assertThat(unwrap(subchannel)).isSameInstanceAs(subchannels[0]);
    InOrder inOrder = inOrder(origLb, mockStateListeners[0]);
    deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
    inOrder.verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(CONNECTING)));
    inOrder.verifyNoMoreInteractions();
    HealthImpl healthImpl = healthImpls[0];
    assertThat(healthImpl.calls).hasSize(1);
    // Server closes the stream without responding.  Client in retry backoff
    assertThat(clock.getPendingTasks()).isEmpty();
    healthImpl.calls.poll().responseObserver.onCompleted();
    assertThat(clock.getPendingTasks()).hasSize(1);
    inOrder.verify(mockStateListeners[0]).onSubchannelState(unavailableStateWithMsg("Health-check stream unexpectedly closed with " + Status.OK + " for 'TeeService'"));
    // NameResolver gives an update without service config, thus health check will be disabled
    ResolvedAddresses result2 = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(Attributes.EMPTY).build();
    hcLbEventDelivery.handleResolvedAddresses(result2);
    // Retry timer is cancelled
    assertThat(clock.getPendingTasks()).isEmpty();
    // No retry was attempted
    assertThat(healthImpl.calls).isEmpty();
    // Subchannel uses original state
    inOrder.verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));
    inOrder.verify(origLb).handleResolvedAddresses(result2);
    verifyNoMoreInteractions(origLb, mockStateListeners[0]);
}
Also used : InOrder(org.mockito.InOrder) Subchannel(io.grpc.LoadBalancer.Subchannel) Attributes(io.grpc.Attributes) ResolvedAddresses(io.grpc.LoadBalancer.ResolvedAddresses) Test(org.junit.Test)

Example 50 with Subchannel

use of io.grpc.LoadBalancer.Subchannel 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)

Aggregations

Subchannel (io.grpc.LoadBalancer.Subchannel)125 Test (org.junit.Test)108 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)54 InOrder (org.mockito.InOrder)43 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)42 Metadata (io.grpc.Metadata)40 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)35 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)33 ForwardingSubchannel (io.grpc.util.ForwardingSubchannel)32 MockClientTransportInfo (io.grpc.internal.TestUtils.MockClientTransportInfo)30 Attributes (io.grpc.Attributes)26 ConnectivityStateInfo (io.grpc.ConnectivityStateInfo)25 ClientStreamTracer (io.grpc.ClientStreamTracer)24 Status (io.grpc.Status)23 PickResult (io.grpc.LoadBalancer.PickResult)19 CallOptions (io.grpc.CallOptions)18 ConnectivityState (io.grpc.ConnectivityState)18 Helper (io.grpc.LoadBalancer.Helper)18 SocketAddress (java.net.SocketAddress)18 ChannelLogger (io.grpc.ChannelLogger)14