diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java
index c9288c54cd..b68dda0f3b 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java
@@ -25,8 +25,21 @@
import org.neo4j.driver.internal.BoltServerAddress;
import org.neo4j.driver.internal.spi.ConnectionPool;
+/**
+ * Provides cluster composition lookup capabilities and initial router address resolution.
+ */
public interface Rediscovery
{
+ /**
+ * Fetches cluster composition using the provided routing table.
+ *
+ * Implementation must be thread safe to be called with distinct routing tables concurrently. The routing table instance may be modified.
+ *
+ * @param routingTable the routing table for cluster composition lookup
+ * @param connectionPool the connection pool for connection acquisition
+ * @param bookmark the bookmark that is presented to the server
+ * @return cluster composition lookup result
+ */
CompletionStage lookupClusterComposition( RoutingTable routingTable, ConnectionPool connectionPool, Bookmark bookmark );
List resolve();
diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java
index 4c95288389..bebc04741d 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java
@@ -49,14 +49,13 @@
import static org.neo4j.driver.internal.util.Futures.completedWithNull;
import static org.neo4j.driver.internal.util.Futures.failedFuture;
-/**
- * This class is used by all router tables to perform discovery.
- * In other words, the methods in this class could be called by multiple threads concurrently.
- */
public class RediscoveryImpl implements Rediscovery
{
private static final String NO_ROUTERS_AVAILABLE = "Could not perform discovery for database '%s'. No routing server available.";
private static final String RECOVERABLE_ROUTING_ERROR = "Failed to update routing table with server '%s'.";
+ private static final String RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER = "Received a recoverable discovery error with server '%s', " +
+ "will continue discovery with other routing servers if available. " +
+ "Complete routing failures will be reported separately from this warning.";
private final BoltServerAddress initialRouter;
private final RoutingSettings settings;
@@ -258,8 +257,9 @@ private ClusterComposition handleRoutingProcedureError( Throwable error, Routing
// Retriable error happened during discovery.
DiscoveryException discoveryError = new DiscoveryException( format( RECOVERABLE_ROUTING_ERROR, routerAddress ), error );
Futures.combineErrors( baseError, discoveryError ); // we record each failure here
- logger.warn( format( "Received a recoverable discovery error with server '%s', will continue discovery with other routing servers if available.",
- routerAddress ), discoveryError );
+ String warningMessage = format( RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER, routerAddress );
+ logger.warn( warningMessage );
+ logger.debug( warningMessage, discoveryError );
routingTable.forget( routerAddress );
return null;
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java
index 26656699ff..d8416f55ef 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java
@@ -52,7 +52,6 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.startsWith;
@@ -182,9 +181,14 @@ void shouldFailImmediatelyWhenClusterCompositionProviderReturnsFailure()
ClusterComposition composition = await( rediscovery.lookupClusterComposition( table, pool, empty() ) );
assertEquals( validComposition, composition );
- ArgumentCaptor argument = ArgumentCaptor.forClass( DiscoveryException.class );
- verify( logger ).warn( anyString(), argument.capture() );
- assertThat( argument.getValue().getCause(), equalTo( protocolError ) );
+ ArgumentCaptor warningMessageCaptor = ArgumentCaptor.forClass( String.class );
+ ArgumentCaptor debugMessageCaptor = ArgumentCaptor.forClass( String.class );
+ ArgumentCaptor debugThrowableCaptor = ArgumentCaptor.forClass( DiscoveryException.class );
+ verify( logger ).warn( warningMessageCaptor.capture() );
+ verify( logger ).debug( debugMessageCaptor.capture(), debugThrowableCaptor.capture() );
+ assertNotNull( warningMessageCaptor.getValue() );
+ assertEquals( warningMessageCaptor.getValue(), debugMessageCaptor.getValue() );
+ assertThat( debugThrowableCaptor.getValue().getCause(), equalTo( protocolError ) );
}
@Test