diff --git a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundChannelAdapterParserTests.java b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundChannelAdapterParserTests.java
index 9cad51a2c6..d1fd4663c6 100644
--- a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundChannelAdapterParserTests.java
+++ b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundChannelAdapterParserTests.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -41,8 +42,11 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.amqp.rabbit.support.PublisherCallbackChannel;
import org.springframework.amqp.rabbit.support.PublisherCallbackChannelImpl;
+import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.amqp.AmqpHeaders;
@@ -222,6 +226,19 @@ public class AmqpOutboundChannelAdapterParserTests {
assertEquals("hello", returned.getPayload());
}
+ @Test
+ public void testInt2718FailForOutboundAdapterChannelAttribute() {
+ try {
+ new ClassPathXmlApplicationContext("AmqpOutboundChannelAdapterWithinChainParserTests-fail-context.xml", this.getClass());
+ fail("Expected BeanDefinitionParsingException");
+ }
+ catch (BeansException e) {
+ assertTrue(e instanceof BeanDefinitionParsingException);
+ assertTrue(e.getMessage().contains("The 'channel' attribute isn't allowed for 'amqp:outbound-channel-adapter' " +
+ "when it is used as a nested element"));
+ }
+ }
+
public static class FooAdvice extends AbstractRequestHandlerAdvice {
@Override
diff --git a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundChannelAdapterWithinChainParserTests-fail-context.xml b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundChannelAdapterWithinChainParserTests-fail-context.xml
new file mode 100644
index 0000000000..f6c0bc9200
--- /dev/null
+++ b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundChannelAdapterWithinChainParserTests-fail-context.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java
index 4629ff3874..805a90bb24 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java
@@ -79,22 +79,31 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit
BeanDefinitionBuilder handlerBuilder = this.parseHandler(element, parserContext);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(handlerBuilder, element, "output-channel");
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "order");
- AbstractBeanDefinition handlerBeanDefinition = handlerBuilder.getBeanDefinition();
- String inputChannelAttributeName = this.getInputChannelAttributeName();
- if (!element.hasAttribute(inputChannelAttributeName)) {
- if (!parserContext.isNested()) {
- String elementDescription = IntegrationNamespaceUtils.createElementDescription(element);
- parserContext.getReaderContext().error("The '" + inputChannelAttributeName
- + "' attribute is required for the top-level endpoint element "
- + elementDescription + ".", element);
- }
- return handlerBeanDefinition;
- }
Element adviceChainElement = DomUtils.getChildElementByTagName(element,
IntegrationNamespaceUtils.REQUEST_HANDLER_ADVICE_CHAIN);
IntegrationNamespaceUtils.configureAndSetAdviceChainIfPresent(adviceChainElement, null,
- handlerBuilder, parserContext);
+ handlerBuilder.getRawBeanDefinition(), parserContext);
+
+ AbstractBeanDefinition handlerBeanDefinition = handlerBuilder.getBeanDefinition();
+ String inputChannelAttributeName = this.getInputChannelAttributeName();
+ boolean hasInputChannelAttribute = element.hasAttribute(inputChannelAttributeName);
+ if (parserContext.isNested()) {
+ if (hasInputChannelAttribute) {
+ String elementDescription = IntegrationNamespaceUtils.createElementDescription(element);
+ parserContext.getReaderContext().error("The '" + inputChannelAttributeName
+ + "' attribute isn't allowed for a nested (e.g. inside a ) endpoint element: "
+ + elementDescription + ".", element);
+ }
+ return handlerBeanDefinition;
+ } else {
+ if (!hasInputChannelAttribute) {
+ String elementDescription = IntegrationNamespaceUtils.createElementDescription(element);
+ parserContext.getReaderContext().error("The '" + inputChannelAttributeName
+ + "' attribute is required for the top-level endpoint element: "
+ + elementDescription + ".", element);
+ }
+ }
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerEndpointFactoryBean.class);
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractOutboundChannelAdapterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractOutboundChannelAdapterParser.java
index 6d77f21953..0778cd4cad 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractOutboundChannelAdapterParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractOutboundChannelAdapterParser.java
@@ -46,7 +46,17 @@ public abstract class AbstractOutboundChannelAdapterParser extends AbstractChann
@Override
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
if (parserContext.isNested()) {
- return this.parseConsumer(element, parserContext);
+ if (channelName != null) {
+ String elementDescription = IntegrationNamespaceUtils.createElementDescription(element);
+ parserContext.getReaderContext().error(
+ "The 'channel' attribute isn't allowed for " +
+ elementDescription +
+ " when it is used as a nested element," +
+ " e.g. inside a ", element);
+ }
+ AbstractBeanDefinition consumerBeanDefinition = this.parseConsumer(element, parserContext);
+ this.configureRequestHandlerAdviceChain(element, parserContext, consumerBeanDefinition, null);
+ return consumerBeanDefinition;
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerEndpointFactoryBean.class);
Element pollerElement = DomUtils.getChildElementByTagName(element, "poller");
@@ -62,13 +72,19 @@ public abstract class AbstractOutboundChannelAdapterParser extends AbstractChann
builder.addPropertyValue("inputChannelName", channelName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-startup");
+ this.configureRequestHandlerAdviceChain(element, parserContext, handlerBeanComponentDefinition.getBeanDefinition(), builder);
+
+ return builder.getBeanDefinition();
+ }
+
+ private void configureRequestHandlerAdviceChain(Element element, ParserContext parserContext,
+ BeanDefinition handlerBeanDefinition, BeanDefinitionBuilder consumerBuilder) {
Element adviceChainElement = DomUtils.getChildElementByTagName(element,
IntegrationNamespaceUtils.REQUEST_HANDLER_ADVICE_CHAIN);
@SuppressWarnings("rawtypes")
- ManagedList adviceChain = IntegrationNamespaceUtils.configureAdviceChain(adviceChainElement, null,
- builder, parserContext);
+ ManagedList adviceChain =
+ IntegrationNamespaceUtils.configureAdviceChain(adviceChainElement, null, handlerBeanDefinition, parserContext);
if (adviceChain != null) {
- BeanDefinition handlerBeanDefinition = handlerBeanComponentDefinition.getBeanDefinition();
/*
* For ARPMH, the advice chain is injected so just the handleRequestMessage method is advised.
* Sometime ARPMHs do double duty as a gateway and a channel adapter. The parser subclass
@@ -90,12 +106,17 @@ public abstract class AbstractOutboundChannelAdapterParser extends AbstractChann
if (isReplyProducer) {
handlerBeanDefinition.getPropertyValues().add("adviceChain", adviceChain);
}
+ else if (consumerBuilder != null) {
+ consumerBuilder.addPropertyValue("adviceChain", adviceChain);
+ }
else {
- builder.addPropertyValue("adviceChain", adviceChain);
+ String elementDescription = IntegrationNamespaceUtils.createElementDescription(element);
+ parserContext.getReaderContext().error("'request-handler-advice-chain' isn't allowed for " +
+ elementDescription +
+ " within a , because its Handler " +
+ "isn't an AbstractReplyProducingMessageHandler", element);
}
}
-
- return builder.getBeanDefinition();
}
/**
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DelayerParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DelayerParser.java
index 4e124399f8..9c2ed01553 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DelayerParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DelayerParser.java
@@ -72,8 +72,8 @@ public class DelayerParser extends AbstractConsumerEndpointParser {
Element txElement = DomUtils.getChildElementByTagName(element, "transactional");
Element adviceChainElement = DomUtils.getChildElementByTagName(element, "advice-chain");
- IntegrationNamespaceUtils.configureAndSetAdviceChainIfPresent(adviceChainElement, txElement, builder,
- parserContext, "delayedAdviceChain");
+ IntegrationNamespaceUtils.configureAndSetAdviceChainIfPresent(adviceChainElement, txElement,
+ builder.getRawBeanDefinition(), parserContext, "delayedAdviceChain");
return builder;
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java
index 6ab28d808e..361cad56bd 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java
@@ -329,22 +329,22 @@ public abstract class IntegrationNamespaceUtils {
}
public static void configureAndSetAdviceChainIfPresent(Element adviceChainElement, Element txElement,
- BeanDefinitionBuilder parentBuilder, ParserContext parserContext) {
- configureAndSetAdviceChainIfPresent(adviceChainElement, txElement, parentBuilder, parserContext, "adviceChain");
+ BeanDefinition parentBeanDefinition, ParserContext parserContext) {
+ configureAndSetAdviceChainIfPresent(adviceChainElement, txElement, parentBeanDefinition, parserContext, "adviceChain");
}
@SuppressWarnings({ "rawtypes" })
public static void configureAndSetAdviceChainIfPresent(Element adviceChainElement, Element txElement,
- BeanDefinitionBuilder parentBuilder, ParserContext parserContext, String propertyName) {
- ManagedList adviceChain = configureAdviceChain(adviceChainElement, txElement, parentBuilder, parserContext);
+ BeanDefinition parentBeanDefinition, ParserContext parserContext, String propertyName) {
+ ManagedList adviceChain = configureAdviceChain(adviceChainElement, txElement, parentBeanDefinition, parserContext);
if (adviceChain != null) {
- parentBuilder.addPropertyValue(propertyName, adviceChain);
+ parentBeanDefinition.getPropertyValues().add(propertyName, adviceChain);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static ManagedList configureAdviceChain(Element adviceChainElement, Element txElement,
- BeanDefinitionBuilder parentBuilder, ParserContext parserContext) {
+ BeanDefinition parentBeanDefinition, ParserContext parserContext) {
ManagedList adviceChain = null;
// Schema validation ensures txElement and adviceChainElement are mutually exclusive
if (txElement != null) {
@@ -361,7 +361,7 @@ public abstract class IntegrationNamespaceUtils {
String localName = child.getLocalName();
if ("bean".equals(localName)) {
BeanDefinitionHolder holder = parserContext.getDelegate().parseBeanDefinitionElement(
- childElement, parentBuilder.getBeanDefinition());
+ childElement, parentBeanDefinition);
parserContext.registerBeanComponent(new BeanComponentDefinition(holder));
adviceChain.add(new RuntimeBeanReference(holder.getBeanName()));
}
@@ -371,7 +371,7 @@ public abstract class IntegrationNamespaceUtils {
}
else {
BeanDefinition customBeanDefinition = parserContext.getDelegate().parseCustomElement(
- childElement, parentBuilder.getBeanDefinition());
+ childElement, parentBeanDefinition);
if (customBeanDefinition == null) {
parserContext.getReaderContext().error(
"failed to parse custom element '" + localName + "'", childElement);
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java
index 8f7b8eefaf..2833ca1514 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java
@@ -90,7 +90,7 @@ public class PollerParser extends AbstractBeanDefinitionParser {
Element txElement = DomUtils.getChildElementByTagName(element, "transactional");
Element adviceChainElement = DomUtils.getChildElementByTagName(element, "advice-chain");
IntegrationNamespaceUtils.configureAndSetAdviceChainIfPresent(adviceChainElement, txElement,
- metadataBuilder, parserContext);
+ metadataBuilder.getRawBeanDefinition(), parserContext);
if (txElement != null){
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(metadataBuilder, txElement,
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/SyslogTransformerParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/SyslogTransformerParserTests.java
index 63bd59e076..a57dea7654 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/SyslogTransformerParserTests.java
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/SyslogTransformerParserTests.java
@@ -34,6 +34,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Gary Russell
+ * @author Artem Bilan
* @since 2.2
*
*/
@@ -53,10 +54,10 @@ public class SyslogTransformerParserTests {
Map, ?> map = (Map, ?>) out.receive(1000).getPayload();
assertNotNull(map);
assertEquals(6, map.size());
- System.out.println(map);
assertEquals(19, map.get(SyslogToMapTransformer.FACILITY));
assertEquals(5, map.get(SyslogToMapTransformer.SEVERITY));
- assertTrue(map.get(SyslogToMapTransformer.TIMESAMP) instanceof Date);
+ Object date = map.get(SyslogToMapTransformer.TIMESAMP);
+ assertTrue(date instanceof Date || date instanceof String);
assertEquals("WEBERN", map.get(SyslogToMapTransformer.HOST));
assertEquals("TESTING[70729]", map.get(SyslogToMapTransformer.TAG));
assertEquals("TEST SYSLOG MESSAGE", map.get(SyslogToMapTransformer.MESSAGE));
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/SysLogTransformerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/SysLogTransformerTests.java
index a7d5856063..da77625675 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/SysLogTransformerTests.java
+++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/SysLogTransformerTests.java
@@ -25,6 +25,7 @@ import org.junit.Test;
/**
* @author Gary Russell
+ * @author Artem Bilan
* @since 2.2
*
*/
@@ -36,10 +37,10 @@ public class SysLogTransformerTests {
Map transformed = t.transformPayload(
"<158>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE".getBytes());
assertEquals(6, transformed.size());
-// System.out.println(transformed);
assertEquals(19, transformed.get(SyslogToMapTransformer.FACILITY));
assertEquals(6, transformed.get(SyslogToMapTransformer.SEVERITY));
- assertTrue(transformed.get(SyslogToMapTransformer.TIMESAMP) instanceof Date);
+ Object date = transformed.get(SyslogToMapTransformer.TIMESAMP);
+ assertTrue(date instanceof Date || date instanceof String);
assertEquals("WEBERN", transformed.get(SyslogToMapTransformer.HOST));
assertEquals("TESTING[70729]", transformed.get(SyslogToMapTransformer.TAG));
assertEquals("TEST SYSLOG MESSAGE", transformed.get(SyslogToMapTransformer.MESSAGE));
diff --git a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests-context.xml b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests-context.xml
index 60145b3ced..29a4d44180 100644
--- a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests-context.xml
+++ b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests-context.xml
@@ -12,7 +12,7 @@
processor = new GroovyScriptExecutingMessageProcessor(scriptSource, scriptVariableGenerator);
Object newResult = processor.processMessage(message);
assertFalse(newResult.equals(result)); // make sure that we get different nanotime verifying that generateScriptVariables() is invoked
@@ -153,7 +154,7 @@ public class GroovyScriptExecutingMessageProcessorTests {
result = processor.processMessage(message);
assertEquals("payload is foo, header is bar", result.toString());
}
-
+
@Test
public void testRefreshableScriptExecutionWithAlwaysRefresh() throws Exception {
String script = "return \"payload is $payload, header is $headers.testHeader\"";
@@ -178,26 +179,26 @@ public class GroovyScriptExecutingMessageProcessorTests {
private static class TestResource extends AbstractResource {
- private String script;
+ private volatile String script;
private final String filename;
- private long lastModified;
+ private volatile long lastModified;
private TestResource(String script, String filename) {
setScript(script);
this.filename = filename;
}
-
+
public long lastModified() throws IOException {
return lastModified;
}
-
+
public void setScript(String script) {
- this.lastModified = System.currentTimeMillis();
+ this.lastModified = System.nanoTime();
this.script = script;
}
-
+
public String getDescription() {
return "test";
}
@@ -208,8 +209,8 @@ public class GroovyScriptExecutingMessageProcessorTests {
}
public InputStream getInputStream() throws IOException {
- return new ByteArrayInputStream(script.getBytes("UTF-8"));
+ return new ByteArrayInputStream(script.getBytes("UTF-8"));
}
- }
+ }
}
diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java
index 37e15b8400..ffbe90640a 100644
--- a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java
+++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java
@@ -20,16 +20,20 @@ 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 static org.junit.Assert.fail;
import java.io.IOException;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.springframework.beans.BeansException;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.http.HttpMethod;
@@ -51,6 +55,7 @@ import org.springframework.web.client.ResponseErrorHandler;
/**
* @author Mark Fisher
* @author Gary Russell
+ * @author Artem Bilan
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@@ -175,6 +180,20 @@ public class HttpOutboundGatewayParserTests {
assertEquals(1, adviceCalled);
}
+ @Test
+ public void testInt2718FailForGatewayRequestChannelAttribute() {
+ try {
+ new ClassPathXmlApplicationContext("HttpOutboundGatewayWithinChainTests-fail-context.xml", this.getClass());
+ fail("Expected BeanDefinitionParsingException");
+ }
+ catch (BeansException e) {
+ assertTrue(e instanceof BeanDefinitionParsingException);
+ assertTrue(e.getMessage().contains("'request-channel' attribute isn't allowed for a nested"));
+ }
+ }
+
+
+
public static class StubErrorHandler implements ResponseErrorHandler {
public boolean hasError(ClientHttpResponse response) throws IOException {
diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayWithinChainTests-fail-context.xml b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayWithinChainTests-fail-context.xml
new file mode 100644
index 0000000000..28619fb55d
--- /dev/null
+++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayWithinChainTests-fail-context.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests-context.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests-context.xml
index 656bf70f91..ab97388e11 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests-context.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests-context.xml
@@ -28,7 +28,7 @@
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests.java
index 388afda528..4469668a34 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/DelayerHandlerRescheduleIntegrationTests.java
@@ -133,7 +133,7 @@ public class DelayerHandlerRescheduleIntegrationTests {
input.send(MessageBuilder.withPayload("test").build());
- Thread.sleep(30);
+ Thread.sleep(100);
assertEquals(1, messageStore.messageGroupSize(delayerMessageGroupId));
@@ -141,12 +141,13 @@ public class DelayerHandlerRescheduleIntegrationTests {
context.destroy();
context.refresh();
- assertTrue(RollbackTxSync.latch.await(2, TimeUnit.SECONDS));
+ assertTrue(RollbackTxSync.latch.await(20, TimeUnit.SECONDS));
//On transaction rollback the delayed Message should remain in the persistent MessageStore
assertEquals(1, messageStore.messageGroupSize(delayerMessageGroupId));
}
+ @SuppressWarnings("unused")
private static class TestJdbcMessageStore extends JdbcMessageStore {
private TestJdbcMessageStore() {
@@ -156,6 +157,7 @@ public class DelayerHandlerRescheduleIntegrationTests {
}
+ @SuppressWarnings("unused")
private static class ExceptionMessageHandler implements MessageHandler {
public void handleMessage(Message> message) throws MessagingException {
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java
index 3efc40244d..ae7e447738 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2011 the original author or authors.
- *
+ * Copyright 2002-2012 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.
@@ -41,6 +41,14 @@ import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StopWatch;
+/**
+ * @author Dave Syer
+ * @author Mark Fisher
+ * @author Gary Russell
+ * @author Oleg Zhurakousky
+ * @author Gunnar Hillert
+ * @author Artem Bilan
+ */
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class JdbcMessageStoreChannelIntegrationTests {
@@ -60,6 +68,7 @@ public class JdbcMessageStoreChannelIntegrationTests {
@Before
public void clear() {
+ Service.reset(1);
for (MessageGroup group : messageStore) {
messageStore.removeMessageGroup(group.getGroupId());
}
@@ -67,7 +76,6 @@ public class JdbcMessageStoreChannelIntegrationTests {
@Test
public void testSendAndActivate() throws Exception {
- Service.reset(1);
input.send(new GenericMessage("foo"));
Service.await(1000);
assertEquals(1, Service.messages.size());
@@ -75,7 +83,6 @@ public class JdbcMessageStoreChannelIntegrationTests {
@Test
public void testSendAndActivateWithRollback() throws Exception {
- Service.reset(1);
Service.fail = true;
input.send(new GenericMessage("foo"));
Service.await(1000);
@@ -99,12 +106,10 @@ public class JdbcMessageStoreChannelIntegrationTests {
});
}
- @Test
- @Repeat(10)
+ @Test
+ @Repeat(2)
public void testTransactionalSendAndReceive() throws Exception {
- Service.reset(1);
-
boolean result = new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Boolean doInTransaction(TransactionStatus status) {
@@ -153,14 +158,13 @@ public class JdbcMessageStoreChannelIntegrationTests {
}
Thread.sleep(50);
}
-
+
assertEquals(1, Service.messages.size());
}
@Test
public void testSameTransactionSendAndReceive() throws Exception {
- Service.reset(1);
final StopWatch stopWatch = new StopWatch();
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
@@ -213,7 +217,7 @@ public class JdbcMessageStoreChannelIntegrationTests {
private static List messages = new CopyOnWriteArrayList();
- private static CountDownLatch latch = new CountDownLatch(0);
+ private static CountDownLatch latch;
public static void reset(int count) {
fail = false;
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests.java
index f06557f91c..eb13322028 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests.java
@@ -55,6 +55,13 @@ import static org.junit.Assert.assertTrue;
import static org.springframework.integration.test.matcher.PayloadAndHeaderMatcher.sameExceptIgnorableHeaders;
+/**
+ * @author Dave Syer
+ * @author Mark Fisher
+ * @author Oleg Zhurakousky
+ * @author Gunnar Hillert
+ * @author Artem Bilan
+ */
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class JdbcMessageStoreTests {
@@ -88,17 +95,17 @@ public class JdbcMessageStoreTests {
assertNotNull(result.getHeaders().get(JdbcMessageStore.SAVED_KEY));
assertNotNull(result.getHeaders().get(JdbcMessageStore.CREATED_DATE_KEY));
}
-
+
@Test
@Transactional
- public void testWithMessageHistory() throws Exception{
-
+ public void testWithMessageHistory() throws Exception{
+
Message> message = new GenericMessage("Hello");
DirectChannel fooChannel = new DirectChannel();
fooChannel.setBeanName("fooChannel");
DirectChannel barChannel = new DirectChannel();
barChannel.setBeanName("barChannel");
-
+
message = MessageHistory.write(message, fooChannel);
message = MessageHistory.write(message, barChannel);
messageStore.addMessage(message);
@@ -226,7 +233,7 @@ public class JdbcMessageStoreTests {
MessageGroup group = messageStore.getMessageGroup(groupId);
assertEquals(0, group.size());
}
-
+
@Test
@Transactional
public void testCompleteMessageGroup() throws Exception {
@@ -238,7 +245,7 @@ public class JdbcMessageStoreTests {
assertTrue(group.isComplete());
assertEquals(1, group.size());
}
-
+
@Test
@Transactional
public void testUpdateLastReleasedSequence() throws Exception {
@@ -272,10 +279,10 @@ public class JdbcMessageStoreTests {
@Transactional
public void testOrderInMessageGroup() throws Exception {
String groupId = "X";
- Message message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
- messageStore.addMessageToGroup(groupId, message);
- message = MessageBuilder.withPayload("bar").setCorrelationId(groupId).build();
- messageStore.addMessageToGroup(groupId, message);
+
+ messageStore.addMessageToGroup(groupId, MessageBuilder.withPayload("foo").setCorrelationId(groupId).build());
+ Thread.sleep(1);
+ messageStore.addMessageToGroup(groupId, MessageBuilder.withPayload("bar").setCorrelationId(groupId).build());
MessageGroup group = messageStore.getMessageGroup(groupId);
assertEquals(2, group.size());
assertEquals("foo", messageStore.pollMessageFromGroup(groupId).getPayload());
@@ -303,7 +310,7 @@ public class JdbcMessageStoreTests {
group = messageStore.getMessageGroup(groupId);
assertEquals(0, group.size());
}
-
+
@Test
@Transactional
public void testExpireMessageGroupOnIdleOnly() throws Exception {
@@ -334,26 +341,31 @@ public class JdbcMessageStoreTests {
@Transactional
public void testMessagePollingFromTheGroup() throws Exception {
String groupId = "X";
- Message message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
- messageStore.addMessageToGroup(groupId, message);
+ messageStore.addMessageToGroup(groupId, MessageBuilder.withPayload("foo").setCorrelationId(groupId).build());
+ Thread.sleep(1);
messageStore.addMessageToGroup(groupId, MessageBuilder.withPayload("bar").setCorrelationId(groupId).build());
+ Thread.sleep(1);
messageStore.addMessageToGroup(groupId, MessageBuilder.withPayload("baz").setCorrelationId(groupId).build());
+
messageStore.addMessageToGroup("Y", MessageBuilder.withPayload("barA").setCorrelationId(groupId).build());
+ Thread.sleep(1);
messageStore.addMessageToGroup("Y", MessageBuilder.withPayload("bazA").setCorrelationId(groupId).build());
+
MessageGroup group = messageStore.getMessageGroup("X");
assertEquals(3, group.size());
Message> message1 = messageStore.pollMessageFromGroup("X");
assertNotNull(message1);
assertEquals("foo", message1.getPayload());
- System.out.println("Polled Message" + message1);
+
group = messageStore.getMessageGroup("X");
assertEquals(2, group.size());
Message> message2 = messageStore.pollMessageFromGroup("X");
assertNotNull(message2);
assertEquals("bar", message2.getPayload());
+
group = messageStore.getMessageGroup("X");
assertEquals(1, group.size());
}
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/StoredProcOutboundGatewayWithNamespaceIntegrationTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/StoredProcOutboundGatewayWithNamespaceIntegrationTests.java
index 5ea654876c..26b587d096 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/StoredProcOutboundGatewayWithNamespaceIntegrationTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/StoredProcOutboundGatewayWithNamespaceIntegrationTests.java
@@ -28,6 +28,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -54,7 +55,7 @@ import javax.sql.DataSource;
public class StoredProcOutboundGatewayWithNamespaceIntegrationTests {
@Autowired
- DataSource dataSource;
+ JdbcTemplate jdbcTemplate;
@Autowired
private Consumer consumer;
@@ -68,6 +69,11 @@ public class StoredProcOutboundGatewayWithNamespaceIntegrationTests {
@Autowired
PollableChannel replyChannel;
+ @Before
+ public void setUp() {
+ this.jdbcTemplate.execute("delete from USERS");
+ }
+
@Test
public void test() throws Exception {
@@ -97,10 +103,6 @@ public class StoredProcOutboundGatewayWithNamespaceIntegrationTests {
@Test //INT-1029
public void testStoredProcOutboundGatewayInsideChain() throws Exception {
- JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
- jdbcTemplate.execute("delete from USERS");
-
Message requestMessage = MessageBuilder.withPayload(new User("myUsername", "myPassword", "myEmail")).build();
storedProcOutboundGatewayInsideChain.send(requestMessage);
diff --git a/spring-integration-jdbc/src/test/resources/derby-stored-procedures-setup-context.xml b/spring-integration-jdbc/src/test/resources/derby-stored-procedures-setup-context.xml
index bf013ecc16..34c4f880ee 100644
--- a/spring-integration-jdbc/src/test/resources/derby-stored-procedures-setup-context.xml
+++ b/spring-integration-jdbc/src/test/resources/derby-stored-procedures-setup-context.xml
@@ -2,13 +2,8 @@
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
@@ -17,6 +12,10 @@
+
+
+
+
diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests-context.xml b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests-context.xml
index 95484539ce..db8f9ae8e1 100644
--- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests-context.xml
+++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests-context.xml
@@ -12,7 +12,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-twitter/src/test/java/org/springframework/integration/twitter/config/TestSendingMessageHandlerParserTests.java b/spring-integration-twitter/src/test/java/org/springframework/integration/twitter/config/TestSendingMessageHandlerParserTests.java
index d8a50ea46d..b94e7457b8 100644
--- a/spring-integration-twitter/src/test/java/org/springframework/integration/twitter/config/TestSendingMessageHandlerParserTests.java
+++ b/spring-integration-twitter/src/test/java/org/springframework/integration/twitter/config/TestSendingMessageHandlerParserTests.java
@@ -18,8 +18,12 @@ package org.springframework.integration.twitter.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import org.junit.Test;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
@@ -33,6 +37,7 @@ import org.springframework.integration.twitter.outbound.DirectMessageSendingMess
/**
* @author Oleg Zhurakousky
* @author Gary Russell
+ * @author Artem Bilan
* @since 2.0
*/
public class TestSendingMessageHandlerParserTests {
@@ -56,6 +61,20 @@ public class TestSendingMessageHandlerParserTests {
assertEquals(2, adviceCalled);
}
+ @Test
+ public void testInt2718FailForOutboundAdapterWithRequestHandlerAdviceChainWithinChainConfig() {
+ try {
+ new ClassPathXmlApplicationContext("OutboundAdapterWithRHACWithinChain-fail-context.xml", this.getClass());
+ fail("Expected BeanDefinitionParsingException");
+ }
+ catch (BeansException e) {
+ assertTrue(e instanceof BeanDefinitionParsingException);
+ assertTrue(e.getMessage().contains("'request-handler-advice-chain' isn't allowed " +
+ "for 'twitter:outbound-channel-adapter' within a , because its Handler isn't an AbstractReplyProducingMessageHandler"));
+ }
+ }
+
+
public static class FooAdvice extends AbstractRequestHandlerAdvice {
@Override
diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java
index 849f9f9db8..adce8d587d 100644
--- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java
+++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java
@@ -28,6 +28,7 @@ import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
+import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.EventDrivenConsumer;
@@ -52,6 +53,7 @@ import org.springframework.ws.transport.WebServiceMessageSender;
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Gary Russell
+ * @author Artem Bilan
*/
public class WebServiceOutboundGatewayParserTests {
@@ -367,6 +369,7 @@ public class WebServiceOutboundGatewayParserTests {
@Test
public void advised() {
+ adviceCalled = 0;
ApplicationContext context = new ClassPathXmlApplicationContext(
"simpleWebServiceOutboundGatewayParserTests.xml", this.getClass());
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithAdvice");
@@ -376,6 +379,16 @@ public class WebServiceOutboundGatewayParserTests {
assertEquals(1, adviceCalled);
}
+ @Test
+ public void testInt2718AdvisedInsideTheChain() {
+ adviceCalled = 0;
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "simpleWebServiceOutboundGatewayParserTests.xml", this.getClass());
+ MessageChannel channel = context.getBean("gatewayWithAdviceInsideAChain", MessageChannel.class);
+ channel.send(new GenericMessage("foo"));
+ assertEquals(1, adviceCalled);
+ }
+
@Test(expected = BeanDefinitionParsingException.class)
public void invalidGatewayWithBothUriAndDestinationProvider() {
new ClassPathXmlApplicationContext("invalidGatewayWithBothUriAndDestinationProvider.xml", this.getClass());
diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml
index d991f24cf9..d28939bad0 100644
--- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml
+++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml
@@ -102,14 +102,25 @@
request-channel="inputChannel"
destination-provider="destinationProvider" />
-
+
+
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/reference/docbook/handler-advice.xml b/src/reference/docbook/handler-advice.xml
index 89bb7ec1e3..6ff7b2497e 100644
--- a/src/reference/docbook/handler-advice.xml
+++ b/src/reference/docbook/handler-advice.xml
@@ -43,6 +43,22 @@
will not apply to further actions taken downstream after the reply is sent to the
nextChannel. The scope of the advice is limited to the endpoint itself.
+
+
+ At this time, you cannot advise an entire <chain/> of endpoints. The schema does not allow
+ a <request-handler-advice-chain/> as a child element of the chain itself.
+
+
+ However, a <request-handler-advice-chain/> can be added to individual reply-producing endpoints
+ within a <chain/> element.
+ An exception is that, in a chain that produces no reply, because the last element in the chain is an
+ outbound-channel-adapter, that last element cannot be advised. If you
+ need to advise such an element, it must be moved outside of the chain (with the
+ output-channel of the chain being the input-channel of
+ the adapter. The adapter can then be advised as normal. For chains that produce a reply, every child
+ element can be advised.
+
+