29
29
import java .util .LinkedHashSet ;
30
30
import java .util .Set ;
31
31
import java .util .concurrent .CompletableFuture ;
32
+ import java .util .function .Function ;
32
33
33
34
import org .neo4j .driver .AccessMode ;
34
35
import org .neo4j .driver .exceptions .ServiceUnavailableException ;
@@ -161,7 +162,7 @@ void shouldSelectLeastConnectedAddress()
161
162
Set <BoltServerAddress > seenAddresses = new HashSet <>();
162
163
for ( int i = 0 ; i < 10 ; i ++ )
163
164
{
164
- Connection connection = await ( loadBalancer .acquireConnection ( simple () ) );
165
+ Connection connection = await ( loadBalancer .acquireConnection ( newBoltV4ConnectionContext () ) );
165
166
seenAddresses .add ( connection .serverAddress () );
166
167
}
167
168
@@ -185,7 +186,7 @@ void shouldRoundRobinWhenNoActiveConnections()
185
186
Set <BoltServerAddress > seenAddresses = new HashSet <>();
186
187
for ( int i = 0 ; i < 10 ; i ++ )
187
188
{
188
- Connection connection = await ( loadBalancer .acquireConnection ( simple () ) );
189
+ Connection connection = await ( loadBalancer .acquireConnection ( newBoltV4ConnectionContext () ) );
189
190
seenAddresses .add ( connection .serverAddress () );
190
191
}
191
192
@@ -204,7 +205,7 @@ void shouldTryMultipleServersAfterRediscovery()
204
205
205
206
LoadBalancer loadBalancer = newLoadBalancer ( connectionPool , routingTable );
206
207
207
- Connection connection = await ( loadBalancer .acquireConnection ( simple () ) );
208
+ Connection connection = await ( loadBalancer .acquireConnection ( newBoltV4ConnectionContext () ) );
208
209
209
210
assertNotNull ( connection );
210
211
assertEquals ( B , connection .serverAddress () );
@@ -257,21 +258,93 @@ void shouldSuccessOnFirstSuccessfulServer() throws Throwable
257
258
assertTrue ( await ( loadBalancer .supportsMultiDbAsync () ) );
258
259
}
259
260
261
+ @ Test
262
+ void shouldThrowModifiedErrorWhenSupportMultiDbTestFails () throws Throwable
263
+ {
264
+ Set <BoltServerAddress > unavailableAddresses = asOrderedSet ( A , B );
265
+ ConnectionPool connectionPool = newConnectionPoolMockWithFailures ( unavailableAddresses );
266
+
267
+ Rediscovery rediscovery = mock ( Rediscovery .class );
268
+ when ( rediscovery .resolve () ).thenReturn ( Arrays .asList ( A , B ) );
269
+
270
+ LoadBalancer loadBalancer = newLoadBalancer ( connectionPool , rediscovery );
271
+
272
+ ServiceUnavailableException exception = assertThrows ( ServiceUnavailableException .class , () -> await ( loadBalancer .verifyConnectivity () ) );
273
+ assertThat ( exception .getMessage (), startsWith ( "Unable to connect to database management service," ) );
274
+ }
275
+
276
+ @ Test
277
+ void shouldThrowModifiedErrorWhenRefreshRoutingTableFails () throws Throwable
278
+ {
279
+ ConnectionPool connectionPool = newConnectionPoolMock ();
280
+
281
+ Rediscovery rediscovery = mock ( Rediscovery .class );
282
+ when ( rediscovery .resolve () ).thenReturn ( Arrays .asList ( A , B ) );
283
+
284
+ RoutingTableRegistry routingTables = mock ( RoutingTableRegistry .class );
285
+ when ( routingTables .refreshRoutingTable ( any ( ConnectionContext .class ) ) ).thenThrow ( new ServiceUnavailableException ( "boooo" ) );
286
+
287
+ LoadBalancer loadBalancer = newLoadBalancer ( connectionPool , routingTables , rediscovery );
288
+
289
+ ServiceUnavailableException exception = assertThrows ( ServiceUnavailableException .class , () -> await ( loadBalancer .verifyConnectivity () ) );
290
+ assertThat ( exception .getMessage (), startsWith ( "Unable to connect to database management service," ) );
291
+ verify ( routingTables ).refreshRoutingTable ( any ( ConnectionContext .class ) );
292
+ }
293
+
294
+ @ Test
295
+ void shouldThrowOriginalErrorWhenRefreshRoutingTableFails () throws Throwable
296
+ {
297
+ ConnectionPool connectionPool = newConnectionPoolMock ();
298
+
299
+ Rediscovery rediscovery = mock ( Rediscovery .class );
300
+ when ( rediscovery .resolve () ).thenReturn ( Arrays .asList ( A , B ) );
301
+
302
+ RoutingTableRegistry routingTables = mock ( RoutingTableRegistry .class );
303
+ when ( routingTables .refreshRoutingTable ( any ( ConnectionContext .class ) ) ).thenThrow ( new SecurityException ( "boo" ) );
304
+
305
+ LoadBalancer loadBalancer = newLoadBalancer ( connectionPool , routingTables , rediscovery );
306
+
307
+ SecurityException exception = assertThrows ( SecurityException .class , () -> await ( loadBalancer .verifyConnectivity () ) );
308
+ assertThat ( exception .getMessage (), startsWith ( "boo" ) );
309
+ verify ( routingTables ).refreshRoutingTable ( any ( ConnectionContext .class ) );
310
+ }
311
+
312
+ @ Test
313
+ void shouldReturnSuccessVerifyConnectivity () throws Throwable
314
+ {
315
+ ConnectionPool connectionPool = newConnectionPoolMock ();
316
+
317
+ Rediscovery rediscovery = mock ( Rediscovery .class );
318
+ when ( rediscovery .resolve () ).thenReturn ( Arrays .asList ( A , B ) );
319
+
320
+ RoutingTableRegistry routingTables = mock ( RoutingTableRegistry .class );
321
+ when ( routingTables .refreshRoutingTable ( any ( ConnectionContext .class ) ) ).thenReturn ( Futures .completedWithNull () );
322
+
323
+ LoadBalancer loadBalancer = newLoadBalancer ( connectionPool , routingTables , rediscovery );
324
+
325
+ await ( loadBalancer .verifyConnectivity () );
326
+ verify ( routingTables ).refreshRoutingTable ( any ( ConnectionContext .class ) );
327
+ }
328
+
260
329
private static ConnectionPool newConnectionPoolMock ()
261
330
{
262
331
return newConnectionPoolMockWithFailures ( emptySet () );
263
332
}
264
333
265
- private static ConnectionPool newConnectionPoolMockWithFailures (
266
- Set <BoltServerAddress > unavailableAddresses )
334
+ private static ConnectionPool newConnectionPoolMockWithFailures ( Set <BoltServerAddress > unavailableAddresses )
335
+ {
336
+ return newConnectionPoolMockWithFailures ( unavailableAddresses , address -> new ServiceUnavailableException ( address + " is unavailable!" ) );
337
+ }
338
+
339
+ private static ConnectionPool newConnectionPoolMockWithFailures ( Set <BoltServerAddress > unavailableAddresses , Function <BoltServerAddress , Throwable > errorAction )
267
340
{
268
341
ConnectionPool pool = mock ( ConnectionPool .class );
269
342
when ( pool .acquire ( any ( BoltServerAddress .class ) ) ).then ( invocation ->
270
343
{
271
344
BoltServerAddress requestedAddress = invocation .getArgument ( 0 );
272
345
if ( unavailableAddresses .contains ( requestedAddress ) )
273
346
{
274
- return Futures .failedFuture ( new ServiceUnavailableException ( requestedAddress + " is unavailable!" ) );
347
+ return Futures .failedFuture ( errorAction . apply ( requestedAddress ) );
275
348
}
276
349
277
350
return completedFuture ( newBoltV4Connection ( requestedAddress ) );
@@ -289,6 +362,11 @@ private static Connection newBoltV4Connection( BoltServerAddress address )
289
362
return connection ;
290
363
}
291
364
365
+ private static ConnectionContext newBoltV4ConnectionContext ()
366
+ {
367
+ return simple ( true );
368
+ }
369
+
292
370
private static LoadBalancer newLoadBalancer ( ConnectionPool connectionPool , RoutingTable routingTable )
293
371
{
294
372
// Used only in testing
@@ -305,6 +383,12 @@ private static LoadBalancer newLoadBalancer( ConnectionPool connectionPool, Redi
305
383
{
306
384
// Used only in testing
307
385
RoutingTableRegistry routingTables = mock ( RoutingTableRegistry .class );
386
+ return newLoadBalancer ( connectionPool , routingTables , rediscovery );
387
+ }
388
+
389
+ private static LoadBalancer newLoadBalancer ( ConnectionPool connectionPool , RoutingTableRegistry routingTables , Rediscovery rediscovery )
390
+ {
391
+ // Used only in testing
308
392
return new LoadBalancer ( connectionPool , routingTables , rediscovery , new LeastConnectedLoadBalancingStrategy ( connectionPool , DEV_NULL_LOGGING ),
309
393
GlobalEventExecutor .INSTANCE , DEV_NULL_LOGGER );
310
394
}
0 commit comments