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 ();
@@ -134,7 +137,7 @@ void shouldNotAddToRoutingTableWhenFailedWithRoutingError() throws Throwable
134137 }
135138
136139 @ Test
137- void shouldNotAddToRoutingTableWhenFailedWithProtocolError () throws Throwable
140+ void shouldNotAddToRoutingTableWhenFailedWithProtocolError ()
138141 {
139142 // Given
140143 ConnectionPool connectionPool = newConnectionPool ();
@@ -154,7 +157,7 @@ void shouldNotAddToRoutingTableWhenFailedWithProtocolError() throws Throwable
154157 }
155158
156159 @ Test
157- void shouldNotAddToRoutingTableWhenFailedWithSecurityError () throws Throwable
160+ void shouldNotAddToRoutingTableWhenFailedWithSecurityError ()
158161 {
159162 // Given
160163 ConnectionPool connectionPool = newConnectionPool ();
@@ -174,7 +177,7 @@ void shouldNotAddToRoutingTableWhenFailedWithSecurityError() throws Throwable
174177 }
175178
176179 @ Test
177- void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired () throws Throwable
180+ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired ()
178181 {
179182 // Given
180183 ConnectionPool connectionPool = newConnectionPool ();
@@ -197,7 +200,7 @@ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() throws Throwable
197200 }
198201
199202 @ Test
200- void shouldRemoveExpiredRoutingTableAndServers () throws Throwable
203+ void shouldRemoveExpiredRoutingTableAndServers ()
201204 {
202205 // Given
203206 ConnectionPool connectionPool = newConnectionPool ();
@@ -224,7 +227,7 @@ void shouldRemoveExpiredRoutingTableAndServers() throws Throwable
224227 }
225228
226229 @ Test
227- void shouldRemoveExpiredRoutingTableButNotServer () throws Throwable
230+ void shouldRemoveExpiredRoutingTableButNotServer ()
228231 {
229232 // Given
230233 ConnectionPool connectionPool = newConnectionPool ();
@@ -263,7 +266,7 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
263266 acquireAndReleaseConnections ( loadBalancer );
264267 Set <BoltServerAddress > servers = routingTables .allServers ();
265268 BoltServerAddress openServer = null ;
266- for ( BoltServerAddress server : servers )
269+ for ( BoltServerAddress server : servers )
267270 {
268271 if ( connectionPool .isOpen ( server ) )
269272 {
@@ -275,6 +278,8 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
275278
276279 // if we remove the open server from servers, then the connection pool should remove the server from the pool.
277280 SERVERS .remove ( openServer );
281+ // ensure rediscovery is necessary on subsequent interaction
282+ Arrays .stream ( DATABASES ).map ( DatabaseNameUtil ::database ).forEach ( routingTables ::remove );
278283 acquireAndReleaseConnections ( loadBalancer );
279284
280285 assertFalse ( connectionPool .isOpen ( openServer ) );
@@ -375,7 +380,11 @@ public CompletionStage<ClusterCompositionLookupResult> lookupClusterComposition(
375380 }
376381 if ( servers .size () == 0 )
377382 {
378- servers .add ( A );
383+ BoltServerAddress address = SERVERS .stream ()
384+ .filter ( Objects ::nonNull )
385+ .findFirst ()
386+ .orElseThrow ( () -> new RuntimeException ( "No non null server addresses are available" ) );
387+ servers .add ( address );
379388 }
380389 ClusterComposition composition = new ClusterComposition ( clock .millis () + 1 , servers , servers , servers , null );
381390 return CompletableFuture .completedFuture ( new ClusterCompositionLookupResult ( composition ) );
0 commit comments