From 5c1652777ec231d7326459ae2e5a7351e588c485 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Wed, 17 Nov 2010 12:02:55 -0500 Subject: [PATCH] INT-1624 Add error-channel to event inbound channel adapter XSD, Parser, Test --- spring-integration-event/.springBeans | 13 ++++++++ .../EventInboundChannelAdapterParser.java | 1 + .../config/spring-integration-event-2.0.xsd | 15 ++++++++++ ...boundChannelAdapterParserTests-context.xml | 3 +- ...EventInboundChannelAdapterParserTests.java | 6 ++++ ...ionEventListeningMessageProducerTests.java | 30 ++++++++++++++++++- 6 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 spring-integration-event/.springBeans diff --git a/spring-integration-event/.springBeans b/spring-integration-event/.springBeans new file mode 100644 index 0000000000..6f4c287497 --- /dev/null +++ b/spring-integration-event/.springBeans @@ -0,0 +1,13 @@ + + + 1 + + + + + + + + + + diff --git a/spring-integration-event/src/main/java/org/springframework/integration/event/config/EventInboundChannelAdapterParser.java b/spring-integration-event/src/main/java/org/springframework/integration/event/config/EventInboundChannelAdapterParser.java index 6fddae8854..5560d5679c 100644 --- a/spring-integration-event/src/main/java/org/springframework/integration/event/config/EventInboundChannelAdapterParser.java +++ b/spring-integration-event/src/main/java/org/springframework/integration/event/config/EventInboundChannelAdapterParser.java @@ -36,6 +36,7 @@ public class EventInboundChannelAdapterParser extends AbstractChannelAdapterPars BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder.rootBeanDefinition( "org.springframework.integration.event.inbound.ApplicationEventListeningMessageProducer"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(adapterBuilder, element, "channel", "outputChannel"); + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(adapterBuilder, element, "error-channel", "errorChannel"); IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "event-types"); IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "payload-expression"); return adapterBuilder.getBeanDefinition(); diff --git a/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-2.0.xsd b/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-2.0.xsd index eedb92b4c7..078d5011cc 100644 --- a/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-2.0.xsd +++ b/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-2.0.xsd @@ -38,6 +38,21 @@ + + + + + + + + + If a (synchronous) downstream exception is thrown and an error-channel is specified, + the MessageHandlingException will be sent to this channel. Otherwise, any such exception + will be propagated to the calling thread. + + + diff --git a/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests-context.xml b/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests-context.xml index 835a4cd39a..6a9fbe516a 100644 --- a/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests-context.xml +++ b/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests-context.xml @@ -11,7 +11,8 @@ - + diff --git a/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests.java b/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests.java index 6eff5c7cea..0b1230b92a 100644 --- a/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests.java +++ b/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests.java @@ -18,6 +18,7 @@ package org.springframework.integration.event.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Properties; @@ -35,6 +36,7 @@ import org.springframework.context.ApplicationEvent; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.expression.Expression; import org.springframework.integration.Message; +import org.springframework.integration.MessageChannel; import org.springframework.integration.core.PollableChannel; import org.springframework.integration.event.inbound.ApplicationEventListeningMessageProducer; import org.springframework.integration.history.MessageHistory; @@ -54,6 +56,8 @@ public class EventInboundChannelAdapterParserTests { @Autowired private ApplicationContext context; + @Autowired + MessageChannel errorChannel; @Test public void validateEventParser() { @@ -62,6 +66,7 @@ public class EventInboundChannelAdapterParserTests { Assert.assertTrue(adapter instanceof ApplicationEventListeningMessageProducer); DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter); Assert.assertEquals(context.getBean("input"), adapterAccessor.getPropertyValue("outputChannel")); + Assert.assertSame(errorChannel, adapterAccessor.getPropertyValue("errorChannel")); } @Test @@ -77,6 +82,7 @@ public class EventInboundChannelAdapterParserTests { assertTrue(eventTypes.size() == 2); assertTrue(eventTypes.contains(SampleEvent.class)); assertTrue(eventTypes.contains(AnotherSampleEvent.class)); + assertNull(adapterAccessor.getPropertyValue("errorChannel")); } @Test diff --git a/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java b/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java index 7424a89ab8..109c5772f6 100644 --- a/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java +++ b/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java @@ -19,9 +19,9 @@ package org.springframework.integration.event.inbound; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import org.junit.Test; - import org.springframework.context.ApplicationEvent; import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextRefreshedEvent; @@ -29,10 +29,14 @@ import org.springframework.context.event.ContextStartedEvent; import org.springframework.context.event.ContextStoppedEvent; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.Message; +import org.springframework.integration.MessageHandlingException; +import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.core.PollableChannel; import org.springframework.integration.event.core.MessagingEvent; +import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; import org.springframework.integration.message.GenericMessage; +import org.springframework.test.annotation.ExpectedException; /** * @author Mark Fisher @@ -145,6 +149,30 @@ public class ApplicationEventListeningMessageProducerTests { assertEquals("test", message2.getPayload()); } + @Test @ExpectedException(value=MessageHandlingException.class) + public void anyApplicationEventCausesExceptionWithErrorHandling() { + DirectChannel channel = new DirectChannel(); + channel.subscribe(new AbstractReplyProducingMessageHandler() { + protected Object handleRequestMessage(Message requestMessage) { + throw new RuntimeException("Failed"); + } + }); + ApplicationEventListeningMessageProducer adapter = new ApplicationEventListeningMessageProducer(); + adapter.setOutputChannel(channel); + QueueChannel errorChannel = new QueueChannel(); + adapter.setErrorChannel(errorChannel); + adapter.start(); + adapter.onApplicationEvent(new TestApplicationEvent1()); + Message message = errorChannel.receive(10000); + assertNotNull(message); + assertEquals("Failed", ((Exception) message.getPayload()).getCause().getMessage()); + adapter.setErrorChannel(null); + try { + adapter.onApplicationEvent(new TestApplicationEvent1()); + fail("Expected MessageHandlingException"); + } catch (MessageHandlingException e) { } + } + @SuppressWarnings("serial") private static class TestApplicationEvent1 extends ApplicationEvent {