INT-3884: Outbound Gateway replyChannel in Chain

JIRA: https://jira.spring.io/browse/INT-3884

Previously, an outbound gateway within a chain allowed a `reply-channel` attribute
but it was ignored. The gateway's output channel is set to send the message to
the next element in the chain, or the chain's output channel if the gateway is
the last element.

Tighten the parser logic to detect and disallow a reply channel within a chain.

Polishing
This commit is contained in:
Gary Russell
2015-11-17 15:37:31 -05:00
committed by Artem Bilan
parent 051b393ed0
commit 33a40f6cae
6 changed files with 93 additions and 20 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -95,12 +95,19 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit
String inputChannelAttributeName = this.getInputChannelAttributeName();
boolean hasInputChannelAttribute = element.hasAttribute(inputChannelAttributeName);
if (parserContext.isNested()) {
String elementDescription = IntegrationNamespaceUtils.createElementDescription(element);
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);
}
if (!replyChannelInChainAllowed(element)) {
if (StringUtils.hasText(element.getAttribute("reply-channel"))) {
parserContext.getReaderContext().error("The 'reply-channel' attribute isn't"
+ " allowed for a nested (e.g. inside a <chain/>) outbound gateway element: "
+ elementDescription + ".", element);
}
}
return handlerBeanDefinition;
}
else {
@@ -168,4 +175,14 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit
return null;
}
/**
* Override to allow 'reply-channel' within a chain, for components where it
* makes sense (e.g. enricher). Default is false for outbound gateways, else true.
* @return true to allow a reply channel attribute within a chain.
*/
protected boolean replyChannelInChainAllowed(Element element) {
String localName = element.getLocalName();
return localName == null || !localName.contains("outbound-gateway");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.util.xml.DomUtils;
* @author Artem Bilan
* @author Liujiong
* @author Kris Jacyna
* @author Gary Russell
* @since 2.1
*/
public class EnricherParser extends AbstractConsumerEndpointParser {
@@ -201,4 +202,9 @@ public class EnricherParser extends AbstractConsumerEndpointParser {
return builder;
}
@Override
protected boolean replyChannelInChainAllowed(Element element) {
return true;
}
}

View File

@@ -11,16 +11,20 @@
<channel id="requestChannel"/>
<channel id="replyChannel"/>
<channel id="errChannel"/>
<channel id="outputChannel">
<queue />
</channel>
<enricher id="enricher"
input-channel="inputChannel" request-channel="requestChannel"
output-channel="outputChannel" error-channel="errChannel">
<property name="name" expression="'Mr. ' + payload.name"/>
</enricher>
<chain input-channel="inputChannel" output-channel="outputChannel">
<enricher id="enricher"
request-channel="requestChannel"
reply-channel="replyChannel"
error-channel="errChannel">
<property name="name" expression="'Mr. ' + payload.name"/>
</enricher>
</chain>
</beans:beans>