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 .NettyChannelHealthChecker ;
48
51
import org .neo4j .driver .internal .async .pool .NettyChannelTracker ;
@@ -85,7 +88,7 @@ class RoutingTableAndConnectionPoolTest
85
88
private static final BoltServerAddress D = new BoltServerAddress ( "localhost:30003" );
86
89
private static final BoltServerAddress E = new BoltServerAddress ( "localhost:30004" );
87
90
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 ) ) );
89
92
90
93
private static final String [] DATABASES = new String []{"" , SYSTEM_DATABASE_NAME , "my database" };
91
94
@@ -94,7 +97,7 @@ class RoutingTableAndConnectionPoolTest
94
97
private final Logging logging = none ();
95
98
96
99
@ Test
97
- void shouldAddServerToRoutingTableAndConnectionPool () throws Throwable
100
+ void shouldAddServerToRoutingTableAndConnectionPool ()
98
101
{
99
102
// Given
100
103
ConnectionPool connectionPool = newConnectionPool ();
@@ -114,7 +117,7 @@ void shouldAddServerToRoutingTableAndConnectionPool() throws Throwable
114
117
}
115
118
116
119
@ Test
117
- void shouldNotAddToRoutingTableWhenFailedWithRoutingError () throws Throwable
120
+ void shouldNotAddToRoutingTableWhenFailedWithRoutingError ()
118
121
{
119
122
// Given
120
123
ConnectionPool connectionPool = newConnectionPool ();
@@ -133,7 +136,7 @@ void shouldNotAddToRoutingTableWhenFailedWithRoutingError() throws Throwable
133
136
}
134
137
135
138
@ Test
136
- void shouldNotAddToRoutingTableWhenFailedWithProtocolError () throws Throwable
139
+ void shouldNotAddToRoutingTableWhenFailedWithProtocolError ()
137
140
{
138
141
// Given
139
142
ConnectionPool connectionPool = newConnectionPool ();
@@ -152,7 +155,7 @@ void shouldNotAddToRoutingTableWhenFailedWithProtocolError() throws Throwable
152
155
}
153
156
154
157
@ Test
155
- void shouldNotAddToRoutingTableWhenFailedWithSecurityError () throws Throwable
158
+ void shouldNotAddToRoutingTableWhenFailedWithSecurityError ()
156
159
{
157
160
// Given
158
161
ConnectionPool connectionPool = newConnectionPool ();
@@ -171,7 +174,7 @@ void shouldNotAddToRoutingTableWhenFailedWithSecurityError() throws Throwable
171
174
}
172
175
173
176
@ Test
174
- void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired () throws Throwable
177
+ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired ()
175
178
{
176
179
// Given
177
180
ConnectionPool connectionPool = newConnectionPool ();
@@ -194,7 +197,7 @@ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() throws Throwable
194
197
}
195
198
196
199
@ Test
197
- void shouldRemoveExpiredRoutingTableAndServers () throws Throwable
200
+ void shouldRemoveExpiredRoutingTableAndServers ()
198
201
{
199
202
// Given
200
203
ConnectionPool connectionPool = newConnectionPool ();
@@ -219,7 +222,7 @@ void shouldRemoveExpiredRoutingTableAndServers() throws Throwable
219
222
}
220
223
221
224
@ Test
222
- void shouldRemoveExpiredRoutingTableButNotServer () throws Throwable
225
+ void shouldRemoveExpiredRoutingTableButNotServer ()
223
226
{
224
227
// Given
225
228
ConnectionPool connectionPool = newConnectionPool ();
@@ -256,7 +259,7 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
256
259
acquireAndReleaseConnections ( loadBalancer );
257
260
Set <BoltServerAddress > servers = routingTables .allServers ();
258
261
BoltServerAddress openServer = null ;
259
- for ( BoltServerAddress server : servers )
262
+ for ( BoltServerAddress server : servers )
260
263
{
261
264
if ( connectionPool .isOpen ( server ) )
262
265
{
@@ -268,6 +271,8 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
268
271
269
272
// if we remove the open server from servers, then the connection pool should remove the server from the pool.
270
273
SERVERS .remove ( openServer );
274
+ // ensure rediscovery is necessary on subsequent interaction
275
+ Arrays .stream ( DATABASES ).map ( DatabaseNameUtil ::database ).forEach ( routingTables ::remove );
271
276
acquireAndReleaseConnections ( loadBalancer );
272
277
273
278
assertFalse ( connectionPool .isOpen ( openServer ) );
@@ -368,7 +373,11 @@ public CompletionStage<ClusterCompositionLookupResult> lookupClusterComposition(
368
373
}
369
374
if ( servers .size () == 0 )
370
375
{
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 );
372
381
}
373
382
ClusterComposition composition = new ClusterComposition ( clock .millis () + 1 , servers , servers , servers );
374
383
return CompletableFuture .completedFuture ( new ClusterCompositionLookupResult ( composition ) );
0 commit comments