20
20
import static com .rabbitmq .client .amqp .ConnectionSettings .Affinity .Operation .CONSUME ;
21
21
import static com .rabbitmq .client .amqp .ConnectionSettings .Affinity .Operation .PUBLISH ;
22
22
import static com .rabbitmq .client .amqp .impl .Assertions .assertThat ;
23
- import static com .rabbitmq .client .amqp .impl .TestUtils .sync ;
24
- import static com .rabbitmq .client .amqp .impl .TestUtils .waitAtMost ;
23
+ import static com .rabbitmq .client .amqp .impl .TestUtils .*;
25
24
import static java .time .Duration .ofMillis ;
26
25
import static java .time .Duration .ofSeconds ;
26
+ import static java .util .stream .Collectors .toList ;
27
+ import static java .util .stream .IntStream .range ;
27
28
import static org .assertj .core .api .Assertions .assertThat ;
28
29
29
30
import com .rabbitmq .client .amqp .*;
30
31
import com .rabbitmq .client .amqp .impl .TestUtils .Sync ;
32
+ import java .util .Arrays ;
31
33
import java .util .List ;
32
34
import java .util .Set ;
33
35
import java .util .concurrent .ConcurrentHashMap ;
41
43
@ TestUtils .DisabledIfNotCluster
42
44
public class ClusterTest {
43
45
46
+ static final String [] URIS =
47
+ new String [] {"amqp://localhost:5672" , "amqp://localhost:5673" , "amqp://localhost:5674" };
44
48
static final BackOffDelayPolicy BACK_OFF_DELAY_POLICY = BackOffDelayPolicy .fixed (ofMillis (100 ));
45
49
Environment environment ;
46
50
Connection connection ;
@@ -49,13 +53,13 @@ public class ClusterTest {
49
53
50
54
@ BeforeEach
51
55
void init (TestInfo info ) {
52
- this .q = TestUtils . name (info );
53
- this .name = TestUtils . name (info );
56
+ this .q = name (info );
57
+ this .name = name (info );
54
58
environment =
55
59
new AmqpEnvironmentBuilder ()
56
60
.connectionSettings ()
57
61
.addressSelector (new RoundRobinAddressSelector ())
58
- .uris ("amqp://localhost:5672" , "amqp://localhost:5673" , "amqp://localhost:5674" )
62
+ .uris (URIS )
59
63
.environmentBuilder ()
60
64
.build ();
61
65
this .connection = environment .connectionBuilder ().build ();
@@ -311,9 +315,7 @@ void consumeFromQuorumQueueWhenLeaderIsPaused() {
311
315
consumeSync .reset ();
312
316
313
317
List <String > initialFollowers =
314
- queueInfo .replicas ().stream ()
315
- .filter (n -> !n .equals (initialLeader ))
316
- .collect (Collectors .toList ());
318
+ queueInfo .replicas ().stream ().filter (n -> !n .equals (initialLeader )).collect (toList ());
317
319
assertThat (initialFollowers ).isNotEmpty ();
318
320
319
321
Cli .pauseNode (initialLeader );
@@ -433,6 +435,48 @@ void consumeFromRestartedStream() {
433
435
}
434
436
}
435
437
438
+ @ Test
439
+ void connectionShouldBeOnOwningNodeWhenAffinityIsActivatedForClassicQueues (TestInfo info ) {
440
+ List <String > names = range (0 , URIS .length ).mapToObj (ignored -> name (info )).collect (toList ());
441
+ try {
442
+ List <Connection > connections =
443
+ Arrays .stream (URIS )
444
+ .map (
445
+ uri ->
446
+ connection (
447
+ b ->
448
+ b .uri (uri )
449
+ .affinity ()
450
+ .strategy (ConnectionUtils .MEMBER_AFFINITY_STRATEGY )))
451
+ .collect (toList ());
452
+ List <Management .QueueInfo > queueInfos =
453
+ range (0 , URIS .length )
454
+ .mapToObj (
455
+ i ->
456
+ connections
457
+ .get (i )
458
+ .management ()
459
+ .queue (names .get (i ))
460
+ .type (Management .QueueType .CLASSIC )
461
+ .declare ())
462
+ .collect (toList ());
463
+ assertThat (queueInfos .stream ().map (Management .QueueInfo ::leader ).collect (Collectors .toSet ()))
464
+ .hasSameSizeAs (URIS );
465
+
466
+ List <AmqpConnection > connectionsWithAffinity =
467
+ names .stream ().map (n -> connection (b -> b .affinity ().queue (n ))).collect (toList ());
468
+
469
+ range (0 , URIS .length )
470
+ .forEach (
471
+ i ->
472
+ assertThat (connectionsWithAffinity .get (i ))
473
+ .hasNodename (queueInfos .get (i ).leader ()));
474
+
475
+ } finally {
476
+ names .forEach (n -> management .queueDeletion ().delete (n ));
477
+ }
478
+ }
479
+
436
480
String moveQqLeader () {
437
481
String initialLeader = deleteQqLeader ();
438
482
addQqMember (initialLeader );
@@ -492,7 +536,12 @@ Management.QueueInfo queueInfo() {
492
536
493
537
AmqpConnection connection (Consumer <AmqpConnectionBuilder > operation ) {
494
538
AmqpConnectionBuilder builder = (AmqpConnectionBuilder ) environment .connectionBuilder ();
495
- builder .recovery ().backOffDelayPolicy (BACK_OFF_DELAY_POLICY );
539
+ builder
540
+ .recovery ()
541
+ .backOffDelayPolicy (BACK_OFF_DELAY_POLICY )
542
+ .connectionBuilder ()
543
+ .affinity ()
544
+ .strategy (ConnectionUtils .PREFER_LEADER_FOR_PUBLISHING_STRATEGY );
496
545
operation .accept (builder );
497
546
return (AmqpConnection ) builder .build ();
498
547
}
0 commit comments