INT-2218 - Chain Parser Validation Improvements
Components within Chain: Add parser validation For reference see: https://jira.springsource.org/browse/INT-2218 INT-2218 - Code review changes INT-2218 - Fix HttpOutboundGatewayParserTests INT-2218 - Remove input-channel validation Was already covered by PR #592
This commit is contained in:
committed by
Gary Russell
parent
c9f73a8a49
commit
7055845424
@@ -13,10 +13,13 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -24,6 +27,8 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.handler.MessageHandlerChain;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <chain> element.
|
||||
@@ -32,14 +37,14 @@ import org.springframework.integration.handler.MessageHandlerChain;
|
||||
* @author Iwein Fuld
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
* @author Gunnar Hillert
|
||||
*/
|
||||
public class ChainParser extends AbstractConsumerEndpointParser {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MessageHandlerChain.class);
|
||||
ManagedList handlerList = new ManagedList();
|
||||
ManagedList<BeanMetadataElement> handlerList = new ManagedList<BeanMetadataElement>();
|
||||
NodeList children = element.getChildNodes();
|
||||
for (int i = 0; i < children.getLength(); i++) {
|
||||
Node child = children.item(i);
|
||||
@@ -63,12 +68,38 @@ public class ChainParser extends AbstractConsumerEndpointParser {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void validateChild(Element element, ParserContext parserContext) {
|
||||
|
||||
final Object source = parserContext.extractSource(element);
|
||||
|
||||
final String order = element.getAttribute(IntegrationNamespaceUtils.ORDER);
|
||||
|
||||
if (StringUtils.hasText(order)) {
|
||||
parserContext.getReaderContext().error(IntegrationNamespaceUtils.createElementDescription(element) + " must not define " +
|
||||
"an 'order' attribute when used within a chain.", source);
|
||||
}
|
||||
|
||||
final List<Element> pollerChildElements = DomUtils
|
||||
.getChildElementsByTagName(element, "poller");
|
||||
|
||||
if (!pollerChildElements.isEmpty()) {
|
||||
parserContext.getReaderContext().error(IntegrationNamespaceUtils.createElementDescription(element) + " must not define " +
|
||||
"a 'poller' sub-element when used within a chain.", source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private BeanDefinitionHolder parseChild(Element element, ParserContext parserContext, BeanDefinition parentDefinition) {
|
||||
|
||||
BeanDefinitionHolder holder = null;
|
||||
|
||||
if ("bean".equals(element.getLocalName())) {
|
||||
holder = parserContext.getDelegate().parseBeanDefinitionElement(element, parentDefinition);
|
||||
}
|
||||
else {
|
||||
|
||||
this.validateChild(element, parserContext);
|
||||
|
||||
BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element, parentDefinition);
|
||||
if (beanDefinition == null) {
|
||||
parserContext.getReaderContext().error("child BeanDefinition must not be null", element);
|
||||
|
||||
@@ -20,8 +20,10 @@ import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -208,6 +210,23 @@ public class ChainElementsFailureTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainResequencerPoller() throws Exception {
|
||||
|
||||
try {
|
||||
this.bootStrap("resequencer-poller");
|
||||
fail("Expected a XmlBeanDefinitionStoreException to be thrown.");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
final String expectedMessage = "Configuration problem: " +
|
||||
"'int:resequencer' must not define a 'poller' sub-element " +
|
||||
"when used within a chain.";
|
||||
final String actualMessage = e.getMessage();
|
||||
assertTrue("Error message did not start with '" + expectedMessage +
|
||||
"' but instead returned: '" + actualMessage + "'", actualMessage.startsWith(expectedMessage));
|
||||
}
|
||||
}
|
||||
|
||||
private ApplicationContext bootStrap(String configProperty) throws Exception {
|
||||
PropertiesFactoryBean pfb = new PropertiesFactoryBean();
|
||||
pfb.setLocation(new ClassPathResource("org/springframework/integration/config/xml/chain-elements-config.properties"));
|
||||
|
||||
@@ -75,3 +75,10 @@ resequencer=\
|
||||
<int:chain input-channel="input"> \
|
||||
<int:resequencer input-channel="fail"/> \
|
||||
</int:chain>
|
||||
|
||||
resequencer-poller=\
|
||||
<int:chain input-channel="input"> \
|
||||
<int:resequencer> \
|
||||
<int:poller fixed-rate="5000" max-messages-per-poll="10" />\
|
||||
</int:resequencer> \
|
||||
</int:chain>
|
||||
Reference in New Issue
Block a user