1
- // Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
1
+ // Copyright (c) 2021-2022 VMware, Inc. or its affiliates. All rights reserved.
2
2
//
3
3
// This software, the RabbitMQ Stream Java client library, is dual-licensed under the
4
4
// Mozilla Public License 2.0 ("MPL"), and the Apache License version 2 ("ASL").
19
19
import static com .rabbitmq .stream .impl .TestUtils .deleteSuperStreamTopology ;
20
20
import static com .rabbitmq .stream .impl .TestUtils .streamName ;
21
21
import static com .rabbitmq .stream .impl .TestUtils .waitAtMost ;
22
+ import static java .util .stream .Collectors .toList ;
22
23
import static org .assertj .core .api .Assertions .assertThat ;
23
24
24
25
import com .rabbitmq .client .Connection ;
25
26
import com .rabbitmq .client .ConnectionFactory ;
27
+ import com .rabbitmq .stream .Host ;
26
28
import com .rabbitmq .stream .OffsetSpecification ;
27
29
import com .rabbitmq .stream .impl .Client .ClientParameters ;
28
30
import com .rabbitmq .stream .impl .Client .ConsumerUpdateListener ;
29
31
import com .rabbitmq .stream .impl .Client .Response ;
32
+ import com .rabbitmq .stream .impl .TestUtils .DisabledIfRabbitMqCtlNotSet ;
30
33
import java .util .HashMap ;
31
34
import java .util .List ;
32
35
import java .util .Map ;
35
38
import java .util .concurrent .atomic .AtomicLong ;
36
39
import java .util .concurrent .atomic .AtomicReference ;
37
40
import java .util .function .Consumer ;
38
- import java .util .stream .Collectors ;
39
41
import java .util .stream .IntStream ;
40
42
import org .junit .jupiter .api .Test ;
41
43
import org .junit .jupiter .api .TestInfo ;
@@ -61,6 +63,10 @@ private static Map<Byte, AtomicInteger> receivedMessages(int subscriptionCount)
61
63
return receivedMessages ;
62
64
}
63
65
66
+ private static ClientParameters withConnectionName (String connectionName ) {
67
+ return new ClientParameters ().clientProperty ("connection_name" , connectionName );
68
+ }
69
+
64
70
@ Test
65
71
void secondSubscriptionShouldTakeOverAfterFirstOneUnsubscribes () throws Exception {
66
72
Client writerClient = cf .get ();
@@ -316,7 +322,7 @@ void singleActiveConsumersShouldSpreadOnSuperStreamPartitions(TestInfo info) thr
316
322
try {
317
323
declareSuperStreamTopology (c , superStream , 3 );
318
324
List <String > partitions =
319
- IntStream .range (0 , 3 ).mapToObj (i -> superStream + "-" + i ).collect (Collectors . toList ());
325
+ IntStream .range (0 , 3 ).mapToObj (i -> superStream + "-" + i ).collect (toList ());
320
326
ConsumerUpdateListener consumerUpdateListener =
321
327
(client1 , subscriptionId , active ) -> {
322
328
consumerStates .put (subscriptionId , active );
@@ -395,4 +401,50 @@ void singleActiveConsumersShouldSpreadOnSuperStreamPartitions(TestInfo info) thr
395
401
deleteSuperStreamTopology (c , superStream , 3 );
396
402
}
397
403
}
404
+
405
+ @ Test
406
+ @ DisabledIfRabbitMqCtlNotSet
407
+ void killingConnectionsShouldTriggerConsumerUpdateNotification () throws Exception {
408
+ Map <String , Boolean > consumerStates = new ConcurrentHashMap <>();
409
+ List <String > consumerNames = IntStream .range (0 , 5 ).mapToObj (i -> "foo-" + i ).collect (toList ());
410
+ for (String consumerName : consumerNames ) {
411
+ Client c0 =
412
+ cf .get (
413
+ withConnectionName (consumerName + "-connection-0" )
414
+ .consumerUpdateListener (
415
+ (client , subscriptionId , active ) -> {
416
+ consumerStates .put (consumerName + "-connection-0" , active );
417
+ return null ;
418
+ }));
419
+ Client c1 =
420
+ cf .get (
421
+ withConnectionName (consumerName + "-connection-1" )
422
+ .consumerUpdateListener (
423
+ (client , subscriptionId , active ) -> {
424
+ consumerStates .put (consumerName + "-connection-1" , active );
425
+ return null ;
426
+ }));
427
+
428
+ Map <String , String > subscriptionProperties = new HashMap <>();
429
+ subscriptionProperties .put ("single-active-consumer" , "true" );
430
+ subscriptionProperties .put ("name" , consumerName );
431
+
432
+ Response response =
433
+ c0 .subscribe (b (0 ), stream , OffsetSpecification .first (), 2 , subscriptionProperties );
434
+ assertThat (response ).is (ok ());
435
+ waitAtMost (() -> consumerStates .containsKey (consumerName + "-connection-0" ));
436
+ response = c1 .subscribe (b (0 ), stream , OffsetSpecification .first (), 2 , subscriptionProperties );
437
+ assertThat (response ).is (ok ());
438
+ response = c0 .subscribe (b (1 ), stream , OffsetSpecification .first (), 2 , subscriptionProperties );
439
+ assertThat (response ).is (ok ());
440
+ }
441
+
442
+ for (String consumerName : consumerNames ) {
443
+ Host .killConnection (consumerName + "-connection-0" );
444
+ waitAtMost (
445
+ () ->
446
+ consumerStates .containsKey (consumerName + "-connection-1" )
447
+ && consumerStates .get (consumerName + "-connection-1" ));
448
+ }
449
+ }
398
450
}
0 commit comments