Skip to end of metadata
Go to start of metadata

This section explains, through an example scenario, how the Message Router EIP can be implemented using WSO2 ESB. The following topics are covered:

Introduction to Message Router

The Message Router EIP reads the content of a message and routes it to a specific recipient based on its content. When the implementation of a specific logical function is distributed across multiple physical systems, an incoming request needs to be passed on to the correct service based on the request's content. A Message Router is useful in handling such scenarios.

The following diagram depicts the Message Router's behavior where the router performs a logical function (such as an inventory check). It receives a request message (new order), reads it, and routes the request to one of the two recipients according to the message's content. The router is also defined as a special type of a filter.

For more information on the Message Router, refer to http://www.eaipatterns.com/MessageRouter.html.

 

 

 

 

 

 

Figure 1: Message Router EIP

Example scenario

The example scenario depicts an inventory for stocks, and how Message Router EIP routes a message to a different service based on the message's content. When the router receives a stock request, it reads the content of the request. If the request is made to foo, it is routed to fooOutQueue. If the request is for bar, it is routed to barOutQueue.

The diagram below depicts how to simulate the example scenario using WSO2 ESB.

Figure 2: Example Scenario of the Message Router EIP

Before digging into implementation details, let's take a look at the relationship between the example scenario and the Message Router EIP by comparing their core components.

Message Router EIP (Figure 1)Message Router Example Scenario (Figure 2)

Incoming message

Stock Quote Request

Message router

 

The Switch and Send mediators of the WSO2 ESB simulate the Message Router EIP. The Switch Mediator depicts the Router and observes the content of the message, while the Send Mediator sends the message to a selected recipient.

Each case defined should decide on routing the message to the appropriate service.

Outgoing queues

fooOutQueue and barOutQueue act as two separate services in the example scenario.

Environment setup

  1. Download and install WSO2 ESB from http://wso2.com/products/enterprise-service-bus. For a list of prerequisites and step-by-step installation instructions, refer to Installation Guide in the WSO2 ESB documentation.
  2. Start two Sample Axis2 server instances in ports 9000 and 9002. For instructions, refer to Setting Up the ESB Samples - Starting the Axis2 server in the WSO2 ESB documentation.

ESB configuration

Start the ESB server and log into its management console UI (https://localhost:9443/carbon). In the management console, navigate to the Main menu and click Source View in the Service Bus section. Next, copy and paste the following configuration, which helps you explore the example scenario, to the source view.

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
    <registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
      <parameter name="cachableDuration">15000</parameter>
    </registry>
    <!-- Receiving sequence which will be the message router -->
    <sequence name="MessageRoute">
      <in>
        <!-- Would analyze the data for filtering -->  
        <switch xmlns:m0="http://services.samples" source="//m0:getQuote/m0:request/m0:symbol">
            <!-- If the content is "foo" -->
            <case regex="foo">
                <!-- Sends the information to the fooOutQueue --> 
                <send>
                  <endpoint>
                      <address uri="http://localhost:9000/services/SimpleStockQuoteService?wsdl"/>
                  </endpoint>
                </send>
            </case>
            <!-- If the content is "bar" -->
            <case regex="bar">
                <!-- Sends the information to the barOutQueue -->
                <send>
                  <endpoint>
                      <address uri="http://localhost:9001/services/SimpleStockQuoteService?wsdl"/>
                  </endpoint>
                </send>
            </case>
            <default>
                <property name="symbol" expression="fn:concat('Normal Stock - ', //m0:getQuote/m0:request/m0:symbol)"/>
            </default>
         </switch>
      </in>
      <out>
          <send/>
      </out>
    </sequence>
    <sequence name="fault">
        <log level="full">
          <property name="MESSAGE" value="Executing default 'fault' sequence"/>
          <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
          <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
      </log>
      <drop/>
    </sequence>
    <sequence name="main">
      <in>
         <!-- Will call the message router -->
         <sequence key="MessageRoute"/>
      </in>
      <out>
         <send/>
      </out>
      <description>Message Router</description>
    </sequence>
</definitions>

Simulating the sample scenario

  1. Next, we use a sample SOAP client by the name Stock Quote client to send a request using WSO2 ESB in the following manner. For more information on the Stock Quote client, refer to the Sample Clients section in the WSO2 ESB documentation.

    ant stockquote -Dtrpurl=http://localhost:8280 -Dsymbol=foo

  2. After you execute the above command through the client, observe that the request is transferred to foo inventory service. If the -Dsymbol parameter is changed to bar, the request goes to bar inventory service. The structure of the request is as follows:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
       <soapenv:Header>    
       </soapenv:Header> 
       <soapenv:Body>
            <ser:getQuote>         
             <ser:request>
                 <ser:symbol>foo</ser:symbol>
             </ser:request>       
          </ser:getQuote>
       </soapenv:Body>
    </soapenv:Envelope>

How the implementation works

Let's investigate the elements of the ESB configuration in detail. The line numbers below refer to the ESB configuration shown above.

  • switch [line 10 in ESB config] - Observes the message and filters out the content to the given xPath expression.
  • case  [line 12 in ESB config] - The filtered content will be matched with the specified regular expression.
  • send [line 14 in ESB config] - When a matching case for foo is found, the message is routed to the specified endpoint indicated in the address URI.
  • send [line 23 in ESB config] - When a matching case for bar is found, the message is routed to the specified endpoint indicated in the address URI.
  • default [line 29 in ESB config] - If a matching condition is not found, the message will be diverted to the default case.
  • main sequence [line 46 in ESB config] - The default sequence that is triggered when the user invokes the ESB server.
  • in [line 47 in ESB config] - After the message is received by the main sequence, it is diverted to the in mediator.
  • out [line 51 in ESB config] - Triggered after execution of steps defined through the in mediator.
  • sequence [line 49 in ESB config] - An external sequence specified by key (in this example, the MessageRoute sequence) where requests are directed.
  • send [line 52 in ESB config] - Routes the message back to the requesting client.
  • No labels