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 .NettyChannelTracker ;
4851import org .neo4j .driver .internal .async .pool .PoolSettings ;
@@ -84,7 +87,7 @@ class RoutingTableAndConnectionPoolTest
8487 private static final BoltServerAddress D = new BoltServerAddress ( "localhost:30003" );
8588 private static final BoltServerAddress E = new BoltServerAddress ( "localhost:30004" );
8689 private static final BoltServerAddress F = new BoltServerAddress ( "localhost:30005" );
87- private static final List <BoltServerAddress > SERVERS = new LinkedList <>( Arrays .asList ( null , A , B , C , D , E , F ) );
90+ private static final List <BoltServerAddress > SERVERS = Collections . synchronizedList ( new LinkedList <>( Arrays .asList ( null , A , B , C , D , E , F ) ) );
8891
8992 private static final String [] DATABASES = new String []{"" , SYSTEM_DATABASE_NAME , "my database" };
9093
@@ -93,7 +96,7 @@ class RoutingTableAndConnectionPoolTest
9396 private final Logging logging = none ();
9497
9598 @ Test
96- void shouldAddServerToRoutingTableAndConnectionPool () throws Throwable
99+ void shouldAddServerToRoutingTableAndConnectionPool ()
97100 {
98101 // Given
99102 ConnectionPool connectionPool = newConnectionPool ();
@@ -113,7 +116,7 @@ void shouldAddServerToRoutingTableAndConnectionPool() throws Throwable
113116 }
114117
115118 @ Test
116- void shouldNotAddToRoutingTableWhenFailedWithRoutingError () throws Throwable
119+ void shouldNotAddToRoutingTableWhenFailedWithRoutingError ()
117120 {
118121 // Given
119122 ConnectionPool connectionPool = newConnectionPool ();
@@ -132,7 +135,7 @@ void shouldNotAddToRoutingTableWhenFailedWithRoutingError() throws Throwable
132135 }
133136
134137 @ Test
135- void shouldNotAddToRoutingTableWhenFailedWithProtocolError () throws Throwable
138+ void shouldNotAddToRoutingTableWhenFailedWithProtocolError ()
136139 {
137140 // Given
138141 ConnectionPool connectionPool = newConnectionPool ();
@@ -151,7 +154,7 @@ void shouldNotAddToRoutingTableWhenFailedWithProtocolError() throws Throwable
151154 }
152155
153156 @ Test
154- void shouldNotAddToRoutingTableWhenFailedWithSecurityError () throws Throwable
157+ void shouldNotAddToRoutingTableWhenFailedWithSecurityError ()
155158 {
156159 // Given
157160 ConnectionPool connectionPool = newConnectionPool ();
@@ -170,7 +173,7 @@ void shouldNotAddToRoutingTableWhenFailedWithSecurityError() throws Throwable
170173 }
171174
172175 @ Test
173- void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired () throws Throwable
176+ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired ()
174177 {
175178 // Given
176179 ConnectionPool connectionPool = newConnectionPool ();
@@ -193,7 +196,7 @@ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() throws Throwable
193196 }
194197
195198 @ Test
196- void shouldRemoveExpiredRoutingTableAndServers () throws Throwable
199+ void shouldRemoveExpiredRoutingTableAndServers ()
197200 {
198201 // Given
199202 ConnectionPool connectionPool = newConnectionPool ();
@@ -218,7 +221,7 @@ void shouldRemoveExpiredRoutingTableAndServers() throws Throwable
218221 }
219222
220223 @ Test
221- void shouldRemoveExpiredRoutingTableButNotServer () throws Throwable
224+ void shouldRemoveExpiredRoutingTableButNotServer ()
222225 {
223226 // Given
224227 ConnectionPool connectionPool = newConnectionPool ();
@@ -255,7 +258,7 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
255258 acquireAndReleaseConnections ( loadBalancer );
256259 Set <BoltServerAddress > servers = routingTables .allServers ();
257260 BoltServerAddress openServer = null ;
258- for ( BoltServerAddress server : servers )
261+ for ( BoltServerAddress server : servers )
259262 {
260263 if ( connectionPool .isOpen ( server ) )
261264 {
@@ -267,6 +270,8 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
267270
268271 // if we remove the open server from servers, then the connection pool should remove the server from the pool.
269272 SERVERS .remove ( openServer );
273+ // ensure rediscovery is necessary on subsequent interaction
274+ Arrays .stream ( DATABASES ).map ( DatabaseNameUtil ::database ).forEach ( routingTables ::remove );
270275 acquireAndReleaseConnections ( loadBalancer );
271276
272277 assertFalse ( connectionPool .isOpen ( openServer ) );
@@ -366,7 +371,11 @@ public CompletionStage<ClusterCompositionLookupResult> lookupClusterComposition(
366371 }
367372 if ( servers .size () == 0 )
368373 {
369- servers .add ( A );
374+ BoltServerAddress address = SERVERS .stream ()
375+ .filter ( Objects ::nonNull )
376+ .findFirst ()
377+ .orElseThrow ( () -> new RuntimeException ( "No non null server addresses are available" ) );
378+ servers .add ( address );
370379 }
371380 ClusterComposition composition = new ClusterComposition ( clock .millis () + 1 , servers , servers , servers );
372381 return CompletableFuture .completedFuture ( new ClusterCompositionLookupResult ( composition ) );
0 commit comments