4 Replies Latest reply on Jul 24, 2006 7:55 AM by Mark Little

    Content-based routing

    Dave Dunkin Newbie

      I would like to work on defining how we can do content based routing. I have developed an inhouse ESB that includes a content based routing function, so I do have some insight in this area.

      In our inhouse system, we have many adapter components that plug into a core. These adapters may handle specific types of input documents (e.g. an Ariba OrderRequest document) or a range of documents. Our system uses OAGIS, an XML "business language," as the common language for the system, so all messages are converted to OAGIS documents if they're not already in that format.

      Here's where the content-based routing comes in. The adapter components in our ESB are deployed with a set of routing rules. These rules basically say "for a document matching this XPath expression, send the document to this location (an instance of an adapter component bound in the JNDI tree)." We use drools 2.1 and a simple custom DSL. Here are a few examples of rulesets:

      <rule-set name="NDSRoutingRules" xmlns="http://drools.org/rules"
       xmlns:rr="http://www.dis-corp.com/xml/ebiz/routing/dsl/1.0" xmlns:ebiz="http://www.dis-corp.com/xml/ebusiness/2.0" xmlns:oa="http://www.openapplications.org/oagis/9">
      
       <rule name="ProcessRFQ_to_dealer">
       <rr:matches>/ebiz:ProcessRFQ/oa:DataArea/oa:RFQ/oa:RFQHeader/oa:SupplierParty/oa:PartyIDs/oa:ID[@schemeURI='http://www.dis-corp.com/xml/ebusiness/2.0/dealer']</rr:matches>
       <rr:destination>
       <rr:var name="dealerId">/ebiz:ProcessRFQ/oa:DataArea/oa:RFQ/oa:RFQHeader/oa:SupplierParty/oa:PartyIDs/oa:ID[@schemeURI='http://www.dis-corp.com/xml/ebusiness/2.0/dealer']</rr:var>
       <rr:template>dealers/{dealerId}/ebiz1</rr:template>
       </rr:destination>
       </rule>
      </rule-set>
      


      <rule-set name="KomatsuPartsAvailabilityRoutingRules" xmlns="http://drools.org/rules"
       xmlns:rr="http://www.dis-corp.com/xml/ebiz/routing/dsl/1.0" xmlns:ebiz="http://www.dis-corp.com/xml/ebusiness/2.0" xmlns:oa="http://www.openapplications.org/oagis/9">
      
       <rule name="Rule">
       <rr:equals>
       <rr:path>/ebiz:ProcessRFQ/oa:DataArea/oa:RFQ/oa:RFQHeader/oa:SupplierParty/oa:PartyIDs/oa:ID[@schemeURI='http://www.dis-corp.com/xml/ebusiness/2.0/services']</rr:path>
       <rr:value>komatsu-pa</rr:value>
       </rr:equals>
       <rr:destination>
       <rr:template>services/komatsu/PartsAvailability</rr:template>
       </rr:destination>
       </rule>
      </rule-set>
      


      So for us, the requirement of content-based routing is pretty simple: be able to determine destination address of a message from an XPath expression. Does anyone else have examples of how they would like content-based routing to work?

      I would like to start playing around with the existing routing in JBossESB, but I haven't been able to find the code that actually does any sort of routing. Can someone point me in the right direction? Thanks.

      Dave D.


        • 1. Re: Content-based routing
          Mark Little Master

          Hi Dave. Unfortunately the alpha (and beta) versions of JBossESB won't have clean enough support for content based routing. But it is on the plan for the GA release. How this fits into the architecture was outlined in the original architecture document from February (on the labs web site, I think). But now is a great time to start the discussion about how to move it from architectural theory into practice because we're now looking at how to bring the current ESB architecture in line with the February document.

          Give me a chance to put some of the original ideas down here and then we can start looking at how what you've done could fit in.

          • 2. Re: Content-based routing
            Dave Dunkin Newbie

            There has to be something in the existing code that says "this message from point A goes to point B." I'm having trouble even finding that.

            • 3. Re: Content-based routing
              Daniel Brum Novice

              Dave, that is all basically done in the configuration of the end-points. Right now, in the trunk of SVN, you can configure a JMS, FIle or SQL table end-points. Those end-points are configurable by way of the paramter file, a sample of which you can see in the File Test shipped with Alpha1. Those end-points, have an Action class that will be invoked. I think right now, you should start to look at the Action/Processor classes as the starting point for your tests. Please use the Trunk though, what is in the Alpha has been re-factored and changed a lot since then. Here is a sample Parameter config which shows what I am talking about that will be included as part of the new docs for the next Beta release:

              <ListenOnJMS
               parmsReloadSecs="60"
              >
               <CreditRequest
               actionClass="org.jboss.soa.esb.samples.loanbroker.actions.ProcessCreditRequest"
               maxThreads="1"
               listenQueue="queue/A"
               listenMsgSelector="sample_loanbroker_servicecode='creditRequest'"
               >
              
               <NotificationList type="OK">
               <target class="NotifyEmail"
               from="ILoveLucy@jbos.com"
               sendTo="bill@microsoft.com"
               subject="Message processed: -LoanBroker TrailBlazer-"
               message="Message from JBossESB: Processor -JMS Listener - LoanBroker TrailBlazer- completed successfully"
               />
               </NotificationList>
              
               <NotificationList type="err">
               <target class="NotifyEmail"
               from="ILoveLucy@jboss.com"
               sendTo="bill@microsoft.com"
               subject="Message processed: -LoanBroker TrailBlazer-"
               message="Message from JBossESB: Processor -JMS Listener - LoanBroker TrailBlazer- had ERRORS"
               />
               </NotificationList>
               </CreditRequest>
              
               <CreditResponse
               actionClass="org.jboss.soa.esb.samples.loanbroker.actions.ProcessCreditResponse"
               maxThreads="1"
               listenQueue="queue/A"
               listenMsgSelector="sample_loanbroker_servicecode='creditResponse'"
               >
              
               <NotificationList type="OK">
               <target class="NotifyEmail"
               from="ILoveLucy@jbos.com"
               sendTo="bill@microsoft.com"
               subject="Message processed: -LoanBroker TrailBlazer-"
               message="Message from JBossESB: Processor -JMS Listener - LoanBroker TrailBlazer- completed successfully"
               />
               </NotificationList>
              
               <NotificationList type="err">
               <target class="NotifyEmail"
               from="ILoveLucy@jboss.com"
               sendTo="bill@microsoft.com"
               subject="Message processed: -LoanBroker TrailBlazer-"
               message="Message from JBossESB: Processor -JMS Listener - LoanBroker TrailBlazer- had ERRORS"
               />
               </NotificationList>
               </CreditResponse>
              </ListenOnJMS>
              


              Hope this points you in the right direction.

              Daniel

              • 4. Re: Content-based routing
                Mark Little Master

                Dave, simple is good for a start and the requirements that you outlined are reasonable. I have a couple of questions on what you said.

                "ddunkin" wrote:
                In our inhouse system, we have many adapter components that plug into a core. These adapters may handle specific types of input documents (e.g. an Ariba OrderRequest document) or a range of documents.


                If you read the original requirements architecture document for JBossESB from March 2006, you'll notice that we have the concept of multiple buses. Each bus can be for a different requirement, e.g., SOAP/HTTP or JMS, lifecycle messages (start/stop a service etc.), or application content. So in our architecture, it would seem that the requirement you've just described could be modeled as a bus per type of document(s). Would that be a fair assessment?


                Our system uses OAGIS, an XML "business language," as the common language for the system, so all messages are converted to OAGIS documents if they're not already in that format.


                Sounds like a good candidate for one of the formats we could transform from/to once Tom gets up to speed. We currently don't have a default message format and I was wondering what the pros and cons are of OAGIS. Could you start a separate thread in the forum on that and just seed it with your impressions of using OAGIS?


                Here's where the content-based routing comes in. The adapter components in our ESB are deployed with a set of routing rules.


                How configurable is this? Is it static or can it be updated dynamically?

                These rules basically say "for a document matching this XPath expression, send the document to this location (an instance of an adapter component bound in the JNDI tree)." We use drools 2.1 and a simple custom DSL.


                The dispatcher component within our ESB architecture has always been the place I've looked to add content-based routing. I think that's still the case, but would be interested in your feedback.


                So for us, the requirement of content-based routing is pretty simple: be able to determine destination address of a message from an XPath expression. Does anyone else have examples of how they would like content-based routing to work?


                Presumably it's not just addresses? I've seen examples of CBR where the routing algorithm is finer grained: for example address and payload ("operation"). I've also seen deployments that use stateful routing algorithms, e.g., "if the last interaction put us into state A, then route this msg here, otherwise route it here." There's an argument that stateful interactions should be dealt with at the higher level by a process flow component and I haven't had time to revisit this in enough depth. Certainly some transient stateful interactions may be better dealt with within the lower levels, e.g., fault tolerance.