diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd index 42c0449cdc..feb0ffd0ab 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd @@ -644,7 +644,7 @@ + + + + + + + + + If a downstream exception is thrown and an error-channel is specified, + the MessagingException will be sent to this channel. Otherwise, any such exception + will be propagated to the calling system. + + + diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/BackToBackTests-context.xml b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/BackToBackTests-context.xml new file mode 100644 index 0000000000..43ff846688 --- /dev/null +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/BackToBackTests-context.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/BackToBackTests.java b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/BackToBackTests.java new file mode 100644 index 0000000000..c2c92e5ebc --- /dev/null +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/BackToBackTests.java @@ -0,0 +1,86 @@ +/* + * Copyright 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.rmi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.integration.Message; +import org.springframework.integration.core.PollableChannel; +import org.springframework.integration.core.SubscribableChannel; +import org.springframework.integration.message.GenericMessage; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Gary Russell + * @since 3.0 + * + */ +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class BackToBackTests { + + @Autowired + private SubscribableChannel good; + + @Autowired + private SubscribableChannel bad; + + @Autowired + private SubscribableChannel ugly; + + @Autowired + private PollableChannel reply; + + @Autowired + private AbstractApplicationContext context; + + @Test + public void testGood() { + good.send(new GenericMessage("foo")); + Message reply = this.reply.receive(0); + assertNotNull(reply); + assertEquals("reply:foo", reply.getPayload()); + } + + @Test + public void testBad() { + bad.send(new GenericMessage("foo")); + Message reply = this.reply.receive(0); + assertNotNull(reply); + assertEquals("error:foo", reply.getPayload()); + } + + @Test + public void testUgly() { + context.setId("context"); + try { + ugly.send(new GenericMessage("foo")); + fail("Expected exception"); + } + catch (Exception e) { + assertEquals("Dispatcher has no subscribers for channel 'context.baz'.", e.getCause().getMessage()); + } + } + +} diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/RmiOutboundGatewayTests.java b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/RmiOutboundGatewayTests.java index af3aaa0275..e62acc6de5 100644 --- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/RmiOutboundGatewayTests.java +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/RmiOutboundGatewayTests.java @@ -35,6 +35,7 @@ import org.springframework.integration.gateway.RequestReplyExchanger; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; import org.springframework.integration.message.GenericMessage; import org.springframework.integration.support.MessageBuilder; +import org.springframework.integration.test.util.SocketUtils; import org.springframework.remoting.RemoteLookupFailureException; import org.springframework.remoting.rmi.RmiServiceExporter; @@ -44,7 +45,9 @@ import org.springframework.remoting.rmi.RmiServiceExporter; */ public class RmiOutboundGatewayTests { - private final RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://localhost:1099/testRemoteHandler"); + private final static int port = SocketUtils.findAvailableServerSocket(11099); + + private final RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://localhost:" + port + "/testRemoteHandler"); private final QueueChannel output = new QueueChannel(1); @@ -59,6 +62,7 @@ public class RmiOutboundGatewayTests { exporter.setService(new TestExchanger()); exporter.setServiceInterface(RequestReplyExchanger.class); exporter.setServiceName("testRemoteHandler"); + exporter.setRegistryPort(port); exporter.afterPropertiesSet(); } diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiInboundGatewayParserTests.java b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiInboundGatewayParserTests.java index 3fdc705991..565833433c 100644 --- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiInboundGatewayParserTests.java +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiInboundGatewayParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 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. @@ -18,6 +18,7 @@ package org.springframework.integration.rmi.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; import org.junit.Test; @@ -27,9 +28,11 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.MessageChannel; import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.rmi.RmiInboundGateway; +import org.springframework.integration.test.util.TestUtils; /** * @author Mark Fisher + * @author Gary Russell */ public class RmiInboundGatewayParserTests { @@ -71,9 +74,11 @@ public class RmiInboundGatewayParserTests { public void gatewayWithHost() { ApplicationContext context = new ClassPathXmlApplicationContext( "rmiInboundGatewayParserTests.xml", this.getClass()); - RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithHost"); + RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithHostAndErrorChannel"); DirectFieldAccessor accessor = new DirectFieldAccessor(gateway); assertEquals("localhost", accessor.getPropertyValue("registryHost")); + assertSame(context.getBean("testErrorChannel"), + TestUtils.getPropertyValue(gateway, "errorChannel")); } @Test diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/rmiInboundGatewayParserTests.xml b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/rmiInboundGatewayParserTests.xml index b57c48fde8..1360f0568f 100644 --- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/rmiInboundGatewayParserTests.xml +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/rmiInboundGatewayParserTests.xml @@ -14,12 +14,15 @@ + + - + diff --git a/src/reference/docbook/rmi.xml b/src/reference/docbook/rmi.xml index f29924550b..a1dca910e8 100644 --- a/src/reference/docbook/rmi.xml +++ b/src/reference/docbook/rmi.xml @@ -32,6 +32,13 @@ ]]> + + If you use an errorChannel on an inbound gateway, it would be normal for the error flow to return a result + (or throw an exception). This is because it is likely that there is a corresponding outbound gateway waiting for a + response of some kind. Consuming a message on the error flow, and not replying, will result in no reply at the inbound + gateway. Exceptions (on the main flow when there is no errorChannel, or on the error flow) will be propagated to the + corresponding inbound gateway. +
@@ -47,7 +54,7 @@ registry-host="localhost"/> + registry-port="1234" error-channel="rmiErrorChannel"/> ]]> diff --git a/src/reference/docbook/whats-new.xml b/src/reference/docbook/whats-new.xml index fd05f895ae..3d0a09ac24 100644 --- a/src/reference/docbook/whats-new.xml +++ b/src/reference/docbook/whats-new.xml @@ -201,6 +201,13 @@ in addition to several other container attributes that were already available.
+
+ RMI Inbound Gateway + + The RMI Inbound Gateway now supports an error-channel attribute. See + . + +
SqlReturnType support for Stored Procedure components