diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/DynamicJmsTemplate.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/DynamicJmsTemplate.java index 98ec5fcf02..0d64fc8bff 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/DynamicJmsTemplate.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/DynamicJmsTemplate.java @@ -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(); diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java index ce442cef2a..d8f77dad65 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java @@ -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(); diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java index cac350bd6f..196404d04d 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java @@ -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(); } diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsParserUtils.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsParserUtils.java index 9a703063b0..5270cc906f 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsParserUtils.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsParserUtils.java @@ -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(); } diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParserTests.java b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParserTests.java index 3fa6f2537d..ec5a3ec0dc 100644 --- a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParserTests.java +++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParserTests.java @@ -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()); + } } } diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/dsl/JmsTests.java b/spring-integration-jms/src/test/java/org/springframework/integration/jms/dsl/JmsTests.java index ffa3c0c0ee..2c0e593992 100644 --- a/spring-integration-jms/src/test/java/org/springframework/integration/jms/dsl/JmsTests.java +++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/dsl/JmsTests.java @@ -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 diff --git a/src/reference/asciidoc/jms.adoc b/src/reference/asciidoc/jms.adoc index 430995d60f..81bfa6d913 100644 --- a/src/reference/asciidoc/jms.adoc +++ b/src/reference/asciidoc/jms.adoc @@ -55,6 +55,8 @@ If instead you prefer to have the raw JMS Message as the Spring Integration Mess ---- +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