Search in sources :

Example 1 with ServerList

use of io.grpc.lb.v1.ServerList in project grpc-java by grpc.

the class GrpclbLoadBalancerTest method subtestGrpclbFallbackConnectionLost.

// Fallback outside of the initial timeout, where all connections are lost.
private void subtestGrpclbFallbackConnectionLost(boolean balancerBroken, boolean allSubchannelsBroken) {
    long loadReportIntervalMillis = 1983;
    InOrder inOrder = inOrder(helper, mockLbService, subchannelPool);
    // Create balancer and backend addresses
    List<EquivalentAddressGroup> backendList = createResolvedBackendAddresses(2);
    List<EquivalentAddressGroup> grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList);
    inOrder.verify(helper).createOobChannel(eq(xattr(grpclbBalancerList)), eq(lbAuthority(0) + NO_USE_AUTHORITY_SUFFIX));
    // Attempted to connect to balancer
    assertEquals(1, fakeOobChannels.size());
    fakeOobChannels.poll();
    inOrder.verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
    StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
    assertEquals(1, lbRequestObservers.size());
    StreamObserver<LoadBalanceRequest> lbRequestObserver = lbRequestObservers.poll();
    verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    lbResponseObserver.onNext(buildInitialResponse(loadReportIntervalMillis));
    // We don't care if these methods have been run.
    inOrder.verify(helper, atLeast(0)).getSynchronizationContext();
    inOrder.verify(helper, atLeast(0)).getScheduledExecutorService();
    inOrder.verifyNoMoreInteractions();
    // Balancer returns a server list
    List<ServerEntry> serverList = Arrays.asList(new ServerEntry("127.0.0.1", 2000, "token0001"), new ServerEntry("127.0.0.1", 2010, "token0002"));
    lbResponseObserver.onNext(buildInitialResponse());
    lbResponseObserver.onNext(buildLbResponse(serverList));
    List<Subchannel> subchannels = fallbackTestVerifyUseOfBalancerBackendLists(inOrder, serverList);
    // Break connections
    if (balancerBroken) {
        lbResponseObserver.onError(Status.UNAVAILABLE.asException());
        // A new stream to LB is created
        inOrder.verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
        lbResponseObserver = lbResponseObserverCaptor.getValue();
        assertEquals(1, lbRequestObservers.size());
        lbRequestObserver = lbRequestObservers.poll();
        inOrder.verify(helper).refreshNameResolution();
    }
    if (allSubchannelsBroken) {
        for (Subchannel subchannel : subchannels) {
            // A READY subchannel transits to IDLE when receiving a go-away
            deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(IDLE));
            inOrder.verify(helper).refreshNameResolution();
        }
    }
    if (balancerBroken && allSubchannelsBroken) {
        // Going into fallback
        subchannels = fallbackTestVerifyUseOfFallbackBackendLists(inOrder, Arrays.asList(backendList.get(0), backendList.get(1)));
        // connections are lost
        for (Subchannel subchannel : subchannels) {
            deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(IDLE));
            inOrder.verify(helper).refreshNameResolution();
        }
        // Exit fallback mode or cancel fallback timer when receiving a new server list from balancer
        List<ServerEntry> serverList2 = Arrays.asList(new ServerEntry("127.0.0.1", 2001, "token0003"), new ServerEntry("127.0.0.1", 2011, "token0004"));
        lbResponseObserver.onNext(buildInitialResponse());
        lbResponseObserver.onNext(buildLbResponse(serverList2));
        fallbackTestVerifyUseOfBalancerBackendLists(inOrder, serverList2);
    }
    assertEquals(0, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
    // No subchannel to fallback backends should have been created if no fallback happened
    if (!(balancerBroken && allSubchannelsBroken)) {
        verify(subchannelPool, never()).takeOrCreateSubchannel(eq(backendList.get(0)), any(Attributes.class));
        verify(subchannelPool, never()).takeOrCreateSubchannel(eq(backendList.get(1)), any(Attributes.class));
    }
}
Also used : InOrder(org.mockito.InOrder) Attributes(io.grpc.Attributes) InitialLoadBalanceResponse(io.grpc.lb.v1.InitialLoadBalanceResponse) LoadBalanceResponse(io.grpc.lb.v1.LoadBalanceResponse) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalanceRequest(io.grpc.lb.v1.LoadBalanceRequest) InitialLoadBalanceRequest(io.grpc.lb.v1.InitialLoadBalanceRequest)

Example 2 with ServerList

use of io.grpc.lb.v1.ServerList in project grpc-java by grpc.

the class GrpclbLoadBalancerTest method grpclbFallback_allLost_failToFallback.

@Test
public void grpclbFallback_allLost_failToFallback() {
    long loadReportIntervalMillis = 1983;
    InOrder inOrder = inOrder(helper, mockLbService, subchannelPool);
    // Create balancer and (empty) backend addresses
    List<EquivalentAddressGroup> grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(Collections.<EquivalentAddressGroup>emptyList(), grpclbBalancerList);
    inOrder.verify(helper).createOobChannel(eq(xattr(grpclbBalancerList)), eq(lbAuthority(0) + NO_USE_AUTHORITY_SUFFIX));
    // Attempted to connect to balancer
    assertEquals(1, fakeOobChannels.size());
    fakeOobChannels.poll();
    inOrder.verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
    StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
    assertEquals(1, lbRequestObservers.size());
    StreamObserver<LoadBalanceRequest> lbRequestObserver = lbRequestObservers.poll();
    verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    lbResponseObserver.onNext(buildInitialResponse(loadReportIntervalMillis));
    // We don't care if these methods have been run.
    inOrder.verify(helper, atLeast(0)).getSynchronizationContext();
    inOrder.verify(helper, atLeast(0)).getScheduledExecutorService();
    inOrder.verifyNoMoreInteractions();
    // Balancer returns a server list
    List<ServerEntry> serverList = Arrays.asList(new ServerEntry("127.0.0.1", 2000, "token0001"), new ServerEntry("127.0.0.1", 2010, "token0002"));
    lbResponseObserver.onNext(buildInitialResponse());
    lbResponseObserver.onNext(buildLbResponse(serverList));
    List<Subchannel> subchannels = fallbackTestVerifyUseOfBalancerBackendLists(inOrder, serverList);
    // Break connections
    lbResponseObserver.onError(Status.UNAVAILABLE.asException());
    // A new stream to LB is created
    inOrder.verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
    assertEquals(1, lbRequestObservers.size());
    // Break all subchannel connections
    Status error = Status.UNAUTHENTICATED.withDescription("Permission denied");
    for (Subchannel subchannel : subchannels) {
        deliverSubchannelState(subchannel, ConnectivityStateInfo.forTransientFailure(error));
    }
    // Recycle all subchannels
    for (Subchannel subchannel : subchannels) {
        verify(subchannelPool).returnSubchannel(eq(subchannel), any(ConnectivityStateInfo.class));
    }
    // RPC error status includes errors of subchannels to balancer-provided backends
    inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
    PickResult result = pickerCaptor.getValue().pickSubchannel(mock(PickSubchannelArgs.class));
    assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
    assertThat(result.getStatus().getDescription()).startsWith(GrpclbState.NO_FALLBACK_BACKENDS_STATUS.getDescription());
    assertThat(result.getStatus().getDescription()).contains(error.getDescription());
}
Also used : Status(io.grpc.Status) InOrder(org.mockito.InOrder) InitialLoadBalanceResponse(io.grpc.lb.v1.InitialLoadBalanceResponse) LoadBalanceResponse(io.grpc.lb.v1.LoadBalanceResponse) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalanceRequest(io.grpc.lb.v1.LoadBalanceRequest) InitialLoadBalanceRequest(io.grpc.lb.v1.InitialLoadBalanceRequest) PickResult(io.grpc.LoadBalancer.PickResult) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 3 with ServerList

use of io.grpc.lb.v1.ServerList in project grpc-java by grpc.

the class GrpclbLoadBalancerTest method subtestGrpclbFallbackInitialTimeout.

// Fallback or not within the period of the initial timeout.
private void subtestGrpclbFallbackInitialTimeout(boolean timerExpires) {
    long loadReportIntervalMillis = 1983;
    InOrder inOrder = inOrder(helper, subchannelPool);
    // Create balancer and backend addresses
    List<EquivalentAddressGroup> backendList = createResolvedBackendAddresses(2);
    List<EquivalentAddressGroup> grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList);
    inOrder.verify(helper).createOobChannel(eq(xattr(grpclbBalancerList)), eq(lbAuthority(0) + NO_USE_AUTHORITY_SUFFIX));
    // Attempted to connect to balancer
    assertEquals(1, fakeOobChannels.size());
    ManagedChannel oobChannel = fakeOobChannels.poll();
    verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
    StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
    assertEquals(1, lbRequestObservers.size());
    StreamObserver<LoadBalanceRequest> lbRequestObserver = lbRequestObservers.poll();
    verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    lbResponseObserver.onNext(buildInitialResponse(loadReportIntervalMillis));
    // We don't care if these methods have been run.
    inOrder.verify(helper, atLeast(0)).getSynchronizationContext();
    inOrder.verify(helper, atLeast(0)).getScheduledExecutorService();
    inOrder.verifyNoMoreInteractions();
    assertEquals(1, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
    fakeClock.forwardTime(GrpclbState.FALLBACK_TIMEOUT_MS - 1, TimeUnit.MILLISECONDS);
    assertEquals(1, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
    // ////////////////////////////////
    if (timerExpires) {
        logs.clear();
        fakeClock.forwardTime(1, TimeUnit.MILLISECONDS);
        assertEquals(0, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
        assertThat(logs).containsExactly("INFO: [grpclb-<api.google.com>] Using fallback backends").inOrder();
        // Fall back to the backends from resolver
        fallbackTestVerifyUseOfFallbackBackendLists(inOrder, backendList);
        assertFalse(oobChannel.isShutdown());
        verify(lbRequestObserver, never()).onCompleted();
    }
    // ////////////////////////////////////////////////////////////////////
    // Name resolver sends new resolution results without any backend addr
    // ////////////////////////////////////////////////////////////////////
    grpclbBalancerList = createResolvedBalancerAddresses(2);
    deliverResolvedAddresses(Collections.<EquivalentAddressGroup>emptyList(), grpclbBalancerList);
    // New addresses are updated to the OobChannel
    inOrder.verify(helper).updateOobChannelAddresses(same(oobChannel), eq(xattr(grpclbBalancerList)));
    if (timerExpires) {
        // Still in fallback logic, except that the backend list is empty
        for (Subchannel subchannel : mockSubchannels) {
            verify(subchannelPool).returnSubchannel(eq(subchannel), any(ConnectivityStateInfo.class));
        }
        // RPC error status includes message of balancer RPC timeout
        inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
        PickResult result = pickerCaptor.getValue().pickSubchannel(mock(PickSubchannelArgs.class));
        assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
        assertThat(result.getStatus().getDescription()).startsWith(GrpclbState.NO_FALLBACK_BACKENDS_STATUS.getDescription());
        assertThat(result.getStatus().getDescription()).contains(GrpclbState.BALANCER_TIMEOUT_STATUS.getDescription());
    }
    // //////////////////////////////////////////////////////////////
    // Name resolver sends new resolution results with backend addrs
    // //////////////////////////////////////////////////////////////
    // prevents the cached subchannel to be used
    subchannelPool.clear();
    backendList = createResolvedBackendAddresses(2);
    grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList);
    // New LB address is updated to the OobChannel
    inOrder.verify(helper).updateOobChannelAddresses(same(oobChannel), eq(xattr(grpclbBalancerList)));
    if (timerExpires) {
        // New backend addresses are used for fallback
        fallbackTestVerifyUseOfFallbackBackendLists(inOrder, Arrays.asList(backendList.get(0), backendList.get(1)));
    }
    // //////////////////////////////////////////////
    if (timerExpires) {
        Status streamError = Status.UNAVAILABLE.withDescription("OOB stream broken");
        lbResponseObserver.onError(streamError.asException());
        // The error will NOT propagate to picker because fallback list is in use.
        inOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
        // A new stream is created
        verify(mockLbService, times(2)).balanceLoad(lbResponseObserverCaptor.capture());
        lbResponseObserver = lbResponseObserverCaptor.getValue();
        assertEquals(1, lbRequestObservers.size());
        lbRequestObserver = lbRequestObservers.poll();
        verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    }
    // ///////////////////////////////
    // Balancer returns a server list
    // ///////////////////////////////
    List<ServerEntry> serverList = Arrays.asList(new ServerEntry("127.0.0.1", 2000, "token0001"), new ServerEntry("127.0.0.1", 2010, "token0002"));
    lbResponseObserver.onNext(buildInitialResponse());
    lbResponseObserver.onNext(buildLbResponse(serverList));
    // Balancer-provided server list now in effect
    fallbackTestVerifyUseOfBalancerBackendLists(inOrder, serverList);
    // /////////////////////////////////////////////////////////////
    // New backend addresses from resolver outside of fallback mode
    // /////////////////////////////////////////////////////////////
    backendList = createResolvedBackendAddresses(1);
    grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList);
    // Will not affect the round robin list at all
    inOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
    // No fallback timeout timer scheduled.
    assertEquals(0, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
}
Also used : Status(io.grpc.Status) InOrder(org.mockito.InOrder) InitialLoadBalanceResponse(io.grpc.lb.v1.InitialLoadBalanceResponse) LoadBalanceResponse(io.grpc.lb.v1.LoadBalanceResponse) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) ConnectivityState(io.grpc.ConnectivityState) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalanceRequest(io.grpc.lb.v1.LoadBalanceRequest) InitialLoadBalanceRequest(io.grpc.lb.v1.InitialLoadBalanceRequest) PickResult(io.grpc.LoadBalancer.PickResult) ManagedChannel(io.grpc.ManagedChannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs)

Aggregations

EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)3 Subchannel (io.grpc.LoadBalancer.Subchannel)3 InitialLoadBalanceRequest (io.grpc.lb.v1.InitialLoadBalanceRequest)3 InitialLoadBalanceResponse (io.grpc.lb.v1.InitialLoadBalanceResponse)3 LoadBalanceRequest (io.grpc.lb.v1.LoadBalanceRequest)3 LoadBalanceResponse (io.grpc.lb.v1.LoadBalanceResponse)3 InOrder (org.mockito.InOrder)3 ConnectivityStateInfo (io.grpc.ConnectivityStateInfo)2 PickResult (io.grpc.LoadBalancer.PickResult)2 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)2 Status (io.grpc.Status)2 Attributes (io.grpc.Attributes)1 ConnectivityState (io.grpc.ConnectivityState)1 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)1 ManagedChannel (io.grpc.ManagedChannel)1 Test (org.junit.Test)1