Added a 'replyTimeout' property to DefaultMessageEndpoint with a default value of 1000 milliseconds. When sending to either the 'defaultOutputChannelName' or the reply channel specified by the input MessageHeader's 'returnAddress', a timeout will now cause the reply Message to be wrapped within a MessageDeliveryException and passed to the endpoint's ErrorHandler. The default error handler publishes the exception as an ErrorMessage to the global error channel (INT-108).

This commit is contained in:
Mark Fisher
2008-02-25 20:55:24 +00:00
parent af229e3576
commit f9d01dd568
3 changed files with 123 additions and 8 deletions

View File

@@ -157,8 +157,8 @@ public class MessageBusTests {
bus.registerHandler("handler2", handler2, new Subscription(inputChannel));
bus.start();
inputChannel.send(new StringMessage(1, "testing"));
Message<?> message1 = outputChannel1.receive(200);
Message<?> message2 = outputChannel2.receive(200);
Message<?> message1 = outputChannel1.receive(500);
Message<?> message2 = outputChannel2.receive(500);
bus.stop();
assertTrue("both handlers should have received and replied to the message",
(message1 != null && message2 != null));

View File

@@ -38,6 +38,7 @@ import org.springframework.integration.handler.MessageHandler;
import org.springframework.integration.handler.MessageHandlerNotRunningException;
import org.springframework.integration.handler.TestHandlers;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.message.StringMessage;
import org.springframework.integration.message.selector.MessageSelector;
import org.springframework.integration.message.selector.MessageSelectorRejectedException;
@@ -442,9 +443,102 @@ public class DefaultMessageEndpointTests {
endpoint.stop();
}
@Test
public void testDefaultOutputChannelTimeoutSendsToErrorHandler() {
SimpleChannel output = new SimpleChannel(1);
ChannelRegistry channelRegistry = new DefaultChannelRegistry();
channelRegistry.registerChannel("output", output);
DefaultMessageEndpoint endpoint = new DefaultMessageEndpoint(new MessageHandler() {
public Message<?> handle(Message<?> message) {
return message;
}
});
endpoint.setDefaultOutputChannelName("output");
endpoint.setChannelRegistry(channelRegistry);
TestErrorHandler errorHandler = new TestErrorHandler();
endpoint.setErrorHandler(errorHandler);
endpoint.setReplyTimeout(0);
endpoint.start();
endpoint.handle(new StringMessage("test1"));
assertNull(errorHandler.getLastError());
endpoint.handle(new StringMessage("test2"));
Throwable error = errorHandler.getLastError();
assertNotNull(error);
assertEquals(MessageDeliveryException.class, error.getClass());
assertEquals("test2", ((MessageDeliveryException) error).getUndeliveredMessage().getPayload());
}
@Test
public void testReturnAddressChannelTimeoutSendsToErrorHandler() {
SimpleChannel replyChannel = new SimpleChannel(1);
DefaultMessageEndpoint endpoint = new DefaultMessageEndpoint(new MessageHandler() {
public Message<?> handle(Message<?> message) {
return message;
}
});
TestErrorHandler errorHandler = new TestErrorHandler();
endpoint.setErrorHandler(errorHandler);
endpoint.setReplyTimeout(0);
endpoint.start();
Message<?> message1 = new StringMessage("test1");
message1.getHeader().setReturnAddress(replyChannel);
endpoint.handle(message1);
assertNull(errorHandler.getLastError());
Message<?> message2 = new StringMessage("test2");
message2.getHeader().setReturnAddress(replyChannel);
endpoint.handle(message2);
Throwable error = errorHandler.getLastError();
assertNotNull(error);
assertEquals(MessageDeliveryException.class, error.getClass());
assertEquals(message2, ((MessageDeliveryException) error).getUndeliveredMessage());
}
@Test
public void testReturnAddressChannelNameTimeoutSendsToErrorHandler() {
SimpleChannel replyChannel = new SimpleChannel(1);
ChannelRegistry channelRegistry = new DefaultChannelRegistry();
channelRegistry.registerChannel("replyChannel", replyChannel);
DefaultMessageEndpoint endpoint = new DefaultMessageEndpoint(new MessageHandler() {
public Message<?> handle(Message<?> message) {
return message;
}
});
endpoint.setChannelRegistry(channelRegistry);
TestErrorHandler errorHandler = new TestErrorHandler();
endpoint.setErrorHandler(errorHandler);
endpoint.setReplyTimeout(10);
endpoint.start();
Message<?> message1 = new StringMessage("test1");
message1.getHeader().setReturnAddress("replyChannel");
endpoint.handle(message1);
assertNull(errorHandler.getLastError());
Message<?> message2 = new StringMessage("test2");
message2.getHeader().setReturnAddress("replyChannel");
endpoint.handle(message2);
Throwable error = errorHandler.getLastError();
assertNotNull(error);
assertEquals(MessageDeliveryException.class, error.getClass());
assertEquals(message2, ((MessageDeliveryException) error).getUndeliveredMessage());
}
private static ExecutorService createExecutor() {
return new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
private static class TestErrorHandler implements ErrorHandler {
private volatile Throwable lastError;
public void handle(Throwable t) {
this.lastError = t;
}
Throwable getLastError() {
return this.lastError;
}
}
}