2525import java .time .Duration ;
2626import java .util .ArrayList ;
2727import java .util .Arrays ;
28+ import java .util .Collections ;
2829import java .util .HashSet ;
2930import java .util .LinkedList ;
3031import java .util .List ;
32+ import java .util .Objects ;
3133import java .util .Random ;
3234import java .util .Set ;
3335import java .util .concurrent .CompletableFuture ;
4345import org .neo4j .driver .exceptions .FatalDiscoveryException ;
4446import org .neo4j .driver .exceptions .ProtocolException ;
4547import org .neo4j .driver .internal .BoltServerAddress ;
48+ import org .neo4j .driver .internal .DatabaseNameUtil ;
4649import org .neo4j .driver .internal .async .connection .BootstrapFactory ;
4750import org .neo4j .driver .internal .async .pool .NettyChannelHealthChecker ;
4851import org .neo4j .driver .internal .async .pool .NettyChannelTracker ;
@@ -85,7 +88,7 @@ class RoutingTableAndConnectionPoolTest
8588 private static final BoltServerAddress D = new BoltServerAddress ( "localhost:30003" );
8689 private static final BoltServerAddress E = new BoltServerAddress ( "localhost:30004" );
8790 private static final BoltServerAddress F = new BoltServerAddress ( "localhost:30005" );
88- private static final List <BoltServerAddress > SERVERS = new LinkedList <>( Arrays .asList ( null , A , B , C , D , E , F ) );
91+ private static final List <BoltServerAddress > SERVERS = Collections . synchronizedList ( new LinkedList <>( Arrays .asList ( null , A , B , C , D , E , F ) ) );
8992
9093 private static final String [] DATABASES = new String []{"" , SYSTEM_DATABASE_NAME , "my database" };
9194
@@ -94,7 +97,7 @@ class RoutingTableAndConnectionPoolTest
9497 private final Logging logging = none ();
9598
9699 @ Test
97- void shouldAddServerToRoutingTableAndConnectionPool () throws Throwable
100+ void shouldAddServerToRoutingTableAndConnectionPool ()
98101 {
99102 // Given
100103 ConnectionPool connectionPool = newConnectionPool ();
@@ -114,7 +117,7 @@ void shouldAddServerToRoutingTableAndConnectionPool() throws Throwable
114117 }
115118
116119 @ Test
117- void shouldNotAddToRoutingTableWhenFailedWithRoutingError () throws Throwable
120+ void shouldNotAddToRoutingTableWhenFailedWithRoutingError ()
118121 {
119122 // Given
120123 ConnectionPool connectionPool = newConnectionPool ();
@@ -133,7 +136,7 @@ void shouldNotAddToRoutingTableWhenFailedWithRoutingError() throws Throwable
133136 }
134137
135138 @ Test
136- void shouldNotAddToRoutingTableWhenFailedWithProtocolError () throws Throwable
139+ void shouldNotAddToRoutingTableWhenFailedWithProtocolError ()
137140 {
138141 // Given
139142 ConnectionPool connectionPool = newConnectionPool ();
@@ -152,7 +155,7 @@ void shouldNotAddToRoutingTableWhenFailedWithProtocolError() throws Throwable
152155 }
153156
154157 @ Test
155- void shouldNotAddToRoutingTableWhenFailedWithSecurityError () throws Throwable
158+ void shouldNotAddToRoutingTableWhenFailedWithSecurityError ()
156159 {
157160 // Given
158161 ConnectionPool connectionPool = newConnectionPool ();
@@ -171,7 +174,7 @@ void shouldNotAddToRoutingTableWhenFailedWithSecurityError() throws Throwable
171174 }
172175
173176 @ Test
174- void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired () throws Throwable
177+ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired ()
175178 {
176179 // Given
177180 ConnectionPool connectionPool = newConnectionPool ();
@@ -194,7 +197,7 @@ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() throws Throwable
194197 }
195198
196199 @ Test
197- void shouldRemoveExpiredRoutingTableAndServers () throws Throwable
200+ void shouldRemoveExpiredRoutingTableAndServers ()
198201 {
199202 // Given
200203 ConnectionPool connectionPool = newConnectionPool ();
@@ -219,7 +222,7 @@ void shouldRemoveExpiredRoutingTableAndServers() throws Throwable
219222 }
220223
221224 @ Test
222- void shouldRemoveExpiredRoutingTableButNotServer () throws Throwable
225+ void shouldRemoveExpiredRoutingTableButNotServer ()
223226 {
224227 // Given
225228 ConnectionPool connectionPool = newConnectionPool ();
@@ -256,7 +259,7 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
256259 acquireAndReleaseConnections ( loadBalancer );
257260 Set <BoltServerAddress > servers = routingTables .allServers ();
258261 BoltServerAddress openServer = null ;
259- for ( BoltServerAddress server : servers )
262+ for ( BoltServerAddress server : servers )
260263 {
261264 if ( connectionPool .isOpen ( server ) )
262265 {
@@ -268,6 +271,8 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
268271
269272 // if we remove the open server from servers, then the connection pool should remove the server from the pool.
270273 SERVERS .remove ( openServer );
274+ // ensure rediscovery is necessary on subsequent interaction
275+ Arrays .stream ( DATABASES ).map ( DatabaseNameUtil ::database ).forEach ( routingTables ::remove );
271276 acquireAndReleaseConnections ( loadBalancer );
272277
273278 assertFalse ( connectionPool .isOpen ( openServer ) );
@@ -368,7 +373,11 @@ public CompletionStage<ClusterCompositionLookupResult> lookupClusterComposition(
368373 }
369374 if ( servers .size () == 0 )
370375 {
371- servers .add ( A );
376+ BoltServerAddress address = SERVERS .stream ()
377+ .filter ( Objects ::nonNull )
378+ .findFirst ()
379+ .orElseThrow ( () -> new RuntimeException ( "No non null server addresses are available" ) );
380+ servers .add ( address );
372381 }
373382 ClusterComposition composition = new ClusterComposition ( clock .millis () + 1 , servers , servers , servers );
374383 return CompletableFuture .completedFuture ( new ClusterCompositionLookupResult ( composition ) );
0 commit comments