diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java index 409b742079..57e4e5a241 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -82,6 +82,8 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp private volatile String replyDestinationName; + private volatile ExpressionEvaluatingMessageProcessor replyDestinationExpressionProcessor; + private volatile DestinationResolver destinationResolver = new DynamicDestinationResolver(); private volatile boolean requestPubSubDomain; @@ -184,6 +186,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp * 'requestDestinationName' is required. */ public void setRequestDestinationExpression(Expression requestDestinationExpression) { + Assert.notNull(requestDestinationExpression, "'requestDestinationExpression' must not be null"); this.requestDestinationExpressionProcessor = new ExpressionEvaluatingMessageProcessor(requestDestinationExpression); } @@ -206,6 +209,16 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp this.replyDestinationName = replyDestinationName; } + /** + * Set the SpEL Expression to be used for determining the reply Destination instance + * or reply destination name. Either this or one of 'replyDestination' or + * 'replyDestinationName' is required. + */ + public void setReplyDestinationExpression(Expression replyDestinationExpression) { + Assert.notNull(replyDestinationExpression, "'replyDestinationExpression' must not be null"); + this.replyDestinationExpressionProcessor = new ExpressionEvaluatingMessageProcessor(replyDestinationExpression); + } + /** * Provide the {@link DestinationResolver} to use when resolving either a * 'requestDestinationName' or 'replyDestinationName' value. The default @@ -369,7 +382,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp this.useReplyContainer = useReplyContainer; } - private Destination getRequestDestination(Message message, Session session) throws JMSException { + private Destination determineRequestDestination(Message message, Session session) throws JMSException { if (this.requestDestination != null) { return this.requestDestination; } @@ -398,19 +411,34 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp session, requestDestinationName, this.requestPubSubDomain); } - private Destination determineReplyDestination(Session session) throws JMSException { + private Destination determineReplyDestination(Message message, Session session) throws JMSException { if (this.replyDestination != null) { return this.replyDestination; } if (this.replyDestinationName != null) { - Assert.notNull(this.destinationResolver, - "DestinationResolver is required when relying upon the 'replyDestinationName' property."); - return this.destinationResolver.resolveDestinationName( - session, this.replyDestinationName, this.replyPubSubDomain); + return this.resolveReplyDestination(this.replyDestinationName, session); + } + if (this.replyDestinationExpressionProcessor != null) { + Object result = this.replyDestinationExpressionProcessor.processMessage(message); + if (result instanceof Destination) { + return (Destination) result; + } + if (result instanceof String) { + return this.resolveReplyDestination((String) result, session); + } + throw new MessageDeliveryException(message, + "Evaluation of replyDestinationExpression failed to produce a Destination or destination name. Result was: " + result); } return session.createTemporaryQueue(); } + private Destination resolveReplyDestination(String replyDestinationName, Session session) throws JMSException { + Assert.notNull(this.destinationResolver, + "DestinationResolver is required when relying upon the 'replyDestinationName' property."); + return this.destinationResolver.resolveDestinationName( + session, replyDestinationName, this.replyPubSubDomain); + } + public int getPhase() { return Integer.MAX_VALUE; } @@ -439,14 +467,19 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp this.requestDestinationExpressionProcessor.setBeanFactory(getBeanFactory()); this.requestDestinationExpressionProcessor.setConversionService(getConversionService()); } + if (this.replyDestinationExpressionProcessor != null) { + this.replyDestinationExpressionProcessor.setBeanFactory(getBeanFactory()); + this.replyDestinationExpressionProcessor.setConversionService(getConversionService()); + } /* * This is needed because there is no way to detect 2 or more gateways using the same reply queue * with no correlation key. */ if (this.useReplyContainer && (this.correlationKey == null && - (this.replyDestination != null || this.replyDestinationName != null))) { + (this.replyDestination != null || this.replyDestinationName != null) || + this.replyDestinationExpressionProcessor != null)) { if (logger.isWarnEnabled()) { - logger.warn("The gateway cannot use a reply listener container with a specified destination(Name) " + + logger.warn("The gateway cannot use a reply listener container with a specified destination(Name/Expression) " + "without a 'correlation-key'; " + "a container will NOT be used; " + "to avoid this problem, set the 'correlation-key' attribute; " + @@ -621,7 +654,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp if (priority == null) { priority = this.priority; } - Destination requestDestination = this.getRequestDestination(requestMessage, session); + Destination requestDestination = this.determineRequestDestination(requestMessage, session); /* * Remove any existing correlation id that was mapped from the inbound message @@ -667,8 +700,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp // map headers headerMapper.fromHeaders(requestMessage.getHeaders(), jmsRequest); - // TODO: support a JmsReplyTo header in the SI Message? - replyTo = this.determineReplyDestination(session); + replyTo = this.determineReplyDestination(requestMessage, session); jmsRequest.setJMSReplyTo(replyTo); connection.start(); @@ -677,7 +709,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp priority = this.priority; } javax.jms.Message replyMessage = null; - Destination requestDestination = this.getRequestDestination(requestMessage, session); + Destination requestDestination = this.determineRequestDestination(requestMessage, session); if (this.correlationKey != null) { replyMessage = this.doSendAndReceiveWithGeneratedCorrelationId(requestDestination, jmsRequest, replyTo, session, priority); } diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java index d8cbfadf54..978e62dfab 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -44,29 +44,12 @@ public class JmsOutboundGatewayParser extends AbstractConsumerEndpointParser { protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(JmsOutboundGateway.class); builder.addPropertyReference("connectionFactory", element.getAttribute("connection-factory")); - String requestDestination = element.getAttribute("request-destination"); - String requestDestinationName = element.getAttribute("request-destination-name"); - String requestDestinationExpression = element.getAttribute("request-destination-expression"); - boolean hasRequestDestination = StringUtils.hasText(requestDestination); - boolean hasRequestDestinationName = StringUtils.hasText(requestDestinationName); - boolean hasRequestDestinationExpression = StringUtils.hasText(requestDestinationExpression); - if (!(hasRequestDestination ^ hasRequestDestinationName ^ hasRequestDestinationExpression)) { - parserContext.getReaderContext().error("Exactly one of the 'request-destination', " + - "'request-destination-name', or 'request-destination-expression' attributes is required.", element); - } - if (hasRequestDestination) { - builder.addPropertyReference("requestDestination", requestDestination); - } - else if (hasRequestDestinationName) { - builder.addPropertyValue("requestDestinationName", requestDestinationName); - } - else if (hasRequestDestinationExpression) { - BeanDefinitionBuilder expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class); - expressionBuilder.addConstructorArgValue(requestDestinationExpression); - builder.addPropertyValue("requestDestinationExpression", expressionBuilder.getBeanDefinition()); - } - IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-destination"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-destination-name"); + parseDestination(element, parserContext, builder, "request-destination", "request-destination-name", + "request-destination-expression", "requestDestination", "requestDestinationName", + "requestDestinationExpression", true); + parseDestination(element, parserContext, builder, "reply-destination", "reply-destination-name", + "reply-destination-expression", "replyDestination", "replyDestinationName", + "replyDestinationExpression", false); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "correlation-key"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converter"); @@ -104,6 +87,44 @@ public class JmsOutboundGatewayParser extends AbstractConsumerEndpointParser { return builder; } + private void parseDestination(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, + String destinationAttributeName, String destinationNameAttributeName, String destinationExpressionAttributeName, + String destinationProperty, String destinationNameProperty, String destinationExpressionProperty, + boolean oneRequired) { + String destinationAttribute = element.getAttribute(destinationAttributeName); + String destinationNameAttribute = element.getAttribute(destinationNameAttributeName); + String destinationExpressionAttribute = element.getAttribute(destinationExpressionAttributeName); + boolean hasDestination = StringUtils.hasText(destinationAttribute); + boolean hasDestinationName = StringUtils.hasText(destinationNameAttribute); + boolean hasDestinationExpression = StringUtils.hasText(destinationExpressionAttribute); + int destCount = (hasDestination ? 1 : 0) + + (hasDestinationName ? 1 : 0) + + (hasDestinationExpression ? 1 : 0); + if (oneRequired) { + if (destCount != 1) { + parserContext.getReaderContext().error("Exactly one of the '" + destinationAttribute + "', " + + "'" + destinationNameAttributeName + "', or '" + destinationExpressionAttributeName + "' attributes is required.", element); + } + } + else { + if (destCount > 1) { + parserContext.getReaderContext().error("Only one of the '" + destinationAttribute + "', " + + "'" + destinationNameAttributeName + "', or '" + destinationExpressionAttributeName + "' attributes is allowed.", element); + } + } + if (hasDestination) { + builder.addPropertyReference(destinationProperty, destinationAttribute); + } + else if (hasDestinationName) { + builder.addPropertyValue(destinationNameProperty, destinationNameAttribute); + } + else if (hasDestinationExpression) { + BeanDefinitionBuilder expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class); + expressionBuilder.addConstructorArgValue(destinationExpressionAttribute); + builder.addPropertyValue(destinationExpressionProperty, expressionBuilder.getBeanDefinition()); + } + } + private void parseReplyContainer(BeanDefinitionBuilder gatewayBuilder, ParserContext parserContext, Element element) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(JmsOutboundGateway.ReplyContainerProperties.class); Integer acknowledgeMode = JmsAdapterParserUtils.parseAcknowledgeMode(element, parserContext); diff --git a/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-3.0.xsd b/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-3.0.xsd index f322cbc9e2..6bd25ed26c 100644 --- a/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-3.0.xsd +++ b/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-3.0.xsd @@ -850,7 +850,8 @@ - When resolving a request destination name (rather than having a 'request-destination' reference), + When resolving a request destination name (rather than a 'request-destination' reference or + a 'request-destination-expression' that evaluates to a destination), a true value here specifies that the DestinationResolver should resolve Topics rather than Queues. Default is false. @@ -858,11 +859,13 @@ - + A reference to a javax.jms.Destination by bean name. As an alternative to a bean reference, use 'reply-destination-name' and 'reply-pub-sub-domain' which will rely upon the DestinationResolver strategy (DynamicDestinationResolver by default). - + This attribute is mutually exclusive with + 'reply-destination-name' and 'reply-destination-expression'. + @@ -870,8 +873,36 @@ - - + + + + Name of a destination which will be used for the replyTo header. This name will be handled + by this gateway's DestinationResolver. This attribute is mutually exclusive with + 'reply-destination' and 'reply-destination-expression'. + + + + + + + A SpEL expression to be evaluated at runtime against each Spring Integration request Message as + the root object. The result should be either a Destination instance or a String representing + the destination name. In the latter case, it will be passed to this adapter's DestinationResolver + together with the reply-pub-sub-domain attribute. + This attribute is mutually exclusive with 'reply-destination' and 'reply-destination-name'. + + + + + + + When resolving a reply destination name (rather than a 'reply-destination' reference or + a 'reply-destination-expression' that evaluates to a destination), + a true value here specifies that the DestinationResolver should resolve Topics rather than Queues. + Default is false. + + + the correlation data includes a UUID + representing the gateway as well as a message identifier. For this reason, the use of a + requires the specification of a 'correlation-key' if an + explicit reply-destination is provided. ]]> diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java index 3a387bcc51..2c3a765e43 100644 --- a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java +++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -19,19 +19,29 @@ package org.springframework.integration.jms.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.lang.reflect.Method; import java.util.Properties; import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.Queue; +import javax.jms.Session; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.DirectFieldAccessor; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.expression.Expression; import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; import org.springframework.integration.MessagingException; @@ -40,11 +50,13 @@ import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.core.SubscribableChannel; import org.springframework.integration.endpoint.EventDrivenConsumer; import org.springframework.integration.endpoint.PollingConsumer; +import org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor; import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice; import org.springframework.integration.history.MessageHistory; import org.springframework.integration.jms.JmsOutboundGateway; import org.springframework.integration.jms.StubMessageConverter; import org.springframework.integration.message.GenericMessage; +import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.test.util.TestUtils; import org.springframework.jms.listener.DefaultMessageListenerContainer; import org.springframework.jms.support.converter.MessageConverter; @@ -116,6 +128,81 @@ public class JmsOutboundGatewayParserTests { assertEquals(99, order); } + @Test + public void gatewayWithDest() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "jmsOutboundGatewayReplyDestOptions.xml", this.getClass()); + EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("jmsGatewayDest"); + DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint); + JmsOutboundGateway gateway = (JmsOutboundGateway) accessor.getPropertyValue("handler"); + accessor = new DirectFieldAccessor(gateway); + assertSame(context.getBean("replyQueue"), accessor.getPropertyValue("replyDestination")); + } + + @Test + public void gatewayWithDestName() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "jmsOutboundGatewayReplyDestOptions.xml", this.getClass()); + EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("jmsGatewayDestName"); + DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint); + JmsOutboundGateway gateway = (JmsOutboundGateway) accessor.getPropertyValue("handler"); + accessor = new DirectFieldAccessor(gateway); + assertEquals("replyQueueName", accessor.getPropertyValue("replyDestinationName")); + } + + @Test + public void gatewayWithDestExpression() throws Exception { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "jmsOutboundGatewayReplyDestOptions.xml", this.getClass()); + EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("jmsGatewayDestExpression"); + DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint); + JmsOutboundGateway gateway = (JmsOutboundGateway) accessor.getPropertyValue("handler"); + ExpressionEvaluatingMessageProcessor processor = TestUtils.getPropertyValue(gateway, "replyDestinationExpressionProcessor", + ExpressionEvaluatingMessageProcessor.class); + Expression expression = TestUtils.getPropertyValue(gateway, "replyDestinationExpressionProcessor.expression", + Expression.class); + assertEquals("payload", expression.getExpressionString()); + Message message = MessageBuilder.withPayload("foo").build(); + assertEquals("foo", processor.processMessage(message)); + + Method method = JmsOutboundGateway.class.getDeclaredMethod("determineReplyDestination", Message.class, Session.class); + method.setAccessible(true); + + Session session = mock(Session.class); + Queue queue = mock(Queue.class); + when(session.createQueue("foo")).thenReturn(queue); + Destination replyQ = (Destination) method.invoke(gateway, message, session); + assertSame(queue, replyQ); + } + + @Test + public void gatewayWithDestBeanRefExpression() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "jmsOutboundGatewayReplyDestOptions.xml", this.getClass()); + EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("jmsGatewayDestExpressionBeanRef"); + DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint); + JmsOutboundGateway gateway = (JmsOutboundGateway) accessor.getPropertyValue("handler"); + ExpressionEvaluatingMessageProcessor processor = TestUtils.getPropertyValue(gateway, "replyDestinationExpressionProcessor", + ExpressionEvaluatingMessageProcessor.class); + Expression expression = TestUtils.getPropertyValue(gateway, "replyDestinationExpressionProcessor.expression", + Expression.class); + assertEquals("@replyQueue", expression.getExpressionString()); + assertSame(context.getBean("replyQueue"), processor.processMessage(null)); + } + + @Test + public void gatewayWithDestAndDestExpression() { + try { + new ClassPathXmlApplicationContext( + "jmsOutboundGatewayReplyDestOptions-fail.xml", this.getClass()); + fail("Exception expected"); + } + catch (BeanDefinitionParsingException e) { + assertTrue(e.getMessage().startsWith("Configuration problem: Only one of the " + + "'replyQueue', 'reply-destination-name', or 'reply-destination-expression' attributes is allowed.")); + } + } + @Test public void gatewayMaintainsReplyChannelAndInboundHistory() { ActiveMqTestUtils.prepare(); diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/jmsOutboundGatewayReplyDestOptions-fail.xml b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/jmsOutboundGatewayReplyDestOptions-fail.xml new file mode 100644 index 0000000000..e04d4849f1 --- /dev/null +++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/jmsOutboundGatewayReplyDestOptions-fail.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/jmsOutboundGatewayReplyDestOptions.xml b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/jmsOutboundGatewayReplyDestOptions.xml new file mode 100644 index 0000000000..a733c741e7 --- /dev/null +++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/jmsOutboundGatewayReplyDestOptions.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/reference/docbook/jms.xml b/src/reference/docbook/jms.xml index 3c1f9b373b..0ec2e68898 100644 --- a/src/reference/docbook/jms.xml +++ b/src/reference/docbook/jms.xml @@ -19,9 +19,12 @@ Whereas the JMS Channel Adapters are intended for unidirectional Messaging (send-only or receive-only), Spring Integration also provides inbound and outbound JMS Gateways for request/reply operations. The inbound gateway relies on one of Spring's MessageListener container implementations for Message-driven reception that is also - capable of sending a return value to the "reply-to" Destination as provided by the received Message. The outbound - Gateway sends a JMS Message to a "request-destination" and then receives a reply Message. The "reply-destination" - reference (or "reply-destination-name") can be configured explicitly or else the outbound gateway will use a + capable of sending a return value to the reply-to Destination as provided by the received Message. The outbound + Gateway sends a JMS Message to a request-destination (or request-destination-name or + request-destination-expression) + and then receives a reply Message. The reply-destination + reference (or reply-destination-name or reply-destination-expression) can be configured + explicitly or else the outbound gateway will use a JMS TemporaryQueue. @@ -279,6 +282,224 @@ Spring JMS documentation for their meanings. +
+ Attribute Reference + ]]>]]> + ]]> + + + + Reference to a javax.jms.ConnectionFactory; + default connectionFactory. + + + + + The name of a property that will contain correlation data to correlate responses with + replies. If omitted, the gateway will expect the responding system to return the + value of the outbound JMSMessageID header in the JMSCorrelationID header. If specified, + the gateway will generate a correlation id and populate the specified property with + it; the responding system must echo back that value in the same property. Can be set + to JMSCorrelationID, in which case the standard header is used instead + of a simple String property to hold the correlation data. When a <reply-container/> + is used, the correlation-key MUST be specified if an explicit reply-destination + is provided. + + + + + A boolean value indicating whether the delivery mode should be + DeliveryMode.PERSISTENT (true) or DeliveryMode.NON_PERSISTENT (false). + This setting will only take effect if explicit-qos-enabled is true. + + + + + A DestinationResolver; default is a + DynamicDestinationResolver which simply maps the + destination name to a queue or topic of that name. + + + + + When set to true, enables the use of quality of service attributes - + priority, delivery-mode, time-to-live. + + + + + When set to true (default), the payload of the Spring Integration reply Message will be + created from the JMS Reply Message's body (using the MessageConverter). + When set to false, the entire JMS Message will become the payload of the + Spring Integration Message. + + + + + When set to true (default), the payload of the Spring Integration Message will + be converted to a JMSMessage (using the MessageConverter). + When set to false, the entire Spring Integration Message will be converted + to the the JMSMessage. In both cases, the Spring Integration Message Headers are + mapped to JMS headers and properties using the HeaderMapper. + + + + + A HeaderMapper used to map Spring Integration Message + Headers to/from JMS Message Headers/Properties. + + + + + A reference to a MessageConverter for converting between JMS Messages + and the Spring Integration Message payloads (or messages if extract-request-payload + is false). Default is a SimpleMessageConverter. + + + + + The default priority of request messages. Overridden by the message priority + header, if present; range 0-9. + This setting will only take effect if explicit-qos-enabled is + true. + + + + + The time (in millseconds) to wait for a reply. Default 5 seconds. + + + + + The channel to which the reply message will be sent. + + + + + A reference to a Destination which will be set as + the JMSReplyTo header. At most, only one of reply-destination, + reply-destination-expression, or reply-destination-name + is allowed. If none is provided, a TemporaryQueue is used + for replies to this gateway. + + + + + A SpEL expression evaluating to a Destination which will be set as + the JMSReplyTo header. The expression can result in a Destination + object, or a String, which will be used by the + DestinationResolver to resolve the actual + Destination. At most, only one of reply-destination, + reply-destination-expression, or reply-destination-name + is allowed. If none is provided, a TemporaryQueue is used + for replies to this gateway. + + + + + The name of the destination which will be set as the JMSReplyTo header; used by the + DestinationResolver to resolve the actual + Destination. At most, only one of reply-destination, + reply-destination-expression, or reply-destination-name + is allowed. If none is provided, a TemporaryQueue is used + for replies to this gateway. + + + + + When set to true, indicates that any reply Destination + resolved by the DestinationResolver should be a + Topic rather then a Queue. + + + + + The time the gateway will wait when sending the reply message to the reply-channel. + This only has an effect if the reply-channel can block - such as a + QueueChannel with a capacity limit that is currently full. Default: infinity. + + + + + The channel on which this gateway receives request messages. + + + + + A reference to a Destination to which request messages + will be sent. One, and only one, of reply-destination, + reply-destination-expression, or reply-destination-name + is required. + + + + + A SpEL expression evaluating to a Destination to which + request messages will be sent. The expression can result in a Destination + object, or a String, which will be used by the + DestinationResolver to resolve the actual + Destination. One, and only one, of reply-destination, + reply-destination-expression, or reply-destination-name + is required. + + + + + The name of the destination to which request messages will be sent; used by the + DestinationResolver to resolve the actual + Destination. One, and only one, of reply-destination, + reply-destination-expression, or reply-destination-name + is required. + + + + + When set to true, indicates that any request Destination + resolved by the DestinationResolver should be a + Topic rather then a Queue. + + + + + Specify the message time to live. + This setting will only take effect if explicit-qos-enabled is true. + + + + + When this element is included, replies are received by a MessageListenerContainer + rather than creating a consumer for each reply. This can be more efficient in + many cases. + + + +