26
26
import static org .mockito .ArgumentMatchers .anyLong ;
27
27
import static org .mockito .ArgumentMatchers .anyMap ;
28
28
import static org .mockito .ArgumentMatchers .anyString ;
29
+ import static org .mockito .ArgumentMatchers .eq ;
29
30
import static org .mockito .BDDMockito .given ;
30
31
import static org .mockito .BDDMockito .willAnswer ;
31
32
import static org .mockito .BDDMockito .willReturn ;
32
33
import static org .mockito .BDDMockito .willThrow ;
33
34
import static org .mockito .Mockito .atLeastOnce ;
34
35
import static org .mockito .Mockito .mock ;
36
+ import static org .mockito .Mockito .never ;
35
37
import static org .mockito .Mockito .spy ;
36
38
import static org .mockito .Mockito .times ;
37
39
import static org .mockito .Mockito .verify ;
40
+ import static org .mockito .Mockito .verifyNoMoreInteractions ;
38
41
39
42
import java .io .IOException ;
40
43
import java .net .URL ;
67
70
import org .springframework .amqp .ImmediateAcknowledgeAmqpException ;
68
71
import org .springframework .amqp .core .AcknowledgeMode ;
69
72
import org .springframework .amqp .core .AnonymousQueue ;
73
+ import org .springframework .amqp .core .BatchMessageListener ;
70
74
import org .springframework .amqp .core .Message ;
71
75
import org .springframework .amqp .core .MessageBuilder ;
72
76
import org .springframework .amqp .core .MessageListener ;
@@ -651,6 +655,7 @@ public Message postProcessMessage(Message message) throws AmqpException {
651
655
assertThat (afterReceivePostProcessors ).containsExactly (mpp2 , mpp3 );
652
656
}
653
657
658
+ @ SuppressWarnings ("unchecked" )
654
659
@ Test
655
660
void setConcurrency () throws Exception {
656
661
ConnectionFactory connectionFactory = mock (ConnectionFactory .class );
@@ -676,6 +681,49 @@ void setConcurrency() throws Exception {
676
681
assertThat (TestUtils .getPropertyValue (container , "consumers" , Collection .class )).hasSize (10 );
677
682
}
678
683
684
+ @ Test
685
+ void filterMppNoDoubleAck () throws Exception {
686
+ ConnectionFactory connectionFactory = mock (ConnectionFactory .class );
687
+ Connection connection = mock (Connection .class );
688
+ Channel channel = mock (Channel .class );
689
+ given (connectionFactory .createConnection ()).willReturn (connection );
690
+ given (connection .createChannel (false )).willReturn (channel );
691
+ final AtomicReference <Consumer > consumer = new AtomicReference <>();
692
+ willAnswer (invocation -> {
693
+ consumer .set (invocation .getArgument (6 ));
694
+ consumer .get ().handleConsumeOk ("1" );
695
+ return "1" ;
696
+ }).given (channel )
697
+ .basicConsume (anyString (), anyBoolean (), anyString (), anyBoolean (), anyBoolean (), anyMap (),
698
+ any (Consumer .class ));
699
+ final CountDownLatch latch = new CountDownLatch (1 );
700
+ willAnswer (invocation -> {
701
+ latch .countDown ();
702
+ return null ;
703
+ }).given (channel ).basicAck (anyLong (), anyBoolean ());
704
+
705
+ final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer (connectionFactory );
706
+ container .setAfterReceivePostProcessors (msg -> null );
707
+ container .setQueueNames ("foo" );
708
+ MessageListener listener = mock (BatchMessageListener .class );
709
+ container .setMessageListener (listener );
710
+ container .setBatchSize (2 );
711
+ container .setConsumerBatchEnabled (true );
712
+ container .start ();
713
+ BasicProperties props = new BasicProperties ();
714
+ byte [] payload = "baz" .getBytes ();
715
+ Envelope envelope = new Envelope (1L , false , "foo" , "bar" );
716
+ consumer .get ().handleDelivery ("1" , envelope , props , payload );
717
+ envelope = new Envelope (2L , false , "foo" , "bar" );
718
+ consumer .get ().handleDelivery ("1" , envelope , props , payload );
719
+ assertThat (latch .await (5 , TimeUnit .SECONDS )).isTrue ();
720
+ verify (channel , never ()).basicAck (eq (1 ), anyBoolean ());
721
+ verify (channel ).basicAck (2 , true );
722
+ container .stop ();
723
+ verify (listener ).containerAckMode (AcknowledgeMode .AUTO );
724
+ verifyNoMoreInteractions (listener );
725
+ }
726
+
679
727
private Answer <Object > messageToConsumer (final Channel mockChannel , final SimpleMessageListenerContainer container ,
680
728
final boolean cancel , final CountDownLatch latch ) {
681
729
return invocation -> {
0 commit comments