INT-4519: Improve JMS inbound-c-a receiveTimeout (#2540)

* INT-4519: Improve JMS inbound-c-a receiveTimeout

JIRA: https://jira.spring.io/browse/INT-4519

* Modify `DynamicJmsTemplate` to default for `-1` if we get
`CachingConnectionFactory` and it is with `cacheConsumers`, otherwise
1 second
* Polishing for some JMS XML parsers, in particular remove
`receiveTimeout` population

**Cherry-pick to 5.0.x**

* * Polishing according PR comments

* * Properly use a `CachingConnectionFactory` in `JmsTests`
This commit is contained in:
Artem Bilan
2018-08-20 13:44:19 -04:00
committed by Gary Russell
parent 15eae700a3
commit 56ce348b2b
7 changed files with 164 additions and 118 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,11 @@
package org.springframework.integration.jms;
import javax.jms.ConnectionFactory;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.destination.JmsDestinationAccessor;
import org.springframework.util.Assert;
/**
@@ -27,6 +31,30 @@ import org.springframework.util.Assert;
*/
public class DynamicJmsTemplate extends JmsTemplate {
private static final long NO_CACHING_RECEIVE_TIMEOUT = 1000L;
private boolean receiveTimeoutExplicitlySet;
@Override
public void setReceiveTimeout(long receiveTimeout) {
super.setReceiveTimeout(receiveTimeout);
this.receiveTimeoutExplicitlySet = true;
}
@Override
public void setConnectionFactory(ConnectionFactory connectionFactory) {
super.setConnectionFactory(connectionFactory);
if (!this.receiveTimeoutExplicitlySet) {
if (connectionFactory instanceof CachingConnectionFactory &&
((CachingConnectionFactory) connectionFactory).isCacheConsumers()) {
super.setReceiveTimeout(JmsDestinationAccessor.RECEIVE_TIMEOUT_NO_WAIT);
}
else {
super.setReceiveTimeout(NO_CACHING_RECEIVE_TIMEOUT);
}
}
}
@Override
public int getPriority() {
Integer priority = DynamicJmsTemplateProperties.getPriority();

View File

@@ -54,7 +54,6 @@ public class JmsInboundChannelAdapterParser extends AbstractPollingInboundChanne
String jmsTemplate = element.getAttribute(JmsParserUtils.JMS_TEMPLATE_ATTRIBUTE);
String destination = element.getAttribute(JmsParserUtils.DESTINATION_ATTRIBUTE);
String destinationName = element.getAttribute(JmsParserUtils.DESTINATION_NAME_ATTRIBUTE);
String headerMapper = element.getAttribute(JmsParserUtils.HEADER_MAPPER_ATTRIBUTE);
boolean hasJmsTemplate = StringUtils.hasText(jmsTemplate);
boolean hasDestinationRef = StringUtils.hasText(destination);
boolean hasDestinationName = StringUtils.hasText(destinationName);
@@ -84,9 +83,7 @@ public class JmsInboundChannelAdapterParser extends AbstractPollingInboundChanne
+ JmsParserUtils.DESTINATION_NAME_ATTRIBUTE +
"' attributes must be provided for a polling JMS adapter", parserContext.extractSource(element));
}
if (StringUtils.hasText(headerMapper)) {
builder.addPropertyReference(JmsParserUtils.HEADER_MAPPER_PROPERTY, headerMapper);
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, JmsParserUtils.HEADER_MAPPER_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "selector", "messageSelector");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-payload");
return builder.getBeanDefinition();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import org.springframework.util.StringUtils;
*
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*/
public class JmsOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
@@ -42,7 +43,6 @@ public class JmsOutboundChannelAdapterParser extends AbstractOutboundChannelAdap
String destination = element.getAttribute(JmsParserUtils.DESTINATION_ATTRIBUTE);
String destinationName = element.getAttribute(JmsParserUtils.DESTINATION_NAME_ATTRIBUTE);
String destinationExpression = element.getAttribute(JmsParserUtils.DESTINATION_EXPRESSION_ATTRIBUTE);
String headerMapper = element.getAttribute(JmsParserUtils.HEADER_MAPPER_ATTRIBUTE);
boolean hasJmsTemplate = StringUtils.hasText(jmsTemplate);
boolean hasDestinationRef = StringUtils.hasText(destination);
boolean hasDestinationName = StringUtils.hasText(destinationName);
@@ -79,9 +79,8 @@ public class JmsOutboundChannelAdapterParser extends AbstractOutboundChannelAdap
JmsParserUtils.DESTINATION_EXPRESSION_ATTRIBUTE +
"' attributes must be provided", parserContext.extractSource(element));
}
if (StringUtils.hasText(headerMapper)) {
builder.addPropertyReference(JmsParserUtils.HEADER_MAPPER_PROPERTY, headerMapper);
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, JmsParserUtils.HEADER_MAPPER_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-payload");
return builder.getBeanDefinition();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.jms.DynamicJmsTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.util.StringUtils;
/**
@@ -31,6 +30,7 @@ import org.springframework.util.StringUtils;
*
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*/
abstract class JmsParserUtils {
@@ -63,7 +63,7 @@ abstract class JmsParserUtils {
static final String HEADER_MAPPER_PROPERTY = "headerMapper";
private static final String[] JMS_TEMPLATE_ATTRIBUTES = {
"connection-factory", "message-converter", "destination-resolver", "pub-sub-domain",
CONNECTION_FACTORY_ATTRIBUTE, "message-converter", "destination-resolver", PUB_SUB_DOMAIN_ATTRIBUTE,
"time-to-live", "priority", "delivery-persistent", "explicit-qos-enabled", "acknowledge",
"receive-timeout", "session-transacted"
};
@@ -86,18 +86,12 @@ abstract class JmsParserUtils {
determineConnectionFactoryBeanName(element, parserContext));
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converter");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "destination-resolver");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "pub-sub-domain");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, PUB_SUB_DOMAIN_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "time-to-live");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "priority");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "delivery-persistent");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "explicit-qos-enabled");
String receiveTimeout = element.getAttribute("receive-timeout");
if (StringUtils.hasText(receiveTimeout)) {
builder.addPropertyValue("receiveTimeout", receiveTimeout);
}
else {
builder.addPropertyValue("receiveTimeout", JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT);
}
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "receive-timeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "session-transacted");
return builder.getBeanDefinition();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@ import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.jms.JmsDestinationPollingSource;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.messaging.Message;
@@ -46,53 +47,62 @@ public class JmsInboundChannelAdapterParserTests {
@Test
public void adapterWithJmsTemplate() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithJmsTemplate.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
MessageHistory history = MessageHistory.read(message);
assertNotNull(history);
Properties componentHistoryRecord = TestUtils.locateComponentInHistory(history, "inboundAdapter", 0);
assertNotNull(componentHistoryRecord);
assertEquals("jms:inbound-channel-adapter", componentHistoryRecord.get("type"));
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithJmsTemplate.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
MessageHistory history = MessageHistory.read(message);
assertNotNull(history);
Properties componentHistoryRecord = TestUtils.locateComponentInHistory(history, "inboundAdapter", 0);
assertNotNull(componentHistoryRecord);
assertEquals("jms:inbound-channel-adapter", componentHistoryRecord.get("type"));
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
}
}
@Test
public void adapterWithoutJmsTemplateAndAcknowlegeMode() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithJmsTemplate.xml", this.getClass());
JmsTemplate jmsTemplate =
TestUtils.getPropertyValue(context.getBean("inboundAdapterWithoutJmsTemplate"),
"source.jmsTemplate", JmsTemplate.class);
assertTrue(jmsTemplate.isSessionTransacted());
context.close();
public void adapterWithoutJmsTemplateAndAcknowledgeMode() {
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithJmsTemplate.xml", this.getClass())) {
JmsTemplate jmsTemplate =
TestUtils.getPropertyValue(context.getBean("inboundAdapterWithoutJmsTemplate"),
"source.jmsTemplate", JmsTemplate.class);
assertTrue(jmsTemplate.isSessionTransacted());
}
}
@Test
public void adapterWithConnectionFactoryAndDestination() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithConnectionFactoryAndDestination.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
assertFalse(TestUtils.getPropertyValue(context.getBean("adapter"), "source.jmsTemplate", JmsTemplate.class)
.isSessionTransacted());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithConnectionFactoryAndDestination.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
assertFalse(TestUtils.getPropertyValue(context.getBean("adapter"), "source.jmsTemplate", JmsTemplate.class)
.isSessionTransacted());
}
}
@Test
public void adapterWithConnectionFactoryAndDestinationName() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithConnectionFactoryAndDestinationName.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithConnectionFactoryAndDestinationName.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(this.timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
JmsDestinationPollingSource jmsDestinationPollingSource = context
.getBean(JmsDestinationPollingSource.class);
JmsTemplate jmsTemplate =
TestUtils.getPropertyValue(jmsDestinationPollingSource, "jmsTemplate", JmsTemplate.class);
assertEquals(1000, jmsTemplate.getReceiveTimeout());
}
}
@Test(expected = BeanDefinitionStoreException.class)
@@ -114,13 +124,14 @@ public class JmsInboundChannelAdapterParserTests {
@Test
public void testAdapterWithDestinationAndDefaultConnectionFactory() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithDestinationAndDefaultConnectionFactory.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithDestinationAndDefaultConnectionFactory.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
}
}
@Test(expected = BeanCreationException.class)
@@ -130,69 +141,75 @@ public class JmsInboundChannelAdapterParserTests {
@Test
public void adapterWithDestinationNameAndDefaultConnectionFactory() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithDestinationNameAndDefaultConnectionFactory.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithDestinationNameAndDefaultConnectionFactory.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
}
}
@Test
public void adapterWithHeaderMapper() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithHeaderMapper.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
assertEquals("foo", message.getHeaders().get("testProperty"));
assertEquals(123, message.getHeaders().get("testAttribute"));
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithHeaderMapper.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("polling-test", message.getPayload());
assertEquals("foo", message.getHeaders().get("testProperty"));
assertEquals(123, message.getHeaders().get("testAttribute"));
}
}
@Test
public void adapterWithMessageSelector() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithMessageSelector.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output1");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("test [with selector: TestProperty = 'foo']", message.getPayload());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithMessageSelector.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output1");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("test [with selector: TestProperty = 'foo']", message.getPayload());
}
}
@Test
public void pollingAdapterWithReceiveTimeout() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithReceiveTimeout.xml", this.getClass());
JmsTemplate jmsTemplate =
TestUtils.getPropertyValue(context.getBean("adapter"), "source.jmsTemplate", JmsTemplate.class);
assertEquals(99, jmsTemplate.getReceiveTimeout());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithReceiveTimeout.xml", this.getClass())) {
JmsTemplate jmsTemplate =
TestUtils.getPropertyValue(context.getBean("adapter"), "source.jmsTemplate", JmsTemplate.class);
assertEquals(99, jmsTemplate.getReceiveTimeout());
}
}
@Test
public void pollingAdapterWithMessageConverter() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithMessageConverter.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output1");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("converted-test", message.getPayload());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithMessageConverter.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output1");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("converted-test", message.getPayload());
}
}
@Test
public void messageDrivenAdapterWithMessageConverter() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithMessageConverter.xml", this.getClass());
PollableChannel output = (PollableChannel) context.getBean("output2");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("converted-test", message.getPayload());
context.close();
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"jmsInboundWithMessageConverter.xml", this.getClass())) {
PollableChannel output = (PollableChannel) context.getBean("output2");
Message<?> message = output.receive(timeoutOnReceive);
assertNotNull("message should not be null", message);
assertEquals("converted-test", message.getPayload());
}
}
}

View File

@@ -60,6 +60,7 @@ import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.Pollers;
import org.springframework.integration.dsl.channel.MessageChannels;
import org.springframework.integration.endpoint.MethodInvokingMessageSource;
import org.springframework.integration.jms.JmsDestinationPollingSource;
import org.springframework.integration.scheduling.PollerMetadata;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
@@ -108,6 +109,9 @@ public class JmsTests {
@Qualifier("jmsOutboundInboundReplyChannel")
private PollableChannel jmsOutboundInboundReplyChannel;
@Autowired
private JmsDestinationPollingSource jmsDestinationPollingSource;
@Autowired
@Qualifier("jmsOutboundGatewayFlow.input")
private MessageChannel jmsOutboundGatewayChannel;
@@ -161,6 +165,11 @@ public class JmsTests {
@Test
public void testJmsOutboundInboundFlow() {
JmsTemplate jmsTemplate =
TestUtils.getPropertyValue(this.jmsDestinationPollingSource, "jmsTemplate", JmsTemplate.class);
assertEquals(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT, jmsTemplate.getReceiveTimeout());
this.jmsOutboundInboundChannel.send(MessageBuilder.withPayload("hello THROUGH the JMS")
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "jmsInbound")
.build());
@@ -247,11 +256,6 @@ public class JmsTests {
@ComponentScan
public static class ContextConfiguration {
@Bean
public ConnectionFactory cachingConnectionFactory() {
return new CachingConnectionFactory(jmsConnectionFactory());
}
@Bean
public ActiveMQConnectionFactory jmsConnectionFactory() {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
@@ -260,9 +264,14 @@ public class JmsTests {
return activeMQConnectionFactory;
}
@Bean
public ConnectionFactory cachingConnectionFactory() {
return new CachingConnectionFactory(jmsConnectionFactory());
}
@Bean
public JmsTemplate jmsTemplate() {
return new JmsTemplate(jmsConnectionFactory());
return new JmsTemplate(cachingConnectionFactory());
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
@@ -296,7 +305,7 @@ public class JmsTests {
@Bean
public IntegrationFlow jmsOutboundFlow() {
return f -> f
.handle(Jms.outboundAdapter(jmsConnectionFactory())
.handle(Jms.outboundAdapter(cachingConnectionFactory())
.destinationExpression("headers." + SimpMessageHeaderAccessor.DESTINATION_HEADER)
.configureJmsTemplate(t -> t.id("jmsOutboundFlowTemplate")));
}
@@ -318,7 +327,7 @@ public class JmsTests {
@Bean
public IntegrationFlow pubSubFlow() {
return IntegrationFlows
.from(Jms.publishSubscribeChannel(jmsConnectionFactory())
.from(Jms.publishSubscribeChannel(cachingConnectionFactory())
.destination("pubsub"))
.channel(c -> c.queue("jmsPubSubBridgeChannel"))
.get();
@@ -371,7 +380,7 @@ public class JmsTests {
@Bean
public IntegrationFlow jmsOutboundGatewayFlow() {
return f -> f.handle(Jms.outboundGateway(jmsConnectionFactory())
return f -> f.handle(Jms.outboundGateway(cachingConnectionFactory())
.replyContainer(c -> c.idleReplyContainerTimeout(10))
.requestDestination("jmsPipelineTest"),
e -> e.id("jmsOutboundGateway"));
@@ -412,7 +421,7 @@ public class JmsTests {
@Bean
public IntegrationFlow jmsMessageDrivenRedeliveryFlow() {
return IntegrationFlows
.from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory())
.from(Jms.messageDrivenChannelAdapter(cachingConnectionFactory())
.errorChannel(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
.destination("jmsMessageDrivenRedelivery")
.configureListenerContainer(c -> c

View File

@@ -55,6 +55,8 @@ If instead you prefer to have the raw JMS Message as the Spring Integration Mess
</int-jms:inbound-channel-adapter>
----
Starting with version 5.0.8, a default value of the `receive-timeout` is `-1` (no wait) for the `org.springframework.jms.connection.CachingConnectionFactory` and `cacheConsumers`, otherwise it is 1 second.
[[jms-ib-transactions]]
==== Transactions