2626import static org .mockito .ArgumentMatchers .anyLong ;
2727import static org .mockito .ArgumentMatchers .anyMap ;
2828import static org .mockito .ArgumentMatchers .anyString ;
29+ import static org .mockito .ArgumentMatchers .eq ;
2930import static org .mockito .BDDMockito .given ;
3031import static org .mockito .BDDMockito .willAnswer ;
3132import static org .mockito .BDDMockito .willReturn ;
3233import static org .mockito .BDDMockito .willThrow ;
3334import static org .mockito .Mockito .atLeastOnce ;
3435import static org .mockito .Mockito .mock ;
36+ import static org .mockito .Mockito .never ;
3537import static org .mockito .Mockito .spy ;
3638import static org .mockito .Mockito .times ;
3739import static org .mockito .Mockito .verify ;
40+ import static org .mockito .Mockito .verifyNoMoreInteractions ;
3841
3942import java .io .IOException ;
4043import java .net .URL ;
6770import org .springframework .amqp .ImmediateAcknowledgeAmqpException ;
6871import org .springframework .amqp .core .AcknowledgeMode ;
6972import org .springframework .amqp .core .AnonymousQueue ;
73+ import org .springframework .amqp .core .BatchMessageListener ;
7074import org .springframework .amqp .core .Message ;
7175import org .springframework .amqp .core .MessageBuilder ;
7276import org .springframework .amqp .core .MessageListener ;
@@ -651,6 +655,7 @@ public Message postProcessMessage(Message message) throws AmqpException {
651655 assertThat (afterReceivePostProcessors ).containsExactly (mpp2 , mpp3 );
652656 }
653657
658+ @ SuppressWarnings ("unchecked" )
654659 @ Test
655660 void setConcurrency () throws Exception {
656661 ConnectionFactory connectionFactory = mock (ConnectionFactory .class );
@@ -676,6 +681,49 @@ void setConcurrency() throws Exception {
676681 assertThat (TestUtils .getPropertyValue (container , "consumers" , Collection .class )).hasSize (10 );
677682 }
678683
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+
679727 private Answer <Object > messageToConsumer (final Channel mockChannel , final SimpleMessageListenerContainer container ,
680728 final boolean cancel , final CountDownLatch latch ) {
681729 return invocation -> {
0 commit comments