Refactor/Standardize Router XSD Schema Attributes
- Add more documentation for schema elements in spring-integration-xml-2.1.xsd - Simplify Handling of Channel Resolution (Failures) for Routers - Fix PayloadTypeRouterTests - Update reference docs, XSD Schemas - Rename 'channel-resolution-required' to 'resolution-required' - Updated all tests accordingly
This commit is contained in:
committed by
Mark Fisher
parent
b55520369d
commit
2c023f6fd1
@@ -342,98 +342,109 @@
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="xpath-router">
|
||||
<xsd:complexType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines an XPath router.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="mapping" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="value" type="xsd:string" />
|
||||
<xsd:attribute name="channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
<xsd:attribute name="evaluate-as-string" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
By default XPath expressions are evaluated as NODESET type and then converted
|
||||
to a List of channel names, thus handling single channel scenarios as well as multiple.
|
||||
However certain XPath expressions may evaluate as String type from the very
|
||||
beginning (e.g., 'name(./node())' - which will return the name of the root node) thus resulting in
|
||||
the exception if default evaluation type (NODESET) is used. This flag will allow you to manage the
|
||||
evaluation type. It is TRUE by default, however if set to FALSE, the String evaluation type will be used.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="input-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="xpath-expression-ref" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.xml.xpath.XPathExpression"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel-resolver" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.core.ChannelResolver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="resolution-required" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify whether this router should always be required to return at least one channel or name.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ignore-channel-name-resolution-failures" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify whether a failure to resolve a channel name returned by this router should be ignored.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="default-output-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<!-- XPath Router definition -->
|
||||
|
||||
<xsd:complexType name="commonXPathRouterType" abstract="true">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="integration:abstractRouterType">
|
||||
<xsd:attribute name="evaluate-as-string" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
By default XPath expressions are evaluated as NODESET type and then converted
|
||||
to a List of channel names, thus handling single channel scenarios as well as multiple.
|
||||
However certain XPath expressions may evaluate as String type from the very
|
||||
beginning (e.g., 'name(./node())' - which will return the name of the root node) thus resulting in
|
||||
the exception if default evaluation type (NODESET) is used.
|
||||
|
||||
This flag will allow you to manage the
|
||||
evaluation type. It is 'false' by default, however if
|
||||
set to 'true', then String evaluation type will be used.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="xpath-expression-ref" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to the XPathExpression instance to be
|
||||
evaluated against the input Message's payload. Either
|
||||
this or 'xpath-expression' must be provided, but not
|
||||
both.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.xml.xpath.XPathExpression"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="XPathRouterType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="commonXPathRouterType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="mapping" type="integration:mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
If the values returned by the Xpaxth Expression
|
||||
do not represent the channel names itself, additional
|
||||
mappings can be specified using the mapping sub-element.
|
||||
|
||||
For example if the '/request/responders' expression
|
||||
results in two values 'responderA' and 'responderB'
|
||||
but you don't want to couple the responder names
|
||||
to channel names you may provide additional mappings
|
||||
such as:
|
||||
|
||||
<int-xml:mapping value="responderA" channel="channelA"/>
|
||||
<int-xml:mapping value="responderB" channel="channelB"/>
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="integration:topLevelRouterAttributeGroup"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="XPathRouterTypeChain">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="commonXPathRouterType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="mapping" type="integration:mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
If the values returned by the Xpaxth Expression
|
||||
do not represent the channel names itself, additional
|
||||
mappings can be specified using the mapping sub-element.
|
||||
|
||||
For example if the '/request/responders' expression
|
||||
results in two values 'responderA' and 'responderB'
|
||||
but you don't want to couple the responder names
|
||||
to channel names you may provide additional mappings
|
||||
such as:
|
||||
|
||||
<int-xml:mapping value="responderA" channel="channelA"/>
|
||||
<int-xml:mapping value="responderB" channel="channelB"/>
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="xpath-router" type="XPathRouterType"/>
|
||||
|
||||
<xsd:element name="xpath-selector">
|
||||
<xsd:complexType>
|
||||
@@ -468,12 +479,26 @@
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="xpath-expression">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines an XPath expression.
|
||||
|
||||
Internally XPath expressions will be evaluated as
|
||||
NODESET type and converted to a List<String>
|
||||
representing channel names. Typically such list
|
||||
will contain a single channel name. However, based
|
||||
on the result of an XPath Expression the XPath router
|
||||
can also take on the characteristics of the
|
||||
Recipient List Router if the XPath Expression
|
||||
returns more then one value, thus resulting in
|
||||
the List<String> containing more then one channel
|
||||
name.
|
||||
|
||||
In that case Message will be sent to all channels
|
||||
in the list.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines an XPath expression.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="beans:map" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
|
||||
@@ -125,19 +125,6 @@ public class XPathRouterParserTests {
|
||||
inputChannel.send(docMessage);
|
||||
assertEquals("Wrong number of messages", 1, outputChannel.getQueueSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetChannelResolver() throws Exception {
|
||||
StringBuffer contextBuffer = new StringBuffer("<si-xml:xpath-router id='router' channel-resolver='stubResolver' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
|
||||
contextBuffer.append("<bean id='stubResolver' class='").append(StubChannelResolver.class.getName()).append("'/>");
|
||||
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
|
||||
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
|
||||
Object handler = accessor.getPropertyValue("handler");
|
||||
accessor = new DirectFieldAccessor(handler);
|
||||
Object resolver = accessor.getPropertyValue("channelResolver");
|
||||
assertEquals("Wrong channel resolver ",StubChannelResolver.class, resolver.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetResolutionRequiredFalse() throws Exception {
|
||||
@@ -163,32 +150,6 @@ public class XPathRouterParserTests {
|
||||
assertEquals("Resolution required not set to true ", true, resolutionRequired);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoreChannelNameResolutionFailuresFalse() throws Exception {
|
||||
StringBuffer contextBuffer = new StringBuffer(
|
||||
"<si-xml:xpath-router id='router' ignore-channel-name-resolution-failures='false' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
|
||||
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
|
||||
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
|
||||
Object handler = accessor.getPropertyValue("handler");
|
||||
accessor = new DirectFieldAccessor(handler);
|
||||
Object ignoreChannelNameResolutionFailures = accessor.getPropertyValue("ignoreChannelNameResolutionFailures");
|
||||
assertEquals("ignoreChannelNameResolutionFailures not set to false", false, ignoreChannelNameResolutionFailures);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoreChannelNameResolutionFailuresTrue() throws Exception {
|
||||
StringBuffer contextBuffer = new StringBuffer(
|
||||
"<si-xml:xpath-router id='router' ignore-channel-name-resolution-failures='true' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
|
||||
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
|
||||
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
|
||||
Object handler = accessor.getPropertyValue("handler");
|
||||
accessor = new DirectFieldAccessor(handler);
|
||||
Object ignoreChannelNameResolutionFailures = accessor.getPropertyValue("ignoreChannelNameResolutionFailures");
|
||||
assertEquals("ignoreChannelNameResolutionFailures not set to true ", true, ignoreChannelNameResolutionFailures);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetDefaultOutputChannel() throws Exception {
|
||||
StringBuffer contextBuffer = new StringBuffer("<si-xml:xpath-router id='router' default-output-channel='defaultOutput' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
|
||||
|
||||
Reference in New Issue
Block a user