|
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.MessagePostProcessor; |
@@ -650,6 +654,49 @@ public Message postProcessMessage(Message message) throws AmqpException { |
650 | 654 | assertThat(afterReceivePostProcessors).containsExactly(mpp2, mpp3); |
651 | 655 | } |
652 | 656 |
|
| 657 | + @Test |
| 658 | + void filterMppNoDoubleAck() throws Exception { |
| 659 | + ConnectionFactory connectionFactory = mock(ConnectionFactory.class); |
| 660 | + Connection connection = mock(Connection.class); |
| 661 | + Channel channel = mock(Channel.class); |
| 662 | + given(connectionFactory.createConnection()).willReturn(connection); |
| 663 | + given(connection.createChannel(false)).willReturn(channel); |
| 664 | + final AtomicReference<Consumer> consumer = new AtomicReference<>(); |
| 665 | + willAnswer(invocation -> { |
| 666 | + consumer.set(invocation.getArgument(6)); |
| 667 | + consumer.get().handleConsumeOk("1"); |
| 668 | + return "1"; |
| 669 | + }).given(channel) |
| 670 | + .basicConsume(anyString(), anyBoolean(), anyString(), anyBoolean(), anyBoolean(), anyMap(), |
| 671 | + any(Consumer.class)); |
| 672 | + final CountDownLatch latch = new CountDownLatch(1); |
| 673 | + willAnswer(invocation -> { |
| 674 | + latch.countDown(); |
| 675 | + return null; |
| 676 | + }).given(channel).basicAck(anyLong(), anyBoolean()); |
| 677 | + |
| 678 | + final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); |
| 679 | + container.setAfterReceivePostProcessors(msg -> null); |
| 680 | + container.setQueueNames("foo"); |
| 681 | + MessageListener listener = mock(BatchMessageListener.class); |
| 682 | + container.setMessageListener(listener); |
| 683 | + container.setBatchSize(2); |
| 684 | + container.setConsumerBatchEnabled(true); |
| 685 | + container.start(); |
| 686 | + BasicProperties props = new BasicProperties(); |
| 687 | + byte[] payload = "baz".getBytes(); |
| 688 | + Envelope envelope = new Envelope(1L, false, "foo", "bar"); |
| 689 | + consumer.get().handleDelivery("1", envelope, props, payload); |
| 690 | + envelope = new Envelope(2L, false, "foo", "bar"); |
| 691 | + consumer.get().handleDelivery("1", envelope, props, payload); |
| 692 | + assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue(); |
| 693 | + verify(channel, never()).basicAck(eq(1), anyBoolean()); |
| 694 | + verify(channel).basicAck(2, true); |
| 695 | + container.stop(); |
| 696 | + verify(listener).containerAckMode(AcknowledgeMode.AUTO); |
| 697 | + verifyNoMoreInteractions(listener); |
| 698 | + } |
| 699 | + |
653 | 700 | private Answer<Object> messageToConsumer(final Channel mockChannel, final SimpleMessageListenerContainer container, |
654 | 701 | final boolean cancel, final CountDownLatch latch) { |
655 | 702 | return invocation -> { |
|
0 commit comments