From 94f2dc755f33338078c16634897a61ff0bf5ea6b Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Mon, 21 Nov 2011 16:18:37 -0500 Subject: [PATCH] INT-2216 - For Payload Enricher - add: 'request-timeout' and 'reply-timeout' attributes For reference see: https://jira.springsource.org/browse/INT-2216 --- .../config/xml/EnricherParser.java | 5 +- .../transformer/ContentEnricher.java | 35 ++++++++ .../config/xml/spring-integration-2.1.xsd | 18 +++++ .../xml/EnricherParserTests-context.xml | 5 +- .../config/xml/EnricherParserTests.java | 15 ++++ .../transformer/ContentEnricherTests.java | 80 +++++++++++++++++++ 6 files changed, 156 insertions(+), 2 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java index 55f084912c..3e3cc70e66 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java @@ -44,7 +44,10 @@ public class EnricherParser extends AbstractConsumerEndpointParser { IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "request-channel"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel"); - + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-timeout"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout"); + + List propertyElements = DomUtils.getChildElementsByTagName(element, "property"); if (!CollectionUtils.isEmpty(propertyElements)) { ManagedMap propertyExpressions = new ManagedMap(); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ContentEnricher.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/ContentEnricher.java index 02b0aba300..18a50e85cb 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ContentEnricher.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/transformer/ContentEnricher.java @@ -63,6 +63,9 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem private volatile Gateway gateway = null; + private volatile Long requestTimeout; + + private volatile Long replyTimeout; /** * Provide the map of expressions to evaluate when enriching the target payload. @@ -102,6 +105,28 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem this.replyChannel = replyChannel; } + /** + * Set the timeout value for sending request messages. If not explicitly + * configured, the default is one second. + * + * @param requestTimeout the timeout value in milliseconds. Must not be null. + */ + public void setRequestTimeout(Long requestTimeout) { + Assert.notNull(requestTimeout, "requestTimeout must not be null"); + this.requestTimeout = requestTimeout; + } + + /** + * Set the timeout value for receiving reply messages. If not explicitly + * configured, the default is one second. + * + * @param replyTimeout the timeout value in milliseconds. Must not be null. + */ + public void setReplyTimeout(Long replyTimeout) { + Assert.notNull(replyTimeout, "replyTimeout must not be null"); + this.replyTimeout = replyTimeout; + } + /** * By default the original message's payload will be used as the actual payload * that will be send to the request-channel. @@ -152,9 +177,19 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem if (this.requestChannel != null) { this.gateway = new Gateway(); this.gateway.setRequestChannel(requestChannel); + + if (this.requestTimeout != null) { + this.gateway.setRequestTimeout(this.requestTimeout); + } + + if (this.replyTimeout != null) { + this.gateway.setReplyTimeout(this.replyTimeout); + } + if (replyChannel != null) { this.gateway.setReplyChannel(replyChannel); } + this.gateway.afterPropertiesSet(); } this.evaluationContext.addPropertyAccessor(new MapAccessor()); diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd index 5a5708f7c5..9d1b2f987f 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd @@ -1043,6 +1043,24 @@ endpoint itself is a Polling Consumer for a channel with a queue. + + + + + + + + + + + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests-context.xml index bcd6c4d5b0..73cfe39887 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests-context.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests-context.xml @@ -15,7 +15,10 @@ - + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java index 7eb96882e1..7582329786 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java @@ -42,6 +42,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Mark Fisher + * @author Gunnar Hillert + * * @since 2.1 */ @RunWith(SpringJUnit4ClassRunner.class) @@ -80,6 +82,19 @@ public class EnricherParserTests { } } + @Test + public void configurationCheckTimeoutParameters() { + + Object endpoint = context.getBean("enricher"); + + Long requestTimeout = TestUtils.getPropertyValue(endpoint, "handler.requestTimeout", Long.class); + Long replyTimeout = TestUtils.getPropertyValue(endpoint, "handler.replyTimeout", Long.class); + + assertEquals(Long.valueOf(1234L), requestTimeout); + assertEquals(Long.valueOf(9876L), replyTimeout); + + } + @Test public void integrationTest() { SubscribableChannel requests = context.getBean("requests", SubscribableChannel.class); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/ContentEnricherTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/ContentEnricherTests.java index 159ce46d82..c58cd71e93 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/ContentEnricherTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/ContentEnricherTests.java @@ -30,18 +30,50 @@ import org.junit.Test; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.integration.Message; +import org.springframework.integration.MessageDeliveryException; import org.springframework.integration.MessageHandlingException; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.channel.RendezvousChannel; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; import org.springframework.integration.support.MessageBuilder; /** * @author Mark Fisher + * @author Gunnar Hillert + * * @since 2.1 */ public class ContentEnricherTests { + @Test + public void requestChannelSendTimingOut() { + + final String requestChannelName = "Request_Channel"; + final long requestTimeout = 200L; + + QueueChannel replyChannel = new QueueChannel(); + QueueChannel requestChannel = new RendezvousChannel(); + requestChannel.setBeanName(requestChannelName); + + ContentEnricher enricher = new ContentEnricher(); + enricher.setRequestChannel(requestChannel); + enricher.setRequestTimeout(requestTimeout); + enricher.afterPropertiesSet(); + + Target target = new Target("replace me"); + Message requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build(); + + try { + enricher.handleMessage(requestMessage); + } catch (MessageDeliveryException e) { + assertEquals("failed to send message to channel '" + requestChannelName + + "' within timeout: " + requestTimeout, e.getMessage()); + return; + } + + } + @Test public void simpleProperty() { QueueChannel replyChannel = new QueueChannel(); @@ -69,6 +101,54 @@ public class ContentEnricherTests { assertEquals("Doe, John", ((Target) reply.getPayload()).getName()); } + @Test + public void setReplyChannelWithoutRequestChannel() { + + QueueChannel replyChannel = new QueueChannel(); + + ContentEnricher enricher = new ContentEnricher(); + enricher.setReplyChannel(replyChannel); + + try { + enricher.afterPropertiesSet(); + } catch (IllegalArgumentException e) { + assertEquals("If the replyChannel is set, then the requestChannel must not be null", e.getMessage()); + return; + } + + fail("Expected an exception."); + } + + @Test + public void setNullReplyTimeout() { + + ContentEnricher enricher = new ContentEnricher(); + + try { + enricher.setReplyTimeout(null); + } catch (IllegalArgumentException e) { + assertEquals("replyTimeout must not be null", e.getMessage()); + return; + } + + fail("Expected an exception."); + } + + @Test + public void setNullRequestTimeout() { + + ContentEnricher enricher = new ContentEnricher(); + + try { + enricher.setRequestTimeout(null); + } catch (IllegalArgumentException e) { + assertEquals("requestTimeout must not be null", e.getMessage()); + return; + } + + fail("Expected an exception."); + } + @Test public void testSimplePropertyWithoutUsingRequestChannel() { QueueChannel replyChannel = new QueueChannel();