Search in sources :

Example 6 with ResolvedAddresses

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

the class HealthCheckingLoadBalancerFactoryTest method serviceConfigHasNoHealthCheckingInitiallyButDoesLater.

@Test
public void serviceConfigHasNoHealthCheckingInitiallyButDoesLater() {
    // No service config, thus no health check.
    ResolvedAddresses result1 = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(Attributes.EMPTY).build();
    hcLbEventDelivery.handleResolvedAddresses(result1);
    verify(origLb).handleResolvedAddresses(result1);
    verifyNoMoreInteractions(origLb);
    // First, create Subchannels 0
    createSubchannel(0, Attributes.EMPTY);
    // No health check activity.  Underlying Subchannel states are directly propagated
    deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
    assertThat(healthImpls[0].calls).isEmpty();
    verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));
    verifyNoMoreInteractions(mockStateListeners[0]);
    // Service config enables health check
    Attributes resolutionAttrs = attrsWithHealthCheckService("FooService");
    ResolvedAddresses result2 = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(resolutionAttrs).build();
    hcLbEventDelivery.handleResolvedAddresses(result2);
    verify(origLb).handleResolvedAddresses(result2);
    // Health check started on existing Subchannel
    assertThat(healthImpls[0].calls).hasSize(1);
    // State stays in READY, instead of switching to CONNECTING.
    verifyNoMoreInteractions(mockStateListeners[0]);
    // Start Subchannel 1, which will have health check
    createSubchannel(1, Attributes.EMPTY);
    assertThat(healthImpls[1].calls).isEmpty();
    deliverSubchannelState(1, ConnectivityStateInfo.forNonError(READY));
    assertThat(healthImpls[1].calls).hasSize(1);
}
Also used : Attributes(io.grpc.Attributes) ResolvedAddresses(io.grpc.LoadBalancer.ResolvedAddresses) Test(org.junit.Test)

Example 7 with ResolvedAddresses

use of io.grpc.LoadBalancer.ResolvedAddresses 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 8 with ResolvedAddresses

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

the class HealthCheckingLoadBalancerFactoryTest method backoffRetriesWhenServerErroneouslyClosesRpcBeforeAnyResponse.

@Test
public void backoffRetriesWhenServerErroneouslyClosesRpcBeforeAnyResponse() {
    Attributes resolutionAttrs = attrsWithHealthCheckService("TeeService");
    ResolvedAddresses result = ResolvedAddresses.newBuilder().setAddresses(resolvedAddressList).setAttributes(resolutionAttrs).build();
    hcLbEventDelivery.handleResolvedAddresses(result);
    verify(origLb).handleResolvedAddresses(result);
    verifyNoMoreInteractions(origLb);
    FakeSubchannel subchannel = unwrap(createSubchannel(0, Attributes.EMPTY));
    assertThat(subchannel).isSameInstanceAs(subchannels[0]);
    SubchannelStateListener mockListener = mockStateListeners[0];
    InOrder inOrder = inOrder(mockListener, backoffPolicyProvider, backoffPolicy1, backoffPolicy2);
    deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
    inOrder.verify(mockListener).onSubchannelState(eq(ConnectivityStateInfo.forNonError(CONNECTING)));
    HealthImpl healthImpl = healthImpls[0];
    assertThat(healthImpl.calls).hasSize(1);
    assertThat(clock.getPendingTasks()).isEmpty();
    subchannel.logs.clear();
    // Server closes the health checking RPC without any response
    healthImpl.calls.poll().responseObserver.onCompleted();
    // which results in TRANSIENT_FAILURE
    inOrder.verify(mockListener).onSubchannelState(unavailableStateWithMsg("Health-check stream unexpectedly closed with " + Status.OK + " for 'TeeService'"));
    assertThat(subchannel.logs).containsExactly("INFO: TRANSIENT_FAILURE: health-check stream closed with " + Status.OK, "DEBUG: Will retry health-check after 11 ns").inOrder();
    // Retry with backoff is scheduled
    inOrder.verify(backoffPolicyProvider).get();
    inOrder.verify(backoffPolicy1).nextBackoffNanos();
    assertThat(clock.getPendingTasks()).hasSize(1);
    verifyRetryAfterNanos(inOrder, mockListener, healthImpl, 11);
    assertThat(clock.getPendingTasks()).isEmpty();
    subchannel.logs.clear();
    // Server closes the health checking RPC without any response
    healthImpl.calls.poll().responseObserver.onError(Status.CANCELLED.asException());
    // which also results in TRANSIENT_FAILURE, with a different description
    inOrder.verify(mockListener).onSubchannelState(unavailableStateWithMsg("Health-check stream unexpectedly closed with " + Status.CANCELLED + " for 'TeeService'"));
    assertThat(subchannel.logs).containsExactly("INFO: TRANSIENT_FAILURE: health-check stream closed with " + Status.CANCELLED, "DEBUG: Will retry health-check after 21 ns").inOrder();
    // Retry with backoff
    inOrder.verify(backoffPolicy1).nextBackoffNanos();
    verifyRetryAfterNanos(inOrder, mockListener, healthImpl, 21);
    // Server responds this time
    healthImpl.calls.poll().responseObserver.onNext(makeResponse(ServingStatus.SERVING));
    inOrder.verify(mockListener).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));
    verifyNoMoreInteractions(origLb, mockListener, backoffPolicyProvider, backoffPolicy1);
}
Also used : SubchannelStateListener(io.grpc.LoadBalancer.SubchannelStateListener) InOrder(org.mockito.InOrder) Attributes(io.grpc.Attributes) ResolvedAddresses(io.grpc.LoadBalancer.ResolvedAddresses) Test(org.junit.Test)

Example 9 with ResolvedAddresses

use of io.grpc.LoadBalancer.ResolvedAddresses 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 10 with ResolvedAddresses

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

the class HealthCheckingLoadBalancerFactoryTest method setup.

@Before
@SuppressWarnings("unchecked")
public void setup() throws Exception {
    MockitoAnnotations.initMocks(this);
    for (int i = 0; i < NUM_SUBCHANNELS; i++) {
        HealthImpl healthImpl = new HealthImpl();
        healthImpls[i] = healthImpl;
        Server server = InProcessServerBuilder.forName("health-check-test-" + i).addService(healthImpl).directExecutor().build().start();
        servers[i] = server;
        ManagedChannel channel = InProcessChannelBuilder.forName("health-check-test-" + i).directExecutor().build();
        channels[i] = channel;
        EquivalentAddressGroup eag = new EquivalentAddressGroup(new FakeSocketAddress("address-" + i));
        eags[i] = eag;
        List<EquivalentAddressGroup> eagList = Arrays.asList(eag);
        eagLists[i] = eagList;
        mockStateListeners[i] = mock(SubchannelStateListener.class);
    }
    resolvedAddressList = Arrays.asList(eags);
    when(backoffPolicyProvider.get()).thenReturn(backoffPolicy1, backoffPolicy2);
    when(backoffPolicy1.nextBackoffNanos()).thenReturn(11L, 21L, 31L);
    when(backoffPolicy2.nextBackoffNanos()).thenReturn(12L, 22L, 32L);
    hcLbFactory = new HealthCheckingLoadBalancerFactory(origLbFactory, backoffPolicyProvider, clock.getStopwatchSupplier());
    hcLb = hcLbFactory.newLoadBalancer(origHelper);
    // Make sure all calls into the hcLb is from the syncContext
    hcLbEventDelivery = new LoadBalancer() {

        // Per LoadBalancer API, no more callbacks will be called after shutdown() is called.
        boolean shutdown;

        @Override
        public void handleResolvedAddresses(final ResolvedAddresses resolvedAddresses) {
            syncContext.execute(new Runnable() {

                @Override
                public void run() {
                    if (!shutdown) {
                        hcLb.handleResolvedAddresses(resolvedAddresses);
                    }
                }
            });
        }

        @Override
        public void handleNameResolutionError(Status error) {
            throw new AssertionError("Not supposed to be called");
        }

        @Override
        public void shutdown() {
            syncContext.execute(new Runnable() {

                @Override
                public void run() {
                    if (!shutdown) {
                        shutdown = true;
                        hcLb.shutdown();
                    }
                }
            });
        }
    };
    verify(origLbFactory).newLoadBalancer(any(Helper.class));
}
Also used : Status(io.grpc.Status) ServingStatus(io.grpc.health.v1.HealthCheckResponse.ServingStatus) SubchannelStateListener(io.grpc.LoadBalancer.SubchannelStateListener) Server(io.grpc.Server) LoadBalancer(io.grpc.LoadBalancer) Helper(io.grpc.LoadBalancer.Helper) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) ManagedChannel(io.grpc.ManagedChannel) ResolvedAddresses(io.grpc.LoadBalancer.ResolvedAddresses) Before(org.junit.Before)

Aggregations

ResolvedAddresses (io.grpc.LoadBalancer.ResolvedAddresses)32 Test (org.junit.Test)31 Attributes (io.grpc.Attributes)16 Status (io.grpc.Status)12 InOrder (org.mockito.InOrder)10 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)9 Subchannel (io.grpc.LoadBalancer.Subchannel)9 UnsupportedClientTransportFactoryBuilder (io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder)9 Helper (io.grpc.LoadBalancer.Helper)8 SubchannelStateListener (io.grpc.LoadBalancer.SubchannelStateListener)8 LoadBalancer (io.grpc.LoadBalancer)4 ConfigOrError (io.grpc.NameResolver.ConfigOrError)3 AutoConfiguredLoadBalancer (io.grpc.internal.AutoConfiguredLoadBalancerFactory.AutoConfiguredLoadBalancer)3 PolicySelection (io.grpc.internal.ServiceConfigUtil.PolicySelection)3 ForwardingLoadBalancerHelper (io.grpc.util.ForwardingLoadBalancerHelper)3 InetSocketAddress (java.net.InetSocketAddress)3 ConnectivityStateInfo (io.grpc.ConnectivityStateInfo)2 InternalConfigSelector (io.grpc.InternalConfigSelector)2 ServingStatus (io.grpc.health.v1.HealthCheckResponse.ServingStatus)2 SocketAddress (java.net.SocketAddress)2