Skip to content

Commit a2119b3

Browse files
garyrussellartembilan
authored andcommitted
GH-1201: Fix for ChannelAwareBatchMessageListener
Resolves #1201 The previous commit did not work with `ChannelAwareBatchMessageListener`. Also add a test to get `List<o.s.a.c.Message>` in a `@RabbitListener` (which exposed this issue). **cherry-pick to 2.2.x**
1 parent 6abdd27 commit a2119b3

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/AbstractMessageListenerContainer.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import org.springframework.amqp.rabbit.connection.RabbitResourceHolder;
5757
import org.springframework.amqp.rabbit.connection.RabbitUtils;
5858
import org.springframework.amqp.rabbit.connection.RoutingConnectionFactory;
59+
import org.springframework.amqp.rabbit.listener.api.ChannelAwareBatchMessageListener;
5960
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
6061
import org.springframework.amqp.rabbit.listener.exception.FatalListenerExecutionException;
6162
import org.springframework.amqp.rabbit.listener.exception.FatalListenerStartupException;
@@ -243,6 +244,8 @@ public abstract class AbstractMessageListenerContainer extends RabbitAccessor
243244

244245
private volatile boolean lazyLoad;
245246

247+
private boolean isBatchListener;
248+
246249
@Override
247250
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
248251
this.applicationEventPublisher = applicationEventPublisher;
@@ -424,6 +427,8 @@ public void setExposeListenerChannel(boolean exposeListenerChannel) {
424427
*/
425428
public void setMessageListener(MessageListener messageListener) {
426429
this.messageListener = messageListener;
430+
this.isBatchListener = messageListener instanceof BatchMessageListener
431+
|| messageListener instanceof ChannelAwareBatchMessageListener;
427432
}
428433

429434
/**
@@ -1923,8 +1928,8 @@ private void checkPossibleAuthenticationFailureFatalFromProperty() {
19231928

19241929
@Nullable
19251930
protected List<Message> debatch(Message message) {
1926-
if (isDeBatchingEnabled() && getBatchingStrategy().canDebatch(message.getMessageProperties())
1927-
&& getMessageListener() instanceof BatchMessageListener) {
1931+
if (this.isBatchListener && isDeBatchingEnabled()
1932+
&& getBatchingStrategy().canDebatch(message.getMessageProperties())) {
19281933
final List<Message> messageList = new ArrayList<>();
19291934
getBatchingStrategy().deBatch(message, fragment -> messageList.add(fragment));
19301935
return messageList;

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@
5656
import org.springframework.amqp.rabbit.support.ListenerContainerAware;
5757
import org.springframework.amqp.rabbit.support.ListenerExecutionFailedException;
5858
import org.springframework.amqp.rabbit.support.RabbitExceptionTranslator;
59+
import org.springframework.amqp.support.ConsumerTagStrategy;
5960
import org.springframework.jmx.export.annotation.ManagedMetric;
6061
import org.springframework.jmx.support.MetricType;
62+
import org.springframework.lang.Nullable;
6163
import org.springframework.transaction.PlatformTransactionManager;
6264
import org.springframework.transaction.support.TransactionSynchronizationManager;
6365
import org.springframework.transaction.support.TransactionTemplate;
@@ -833,8 +835,9 @@ this.cancellationLock, getAcknowledgeMode(), isChannelTransacted(), actualPrefet
833835
if (this.retryDeclarationInterval != null) {
834836
consumer.setRetryDeclarationInterval(this.retryDeclarationInterval);
835837
}
836-
if (getConsumerTagStrategy() != null) {
837-
consumer.setTagStrategy(getConsumerTagStrategy()); // NOSONAR never null here
838+
ConsumerTagStrategy consumerTagStrategy = getConsumerTagStrategy();
839+
if (consumerTagStrategy != null) {
840+
consumer.setTagStrategy(consumerTagStrategy);
838841
}
839842
consumer.setBackOffExecution(getRecoveryBackOff().start());
840843
consumer.setShutdownTimeout(getShutdownTimeout());
@@ -1098,7 +1101,7 @@ protected void handleStartupFailure(BackOffExecution backOffExecution) {
10981101
}
10991102

11001103
@Override
1101-
protected void publishConsumerFailedEvent(String reason, boolean fatal, Throwable t) {
1104+
protected void publishConsumerFailedEvent(String reason, boolean fatal, @Nullable Throwable t) {
11021105
if (!fatal || !isRunning()) {
11031106
super.publishConsumerFailedEvent(reason, fatal, t);
11041107
}

spring-rabbit/src/test/java/org/springframework/amqp/rabbit/annotation/EnableRabbitBatchIntegrationTests.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 the original author or authors.
2+
* Copyright 2019-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
3434
import org.springframework.amqp.rabbit.junit.RabbitAvailable;
3535
import org.springframework.amqp.rabbit.junit.RabbitAvailableCondition;
3636
import org.springframework.amqp.support.AmqpHeaders;
37+
import org.springframework.amqp.support.converter.SimpleMessageConverter;
3738
import org.springframework.beans.factory.annotation.Autowired;
3839
import org.springframework.context.annotation.Bean;
3940
import org.springframework.context.annotation.Configuration;
@@ -50,7 +51,7 @@
5051
*/
5152
@SpringJUnitConfig
5253
@DirtiesContext
53-
@RabbitAvailable(queues = { "batch.1", "batch.2", "batch.3" })
54+
@RabbitAvailable(queues = { "batch.1", "batch.2", "batch.3", "batch.4" })
5455
public class EnableRabbitBatchIntegrationTests {
5556

5657
@Autowired
@@ -99,6 +100,20 @@ public void simpleListConsumerAndProducerBatching() throws InterruptedException
99100
assertThat(this.listener.foosConsumerBatchToo.get(3).getBar()).isEqualTo("qux");
100101
}
101102

103+
@Test
104+
public void nativeMessageList() throws InterruptedException {
105+
this.template.convertAndSend("batch.4", new Foo("foo"));
106+
this.template.convertAndSend("batch.4", new Foo("bar"));
107+
assertThat(this.listener.nativeMessagesLatch.await(10, TimeUnit.SECONDS)).isTrue();
108+
assertThat(this.listener.nativeMessages).hasSize(2);
109+
Foo payload = (Foo) new SimpleMessageConverter().fromMessage(this.listener.nativeMessages.get(0));
110+
assertThat(payload.getBar()).isEqualTo("foo");
111+
assertThat(this.listener.nativeMessages.get(1).getMessageProperties()
112+
.getHeaders()
113+
.get(AmqpHeaders.BATCH_SIZE))
114+
.isEqualTo(2);
115+
}
116+
102117
@Configuration
103118
@EnableRabbit
104119
public static class Config {
@@ -116,6 +131,11 @@ public DirectRabbitListenerContainerFactory directListenerContainerFactory() {
116131
DirectRabbitListenerContainerFactory factory = new DirectRabbitListenerContainerFactory();
117132
factory.setConnectionFactory(connectionFactory());
118133
factory.setBatchListener(true);
134+
factory.setContainerCustomizer(container -> {
135+
if (container.getQueueNames()[0].equals("batch.4")) {
136+
container.setDeBatchingEnabled(true);
137+
}
138+
});
119139
return factory;
120140
}
121141

@@ -166,6 +186,10 @@ public static class Listener {
166186

167187
CountDownLatch fooConsumerBatchTooLatch = new CountDownLatch(1);
168188

189+
private List<org.springframework.amqp.core.Message> nativeMessages;
190+
191+
private final CountDownLatch nativeMessagesLatch = new CountDownLatch(1);
192+
169193
@RabbitListener(queues = "batch.1")
170194
public void listen1(List<Foo> in) {
171195
this.foos = in;
@@ -184,6 +208,12 @@ public void listen3(List<Foo> in) {
184208
this.fooConsumerBatchTooLatch.countDown();
185209
}
186210

211+
@RabbitListener(queues = "batch.4", containerFactory = "directListenerContainerFactory")
212+
public void listen4(List<org.springframework.amqp.core.Message> in) {
213+
this.nativeMessages = in;
214+
this.nativeMessagesLatch.countDown();
215+
}
216+
187217
}
188218

189219
@SuppressWarnings("serial")

0 commit comments

Comments
 (0)