25
25
import java .time .Duration ;
26
26
import java .util .ArrayList ;
27
27
import java .util .Arrays ;
28
+ import java .util .Collections ;
28
29
import java .util .HashSet ;
29
30
import java .util .LinkedList ;
30
31
import java .util .List ;
32
+ import java .util .Objects ;
31
33
import java .util .Random ;
32
34
import java .util .Set ;
33
35
import java .util .concurrent .CompletableFuture ;
43
45
import org .neo4j .driver .exceptions .FatalDiscoveryException ;
44
46
import org .neo4j .driver .exceptions .ProtocolException ;
45
47
import org .neo4j .driver .internal .BoltServerAddress ;
48
+ import org .neo4j .driver .internal .DatabaseNameUtil ;
46
49
import org .neo4j .driver .internal .async .connection .BootstrapFactory ;
47
50
import org .neo4j .driver .internal .async .pool .NettyChannelTracker ;
48
51
import org .neo4j .driver .internal .async .pool .PoolSettings ;
@@ -84,7 +87,7 @@ class RoutingTableAndConnectionPoolTest
84
87
private static final BoltServerAddress D = new BoltServerAddress ( "localhost:30003" );
85
88
private static final BoltServerAddress E = new BoltServerAddress ( "localhost:30004" );
86
89
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 ) ) );
88
91
89
92
private static final String [] DATABASES = new String []{"" , SYSTEM_DATABASE_NAME , "my database" };
90
93
@@ -93,7 +96,7 @@ class RoutingTableAndConnectionPoolTest
93
96
private final Logging logging = none ();
94
97
95
98
@ Test
96
- void shouldAddServerToRoutingTableAndConnectionPool () throws Throwable
99
+ void shouldAddServerToRoutingTableAndConnectionPool ()
97
100
{
98
101
// Given
99
102
ConnectionPool connectionPool = newConnectionPool ();
@@ -113,7 +116,7 @@ void shouldAddServerToRoutingTableAndConnectionPool() throws Throwable
113
116
}
114
117
115
118
@ Test
116
- void shouldNotAddToRoutingTableWhenFailedWithRoutingError () throws Throwable
119
+ void shouldNotAddToRoutingTableWhenFailedWithRoutingError ()
117
120
{
118
121
// Given
119
122
ConnectionPool connectionPool = newConnectionPool ();
@@ -132,7 +135,7 @@ void shouldNotAddToRoutingTableWhenFailedWithRoutingError() throws Throwable
132
135
}
133
136
134
137
@ Test
135
- void shouldNotAddToRoutingTableWhenFailedWithProtocolError () throws Throwable
138
+ void shouldNotAddToRoutingTableWhenFailedWithProtocolError ()
136
139
{
137
140
// Given
138
141
ConnectionPool connectionPool = newConnectionPool ();
@@ -151,7 +154,7 @@ void shouldNotAddToRoutingTableWhenFailedWithProtocolError() throws Throwable
151
154
}
152
155
153
156
@ Test
154
- void shouldNotAddToRoutingTableWhenFailedWithSecurityError () throws Throwable
157
+ void shouldNotAddToRoutingTableWhenFailedWithSecurityError ()
155
158
{
156
159
// Given
157
160
ConnectionPool connectionPool = newConnectionPool ();
@@ -170,7 +173,7 @@ void shouldNotAddToRoutingTableWhenFailedWithSecurityError() throws Throwable
170
173
}
171
174
172
175
@ Test
173
- void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired () throws Throwable
176
+ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired ()
174
177
{
175
178
// Given
176
179
ConnectionPool connectionPool = newConnectionPool ();
@@ -193,7 +196,7 @@ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() throws Throwable
193
196
}
194
197
195
198
@ Test
196
- void shouldRemoveExpiredRoutingTableAndServers () throws Throwable
199
+ void shouldRemoveExpiredRoutingTableAndServers ()
197
200
{
198
201
// Given
199
202
ConnectionPool connectionPool = newConnectionPool ();
@@ -218,7 +221,7 @@ void shouldRemoveExpiredRoutingTableAndServers() throws Throwable
218
221
}
219
222
220
223
@ Test
221
- void shouldRemoveExpiredRoutingTableButNotServer () throws Throwable
224
+ void shouldRemoveExpiredRoutingTableButNotServer ()
222
225
{
223
226
// Given
224
227
ConnectionPool connectionPool = newConnectionPool ();
@@ -255,7 +258,7 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
255
258
acquireAndReleaseConnections ( loadBalancer );
256
259
Set <BoltServerAddress > servers = routingTables .allServers ();
257
260
BoltServerAddress openServer = null ;
258
- for ( BoltServerAddress server : servers )
261
+ for ( BoltServerAddress server : servers )
259
262
{
260
263
if ( connectionPool .isOpen ( server ) )
261
264
{
@@ -267,6 +270,8 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
267
270
268
271
// if we remove the open server from servers, then the connection pool should remove the server from the pool.
269
272
SERVERS .remove ( openServer );
273
+ // ensure rediscovery is necessary on subsequent interaction
274
+ Arrays .stream ( DATABASES ).map ( DatabaseNameUtil ::database ).forEach ( routingTables ::remove );
270
275
acquireAndReleaseConnections ( loadBalancer );
271
276
272
277
assertFalse ( connectionPool .isOpen ( openServer ) );
@@ -366,7 +371,11 @@ public CompletionStage<ClusterCompositionLookupResult> lookupClusterComposition(
366
371
}
367
372
if ( servers .size () == 0 )
368
373
{
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 );
370
379
}
371
380
ClusterComposition composition = new ClusterComposition ( clock .millis () + 1 , servers , servers , servers );
372
381
return CompletableFuture .completedFuture ( new ClusterCompositionLookupResult ( composition ) );
0 commit comments