INT-2216 - For Payload Enricher - add: 'request-timeout' and 'reply-timeout' attributes

For reference see: https://jira.springsource.org/browse/INT-2216
This commit is contained in:
Gunnar Hillert
2011-11-21 16:18:37 -05:00
parent d484f65100
commit 94f2dc755f
6 changed files with 156 additions and 2 deletions

View File

@@ -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<Element> propertyElements = DomUtils.getChildElementsByTagName(element, "property");
if (!CollectionUtils.isEmpty(propertyElements)) {
ManagedMap<String, Object> propertyExpressions = new ManagedMap<String, Object>();

View File

@@ -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());

View File

@@ -1043,6 +1043,24 @@ endpoint itself is a Polling Consumer for a channel with a queue.
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="request-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set the timeout value for sending request messages in milliseconds.
If not explicitly configured, the default is one second.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="reply-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set the timeout value for receiving reply messages in milliseconds.
If not explicitly configured, the default is one second.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="should-clone-payload">
<xsd:annotation>
<xsd:documentation>

View File

@@ -15,7 +15,10 @@
<channel id="requests"/>
<enricher id="enricher" input-channel="input" request-channel="requests" order="99" should-clone-payload="true" output-channel="output">
<enricher id="enricher" input-channel="input"
request-channel="requests" request-timeout="1234"
reply-timeout="9876"
order="99" should-clone-payload="true" output-channel="output">
<property name="name" expression="payload.sourceName"/>
<property name="age" value="42"/>
</enricher>

View File

@@ -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);

View File

@@ -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();