Merge pull request #592 from artembilan/INT-2718
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:amqp="http://www.springframework.org/schema/integration/amqp"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<int:chain input-channel="inputChannel">
|
||||
<amqp:outbound-channel-adapter channel="someChannel"/>
|
||||
</int:chain>
|
||||
|
||||
</beans>
|
||||
@@ -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 <chain/>) 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);
|
||||
|
||||
|
||||
@@ -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 <chain/>", 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 <chain/>, because its Handler " +
|
||||
"isn't an AbstractReplyProducingMessageHandler", element);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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<String, ?> 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));
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</bean>
|
||||
|
||||
<int-ftp:outbound-gateway id="gateway1"
|
||||
local-directory="/tmp"
|
||||
local-directory="local-test-dir"
|
||||
session-factory="sf"
|
||||
request-channel="inbound1"
|
||||
reply-channel="outbound"
|
||||
@@ -29,7 +29,7 @@
|
||||
/>
|
||||
|
||||
<int-ftp:outbound-gateway id="gateway2"
|
||||
local-directory="/tmp"
|
||||
local-directory="local-test-dir"
|
||||
session-factory="sf"
|
||||
request-channel="inbound2"
|
||||
reply-channel="outbound"
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
@@ -62,7 +63,7 @@ public class FtpOutboundGatewayParserTests {
|
||||
assertEquals("X", TestUtils.getPropertyValue(gateway, "remoteFileSeparator"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "sessionFactory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals(new File("/tmp"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertEquals(new File("local-test-dir"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertFalse((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "filter"));
|
||||
assertEquals("ls", TestUtils.getPropertyValue(gateway, "command"));
|
||||
@@ -83,7 +84,7 @@ public class FtpOutboundGatewayParserTests {
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "sessionFactory"));
|
||||
assertTrue(TestUtils.getPropertyValue(gateway, "sessionFactory") instanceof CachingSessionFactory);
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals(new File("/tmp"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertEquals(new File("local-test-dir"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertFalse((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory"));
|
||||
assertEquals("get", TestUtils.getPropertyValue(gateway, "command"));
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
@@ -42,6 +42,7 @@ import org.springframework.test.annotation.Repeat;
|
||||
* @author Mark Fisher
|
||||
* @author Dave Syer
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
public class GroovyScriptExecutingMessageProcessorTests {
|
||||
@@ -63,7 +64,7 @@ public class GroovyScriptExecutingMessageProcessorTests {
|
||||
Object result = processor.processMessage(message);
|
||||
assertEquals("payload is foo, header is bar"+count, result.toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSimpleExecutionWithScriptVariableGenerator() throws Exception {
|
||||
int count = countHolder.getAndIncrement();
|
||||
@@ -82,7 +83,7 @@ public class GroovyScriptExecutingMessageProcessorTests {
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
ScriptVariableGenerator scriptVariableGenerator = new CustomScriptVariableGenerator();
|
||||
ScriptVariableGenerator scriptVariableGenerator = new CustomScriptVariableGenerator();
|
||||
MessageProcessor<Object> 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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans
|
||||
xmlns="http://www.springframework.org/schema/integration/http"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<si:chain input-channel="httpOutboundGatewayWithinChain">
|
||||
<outbound-gateway url="http://test.org" request-channel="someRequestChannel"/>
|
||||
</si:chain>
|
||||
|
||||
</beans:beans>
|
||||
@@ -28,7 +28,7 @@
|
||||
<delayer id="transactionalDelayer"
|
||||
input-channel="transactionalDelayerInput"
|
||||
output-channel="transactionalDelayerOutput"
|
||||
default-delay="10"
|
||||
default-delay="50"
|
||||
message-store="messageStore">
|
||||
<transactional/>
|
||||
</delayer>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<String>("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<String>("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<Boolean>() {
|
||||
|
||||
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<String> messages = new CopyOnWriteArrayList<String>();
|
||||
|
||||
private static CountDownLatch latch = new CountDownLatch(0);
|
||||
private static CountDownLatch latch;
|
||||
|
||||
public static void reset(int count) {
|
||||
fail = false;
|
||||
|
||||
@@ -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<String>("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<String> 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<String> 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());
|
||||
}
|
||||
|
||||
@@ -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<User> requestMessage = MessageBuilder.withPayload(new User("myUsername", "myPassword", "myEmail")).build();
|
||||
|
||||
storedProcOutboundGatewayInsideChain.send(requestMessage);
|
||||
|
||||
@@ -2,13 +2,8 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="DERBY"/>
|
||||
|
||||
@@ -17,6 +12,10 @@
|
||||
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
|
||||
</jdbc:initialize-database>
|
||||
|
||||
<bean class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager"
|
||||
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</bean>
|
||||
|
||||
<int-sftp:outbound-gateway id="gateway1"
|
||||
local-directory="/tmp"
|
||||
local-directory="local-test-dir"
|
||||
session-factory="sf"
|
||||
request-channel="inbound1"
|
||||
reply-channel="outbound"
|
||||
@@ -29,7 +29,7 @@
|
||||
/>
|
||||
|
||||
<int-sftp:outbound-gateway id="gateway2"
|
||||
local-directory="/tmp"
|
||||
local-directory="local-test-dir"
|
||||
session-factory="sf"
|
||||
request-channel="inbound2"
|
||||
reply-channel="outbound"
|
||||
@@ -44,7 +44,7 @@
|
||||
/>
|
||||
|
||||
<int-sftp:outbound-gateway id="advised"
|
||||
local-directory="/tmp"
|
||||
local-directory="local-test-dir"
|
||||
session-factory="sf"
|
||||
request-channel="inbound2"
|
||||
reply-channel="outbound"
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
@@ -65,7 +66,7 @@ public class SftpOutboundGatewayParserTests {
|
||||
assertEquals("X", TestUtils.getPropertyValue(gateway, "remoteFileSeparator"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "sessionFactory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals(new File("/tmp"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertEquals(new File("local-test-dir"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertFalse((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "filter"));
|
||||
assertEquals("ls", TestUtils.getPropertyValue(gateway, "command"));
|
||||
@@ -86,7 +87,7 @@ public class SftpOutboundGatewayParserTests {
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "sessionFactory"));
|
||||
assertTrue(TestUtils.getPropertyValue(gateway, "sessionFactory") instanceof CachingSessionFactory);
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals(new File("/tmp"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertEquals(new File("local-test-dir"), TestUtils.getPropertyValue(gateway, "localDirectory"));
|
||||
assertFalse((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory"));
|
||||
assertEquals("get", TestUtils.getPropertyValue(gateway, "command"));
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter.xsd">
|
||||
|
||||
<beans:bean id="twitter" class="org.springframework.social.twitter.api.impl.TwitterTemplate"/>
|
||||
|
||||
<chain input-channel="inputChannel">
|
||||
<twitter:outbound-channel-adapter twitter-template="twitter">
|
||||
<twitter:request-handler-advice-chain>
|
||||
<beans:bean class="org.springframework.integration.twitter.config.TestSendingMessageHandlerParserTests$FooAdvice" />
|
||||
</twitter:request-handler-advice-chain>
|
||||
</twitter:outbound-channel-adapter>
|
||||
</chain>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
|
||||
@@ -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 <chain/>, because its Handler isn't an AbstractReplyProducingMessageHandler"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class FooAdvice extends AbstractRequestHandlerAdvice {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<String>("foo"));
|
||||
assertEquals(1, adviceCalled);
|
||||
}
|
||||
|
||||
@Test(expected = BeanDefinitionParsingException.class)
|
||||
public void invalidGatewayWithBothUriAndDestinationProvider() {
|
||||
new ClassPathXmlApplicationContext("invalidGatewayWithBothUriAndDestinationProvider.xml", this.getClass());
|
||||
|
||||
@@ -102,14 +102,25 @@
|
||||
request-channel="inputChannel"
|
||||
destination-provider="destinationProvider" />
|
||||
|
||||
<ws:outbound-gateway id="gatewayWithAdvice"
|
||||
<bean id="fooAdvice" class="org.springframework.integration.ws.config.WebServiceOutboundGatewayParserTests$FooAdvice"/>
|
||||
|
||||
<ws:outbound-gateway id="gatewayWithAdvice"
|
||||
request-channel="inputChannel"
|
||||
destination-provider="destinationProvider">
|
||||
<ws:request-handler-advice-chain>
|
||||
<bean class="org.springframework.integration.ws.config.WebServiceOutboundGatewayParserTests$FooAdvice"/>
|
||||
<ref bean="fooAdvice"/>
|
||||
</ws:request-handler-advice-chain>
|
||||
</ws:outbound-gateway>
|
||||
|
||||
|
||||
<si:chain input-channel="gatewayWithAdviceInsideAChain">
|
||||
<ws:outbound-gateway destination-provider="destinationProvider">
|
||||
<ws:request-handler-advice-chain>
|
||||
<ref bean="fooAdvice"/>
|
||||
</ws:request-handler-advice-chain>
|
||||
</ws:outbound-gateway>
|
||||
</si:chain>
|
||||
|
||||
<bean id="sourceExtractor" class="org.springframework.integration.ws.config.StubSourceExtractor"/>
|
||||
|
||||
<bean id="requestCallback" class="org.springframework.integration.ws.config.StubWebServiceMessageCallback"/>
|
||||
|
||||
@@ -43,6 +43,22 @@
|
||||
will not apply to further actions taken downstream after the reply is sent to the
|
||||
<emphasis>nextChannel</emphasis>. The scope of the advice is limited to the endpoint itself.
|
||||
</para>
|
||||
<important>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
However, a <request-handler-advice-chain/> can be added to individual reply-producing endpoints
|
||||
<emphasis>within</emphasis> a <chain/> element.
|
||||
An exception is that, in a chain that produces no reply, because the last element in the chain is an
|
||||
<emphasis>outbound-channel-adapter</emphasis>, that <emphasis>last</emphasis> element cannot be advised. If you
|
||||
need to advise such an element, it must be moved outside of the chain (with the
|
||||
<emphasis>output-channel</emphasis> of the chain being the <emphasis>input-channel</emphasis> of
|
||||
the adapter. The adapter can then be advised as normal. For chains that produce a reply, every child
|
||||
element can be advised.
|
||||
</para>
|
||||
</important>
|
||||
<section id="advice-classes">
|
||||
<title>Provided Advice Classes</title>
|
||||
<para>
|
||||
|
||||
Reference in New Issue
Block a user