Announcement Announcement Module
Collapse
No announcement yet.
EAI: Content Based Filter with Spring Integration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • EAI: Content Based Filter with Spring Integration

    Hi there,

    I am trying to implement simple content based router using Spring integration and cannot figure out what should be the right way.

    Case
    On input channel I receive a simple XML message
    HTML Code:
    <passenger>
        <name>John</name>
        <age>28</age>
    </passenger>
    Based on the age value i want to determine whether a passenger is infant, child or adult, and direct message to a corresponding channel, i.e. infantChannel, childChannel or adultChannel. I want to use XPath to define conditions of the content based filter, since it is XML message.

    Apache Camel Solution
    With Apache Camel it is rather straight forward

    HTML Code:
    <route>
        <from uri="file:src/test/resources/message?noop=true"/>
        <choice>
            <when>
                <xpath>/passenger/age &lt;= '1'</xpath>
                <log message="INFANT"/>
            </when>
            <when>
                <xpath>/passenger/age &gt; '1' and /passenger/age &lt;= '12'</xpath>
                <log message="CHILD"/>
            </when>
            <when>
                <xpath>/passenger/age &gt; '12'</xpath>
                <log message="ADULT"/>
            </when>
            <otherwise>
                <log message="ERROR"/>
            </otherwise>
        </choice>
    </route>
    Spring Integration Solution
    Well... I wasn't able to figure out and run out of patience. That is why I am writing to this forum.

    It was logical to use <xpath-router>, but based on the documentation the output channels are determined dynamically based on the result of the XPath expression.

    What I am trying to do is the following
    HTML Code:
    <si-xml:xpath-router id="passengerRouter" input-channel="passengerChannel" resolution-required="true" >
        <si-xml:xpath-expression expression="/passenger/age"/>
    </si-xml:xpath-router>
    Based on the doc, the XPath expressions are evaluated as NODESET and converter to list of strings, where every value of this list represents a channel name to which this message will be sent. In my case this will be just a list of integers from <age> message element and this this is not what I want. I just have four channels I want the message to be sent to.

    So, my question is how to configure <xpath-router> to implement my case?

    Thanks in advance.
    Last edited by opatopa; Nov 4th, 2012, 06:07 AM.

  • #2
    The xpath router (currently) routes on the value, or a channel mapped from the value. It currently doesn't support conditional routing based on the value of the xpath expression. This would seem to me a useful enhancement; please open a new feature JIRA https://jira.springsource.org/browse/INT.

    In the meantime, the following can be used:

    Code:
    <int:chain input-channel="foo">
    	<int-xml:xpath-header-enricher>
    		<int-xml:header name="passengerAge" evaluation-type="NUMBER_RESULT" xpath-expression="/passenger/age" />
    	</int-xml:xpath-header-enricher>
    	<int:recipient-list-router>
    		<int:recipient channel="infant" selector-expression="headers['passengerAge'] le 1" />
    		<int:recipient channel="child" selector-expression="headers['passengerAge'] gt 1 and headers['passengerAge'] le 12" />
    		<int:recipient channel="adult" selector-expression="headers['passengerAge'] gt 12" />		
    	</int:recipient-list-router>
    </int:chain>
    Essentially, it evaluates the xpath expression once, and puts the result in a header; the selector-expressions in the RLR then routes to the appropriate channel based on the header value.

    Hope that helps.

    Comment


    • #3
      Thanks Gary, that helped indeed. Even though, from EIP point of view Recipient List is slightly different pattern then Content Based Router (more precisely its subset), I was able to see how it is implemented using Spring Integration.

      I have created a JIRA task: https://jira.springsource.org/browse/INT-2808

      Comment

      Working...
      X