LoadBalancer implements ConnectionProvider { @Override public CompletionStage<Void> verifyConnectivity() { return this.supportsMultiDb().thenCompose( supports -> routingTables.ensureRoutingTable( simple( supports ) ) ).handle( ( ignored, error ) -> { if ( error != null ) { Throwable cause = completionExceptionCause( error ); if ( cause instanceof ServiceUnavailableException ) { throw Futures.asCompletionException( new ServiceUnavailableException( "Unable to connect to database management service, ensure the database is running and that there is a working network connection to it.", cause ) ); } throw Futures.asCompletionException( cause ); } return null; } ); } LoadBalancer( BoltServerAddress initialRouter, RoutingSettings settings, ConnectionPool connectionPool,
            EventExecutorGroup eventExecutorGroup, Clock clock, Logging logging,
            LoadBalancingStrategy loadBalancingStrategy, ServerAddressResolver resolver ); private  LoadBalancer( ConnectionPool connectionPool, Rediscovery rediscovery, RoutingSettings settings, LoadBalancingStrategy loadBalancingStrategy,
            EventExecutorGroup eventExecutorGroup, Clock clock, Logger log );   LoadBalancer( ConnectionPool connectionPool, RoutingTableRegistry routingTables, Rediscovery rediscovery, LoadBalancingStrategy loadBalancingStrategy,
            EventExecutorGroup eventExecutorGroup, Logger log ); @Override CompletionStage<Connection> acquireConnection( ConnectionContext context ); @Override CompletionStage<Void> verifyConnectivity(); @Override CompletionStage<Void> close(); @Override CompletionStage<Boolean> supportsMultiDb();  }
@Test void shouldThrowModifiedErrorWhenSupportMultiDbTestFails() throws Throwable { Set<BoltServerAddress> unavailableAddresses = asOrderedSet( A, B ); ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses ); Rediscovery rediscovery = mock( Rediscovery.class ); when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); LoadBalancer loadBalancer = newLoadBalancer( connectionPool, rediscovery ); ServiceUnavailableException exception = assertThrows( ServiceUnavailableException.class, () -> await( loadBalancer.verifyConnectivity() ) ); assertThat( exception.getMessage(), startsWith( "Unable to connect to database management service," ) ); }
@Test void shouldFailEarlyOnSecurityErrorWhenSupportMultiDbTestFails() throws Throwable { Set<BoltServerAddress> unavailableAddresses = asOrderedSet( A, B ); ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses, address -> new AuthenticationException( "code", "error" ) ); Rediscovery rediscovery = mock( Rediscovery.class ); when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); LoadBalancer loadBalancer = newLoadBalancer( connectionPool, rediscovery ); AuthenticationException exception = assertThrows( AuthenticationException.class, () -> await( loadBalancer.verifyConnectivity() ) ); assertThat( exception.getMessage(), startsWith( "error" ) ); }
@Test void shouldThrowModifiedErrorWhenRefreshRoutingTableFails() throws Throwable { ConnectionPool connectionPool = newConnectionPoolMock(); Rediscovery rediscovery = mock( Rediscovery.class ); when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenThrow( new ServiceUnavailableException( "boooo" ) ); LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables, rediscovery ); ServiceUnavailableException exception = assertThrows( ServiceUnavailableException.class, () -> await( loadBalancer.verifyConnectivity() ) ); assertThat( exception.getMessage(), startsWith( "Unable to connect to database management service," ) ); verify( routingTables ).ensureRoutingTable( any( ConnectionContext.class ) ); }
@Test void shouldThrowOriginalErrorWhenRefreshRoutingTableFails() throws Throwable { ConnectionPool connectionPool = newConnectionPoolMock(); Rediscovery rediscovery = mock( Rediscovery.class ); when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenThrow( new RuntimeException( "boo" ) ); LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables, rediscovery ); RuntimeException exception = assertThrows( RuntimeException.class, () -> await( loadBalancer.verifyConnectivity() ) ); assertThat( exception.getMessage(), startsWith( "boo" ) ); verify( routingTables ).ensureRoutingTable( any( ConnectionContext.class ) ); }
@Test void shouldReturnSuccessVerifyConnectivity() throws Throwable { ConnectionPool connectionPool = newConnectionPoolMock(); Rediscovery rediscovery = mock( Rediscovery.class ); when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenReturn( Futures.completedWithNull() ); LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables, rediscovery ); await( loadBalancer.verifyConnectivity() ); verify( routingTables ).ensureRoutingTable( any( ConnectionContext.class ) ); }