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 ();
@@ -134,7 +137,7 @@ void shouldNotAddToRoutingTableWhenFailedWithRoutingError() throws Throwable
134
137
}
135
138
136
139
@ Test
137
- void shouldNotAddToRoutingTableWhenFailedWithProtocolError () throws Throwable
140
+ void shouldNotAddToRoutingTableWhenFailedWithProtocolError ()
138
141
{
139
142
// Given
140
143
ConnectionPool connectionPool = newConnectionPool ();
@@ -154,7 +157,7 @@ void shouldNotAddToRoutingTableWhenFailedWithProtocolError() throws Throwable
154
157
}
155
158
156
159
@ Test
157
- void shouldNotAddToRoutingTableWhenFailedWithSecurityError () throws Throwable
160
+ void shouldNotAddToRoutingTableWhenFailedWithSecurityError ()
158
161
{
159
162
// Given
160
163
ConnectionPool connectionPool = newConnectionPool ();
@@ -174,7 +177,7 @@ void shouldNotAddToRoutingTableWhenFailedWithSecurityError() throws Throwable
174
177
}
175
178
176
179
@ Test
177
- void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired () throws Throwable
180
+ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired ()
178
181
{
179
182
// Given
180
183
ConnectionPool connectionPool = newConnectionPool ();
@@ -197,7 +200,7 @@ void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() throws Throwable
197
200
}
198
201
199
202
@ Test
200
- void shouldRemoveExpiredRoutingTableAndServers () throws Throwable
203
+ void shouldRemoveExpiredRoutingTableAndServers ()
201
204
{
202
205
// Given
203
206
ConnectionPool connectionPool = newConnectionPool ();
@@ -224,7 +227,7 @@ void shouldRemoveExpiredRoutingTableAndServers() throws Throwable
224
227
}
225
228
226
229
@ Test
227
- void shouldRemoveExpiredRoutingTableButNotServer () throws Throwable
230
+ void shouldRemoveExpiredRoutingTableButNotServer ()
228
231
{
229
232
// Given
230
233
ConnectionPool connectionPool = newConnectionPool ();
@@ -263,7 +266,7 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
263
266
acquireAndReleaseConnections ( loadBalancer );
264
267
Set <BoltServerAddress > servers = routingTables .allServers ();
265
268
BoltServerAddress openServer = null ;
266
- for ( BoltServerAddress server : servers )
269
+ for ( BoltServerAddress server : servers )
267
270
{
268
271
if ( connectionPool .isOpen ( server ) )
269
272
{
@@ -275,6 +278,8 @@ void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwabl
275
278
276
279
// if we remove the open server from servers, then the connection pool should remove the server from the pool.
277
280
SERVERS .remove ( openServer );
281
+ // ensure rediscovery is necessary on subsequent interaction
282
+ Arrays .stream ( DATABASES ).map ( DatabaseNameUtil ::database ).forEach ( routingTables ::remove );
278
283
acquireAndReleaseConnections ( loadBalancer );
279
284
280
285
assertFalse ( connectionPool .isOpen ( openServer ) );
@@ -375,7 +380,11 @@ public CompletionStage<ClusterCompositionLookupResult> lookupClusterComposition(
375
380
}
376
381
if ( servers .size () == 0 )
377
382
{
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 );
379
388
}
380
389
ClusterComposition composition = new ClusterComposition ( clock .millis () + 1 , servers , servers , servers , null );
381
390
return CompletableFuture .completedFuture ( new ClusterCompositionLookupResult ( composition ) );
0 commit comments