WSO2 ESB - Advanced Mediation Samples

Running the Advanced Mediation samples with WSO2 Enterprise Service Bus (ESB)

Using scripts in mediation (Script Mediator)

The ESB Script Mediator is a ESB extension, and thus all prerequisites are not bundled by default with the ESB distribution. Before you use some script mediators you may need to manually add the required jar files to the ESB lib directory, and optionally perform other installation tasks as may be required by the individual scripting language. This is explained in the Samples Setup guide.

Sample 350: Introduction to the script mediator using js scripts

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <localEntry key="stockquoteScript" src="file:repository/samples/resources/script/stockquoteTransform.js"/>

    <in>
        <!-- transform the custom quote request into a standard quote request expected by the service -->
        <script language="js" key="stockquoteScript" function="transformRequest"/>
        <send>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
        </send>
    </in>
    <out>
        <!-- transform the standard response back into the custom format the client expects -->
        <script language="js" key="stockquoteScript" function="transformResponse"/>
        <send/>
    </out>
</definitions> 
<x><![CDATA[
  function transformRequest(mc) {
     var symbol = mc.getPayloadXML()..*::Code.toString();
     mc.setPayloadXML(
        <m:getQuote xmlns:m="http://services.samples">
           <m:request>
              <m:symbol>{symbol}</m:symbol>
           </m:request>
        </m:getQuote>);
  }

  function transformResponse(mc) {
     var symbol = mc.getPayloadXML()..*::symbol.toString();
     var price = mc.getPayloadXML()..*::last.toString();
     mc.setPayloadXML(
        <m:CheckPriceResponse xmlns:m="http://services.samples/xsd">
   <m:Code>{symbol}</m:Code>
   <m:Price>{price}</m:Price>
        </m:CheckPriceResponse>);
  }
]]></x>

Objective: Introduction to the script mediators

Prerequisites:

Start the Synapse configuration numbered 350: i.e. wso2esb-samples -sn 350
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This sample is similar to sample 8 but instead of using XSLT the transformation is done with JavaScript and E4X. Note that the script source loaded from a resource must be specified within a CDATA tag within an XML element. The script used in this example has two functions, 'transformRequest' and 'transformResponse', and the Synapse configuration uses the function attribute to specify which function should be invoked. Use the stock quote client to issue a custom quote client as follows.:

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dmode=customquote

ESB uses the script mediator and the specified Javascript function to convert the custom request to a standard quote request. Subsequently the response received is transformed and sent back to the client.

Sample 351: In-line script mediation with JavaScript

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <in>
        <!-- transform the custom quote request into a standard quote requst expected by the service -->
        <script language="js"><![CDATA[
               var symbol = mc.getPayloadXML()..*::Code.toString();
               mc.setPayloadXML(
                  <m:getQuote xmlns:m="http://services.samples/xsd">
                     <m:request>
                        <m:symbol>{symbol}</m:symbol>
                     </m:request>
                  </m:getQuote>);
        ]]></script>
        <send>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
        </send>
    </in>
    <out>
        <!-- transform the standard response back into the custom format the client expects -->
        <script language="js"><![CDATA[
               var symbol = mc.getPayloadXML()..*::symbol.toString();
               var price = mc.getPayloadXML()..*::last.toString();
               mc.setPayloadXML(
                  <m:CheckPriceResponse xmlns:m="http://services.samples/xsd">
               <m:Code>{symbol}</m:Code>
               <m:Price>{price}</m:Price>
                  </m:CheckPriceResponse>);
            ]]></script>
        <send/>
    </out>
</definitions> 

Objective: Introduction to in-line script mediation

Prerequisites:

Start the Synapse configuration numbered 351: i.e. wso2esb-samples -sn 351
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This example is functionally equivalent to sample # 350 and sample # 8, and demonstrates in-line script mediation in ESB. Use the stock quote client to send a custom quote as in example # 350 to test this example.

Sample 352: Accessing Synapse message context API methods using scripting language

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <in>
       <!-- change the MessageContext into a response and set a response payload -->
       <script language="js"><![CDATA[
          mc.setTo(mc.getReplyTo());
          mc.setProperty("RESPONSE", "true");
          mc.setPayloadXML(
             <ns:getQuoteResponse xmlns:ns="http://services.samples/xsd">
                <ns:return>
                   <ns:last>99.9</ns:last>
                </ns:return>
             </ns:getQuoteResponse>);
       ]]></script>
    </in>
    <send/>
</definitions> 

Objective: Accessing the Synapse APIs from scripting languages

Prerequisites:

Start the Synapse configuration numbered 352: i.e. wso2esb-samples -sn 352

This example shows how an inline JavaScript mediator script could access the Synapse message context API to set its 'To' EPR and to set a custom property to mark it as a response. Execute the stock quote client, and you will receive the response "99.9" as the last sale price as per the above script.

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/
 ...
stockquote:
     [java] Standard :: Stock price = $99.9

Sample 353: Using Ruby scripts for mediation

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <localEntry key="stockquoteScript" src="file:repository/samples/resources/script/stockquoteTransform.rb"/>
    <in>
        <!-- transform the custom quote request into a standard quote request expected by the service -->
        <script language="rb" key="stockquoteScript" function="transformRequest"/>

        <!-- send message to real endpoint referenced by name "stockquote" and stop -->
        <send>
            <endpoint name="stockquote">
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
        </send>
    </in>
    <out>
        <!-- transform the standard response back into the custom format the client expects -->
        <script language="rb" key="stockquoteScript" function="transformResponse"/>
        <send/>
    </out>
</definitions> 
<x><![CDATA[
require 'rexml/document'
include REXML

def transformRequest(mc)
   newRequest= Document.new '<m:getQuote xmlns:m="http://services.samples/xsd">'<<
      '<m:request><m:symbol></m:symbol></m:request></m:getQuote>'
   newRequest.root.elements[1].elements[1].text = mc.getPayloadXML().root.elements[1].get_text
   mc.setPayloadXML(newRequest)
end

def transformResponse(mc)
   newResponse = Document.new '<m:CheckPriceResponse xmlns:m="http://services.samples/xsd"><m:Code>' <<
      '</m:Code><m:Price></m:Price></m:CheckPriceResponse>'
   newResponse.root.elements[1].text = mc.getPayloadXML().root.elements[1].elements[1].get_text
   newResponse.root.elements[2].text = mc.getPayloadXML().root.elements[1].elements[2].get_text
   mc.setPayloadXML(newResponse)
end
]]></x>

Objective: Script mediators using Ruby

Prerequisites:

This sample uses Ruby so first setup support for this in ESB as described at Configuring JRuby.

Start the Synapse configuration numbered 353: i.e. wso2esb-samples -sn 353
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This sample is functionally equivalent to sample # 350 (#351 and #8) but instead uses a Ruby script using the JRuby interpreter. The script has two functions, 'transformRequest' and 'transformResponse', and the Synapse configuration specifies which function is to be invoked when used. Execute the stock quote client to send a custom stock quote as per example #350 and check the received stock quote response.

Sample 354: Using In-lined Ruby scripts for mediation

<!-- Using In-lined Ruby scripts for mediation -->
<definitions xmlns="http://ws.apache.org/ns/synapse">
    <in>
        <script language="rb">
            <![CDATA[
                require 'rexml/document'
                include REXML
                newRequest= Document.new '<m:getQuote xmlns:m="http://services.samples/xsd"><m:request><m:symbol>...test...</m:symbol></m:request></m:getQuote>'
                newRequest.root.elements[1].elements[1].text = $mc.getPayloadXML().root.elements[1].get_text
                $mc.setPayloadXML(newRequest)
            ]]>
        </script>
        <send>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
        </send>
    </in>
    <out>
        <script language="rb">
            <![CDATA[
                require 'rexml/document'
                include REXML
                newResponse = Document.new '<m:CheckPriceResponse xmlns:m="http://services.samples/xsd"><m:Code></m:Code><m:Price></m:Price></m:CheckPriceResponse>'
                newResponse.root.elements[1].text = $mc.getPayloadXML().root.elements[1].elements[1].get_text
                newResponse.root.elements[2].text = $mc.getPayloadXML().root.elements[1].elements[2].get_text
                $mc.setPayloadXML(newResponse)
            ]]>
        </script>
        <send/>
    </out>
</definitions> 

Objective: Script mediators using Ruby(In-lined Ruby Script)

Prerequisites:

This sample uses Ruby so first setup support for this in ESB as described at Configuring JRuby.

Start the Synapse configuration numbered 354: i.e. wso2esb-samples -sn 354
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This sample is functionally equivalent to the sample #353.

Runs the client with

 ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dmode=customquote

Database interactions in mediation (DBLookup / DBReport)

Following database mediators use Derby in a client/server configuration by using the network server. Therefore, to proceed with the following samples, you need a working Derby database server and you have to follow the steps in Sample Setup Guide before going through the samples.

Sample 360: Introduction to dblookup mediator

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="myFaultHandler">
        <makefault>
            <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason expression="get-property('ERROR_MESSAGE')"/>
        </makefault>

        <property name="RESPONSE" value="true"/>
        <header name="To" expression="get-property('ReplyTo')"/>
        <send/>
        <drop/>
    </sequence>

    <sequence name="main" onError="myFaultHandler">
        <in>
            <log level="custom">
                <property name="text"
                          value="** Looking up from the Database **"/>
            </log>
            <dblookup xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <driver>org.apache.derby.jdbc.ClientDriver</driver>
                        <url>jdbc:derby://localhost:1527/esbdb;create=false</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>select * from company where name =?</sql>
                    <parameter expression="//m0:getQuote/m0:request/m0:symbol"
                               xmlns:m0="http://services.samples/xsd" type="VARCHAR"/>
                    <result name="company_id" column="id"/>
                </statement>
            </dblookup>

            <switch source="get-property('company_id')">
                <case regex="c1">
                    <log level="custom">
                        <property name="text"
                                  expression="fn:concat('Company ID - ',get-property('company_id'))"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
                <case regex="c2">
                    <log level="custom">
                        <property name="text"
                                  expression="fn:concat('Company ID - ',get-property('company_id'))"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
                <case regex="c3">
                    <log level="custom">
                        <property name="text"
                                  expression="fn:concat('Company ID - ',get-property('company_id'))"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
                <default>
                    <log level="custom">
                        <property name="text" value="** Unrecognized Company ID **"/>
                    </log>
                    <makefault>
                        <code value="tns:Receiver"
                              xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
                        <reason value="** Unrecognized Company ID **"/>
                    </makefault>
                    <property name="RESPONSE" value="true"/>
                    <header name="To" action="remove"/>
                    <send/>
                    <drop/>
                </default>
            </switch>
            <drop/>
        </in>

        <out>
            <send/>
        </out>

    </sequence>

</definitions>

Objective:Introduction to the dblookup mediator

Prerequisites: Setting up Derby database as explained above.

Start the Synapse configuration numbered 360: i.e. wso2esb-samples -sn 360

Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This sample demonstrates simple database read operations through ESB. When a message arrives at dblookup mediator, it opens a connection to the database and executes the SQL query. The SQL query use '?' character for attributes that will be filled at runtime. The parameters define how to calculate the value of those attributes at runtime. In this sample a dblookup mediator has been used to extract 'id' of the company from the company database using the symbol which is evaluated using an xpath against the SOAP envelope. Then 'id' base switching will be done by a switch mediator.

When the IBM stock quote is requested,

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=IBM

ESB console shows

INFO LogMediator text = ** Looking up from the Database **INFO LogMediator text = Company ID ? c1

For the SUN stock quote,

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=SUN

ESB console shows

INFO LogMediator text = ** Looking up from the Database **INFO LogMediator text = Company ID ? c2

and for the MSFT stock quote,

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=MSFT
INFO LogMediator text = ** Looking up from the Database **
INFO LogMediator text = Company ID ? c2

For any other symbols, ESB console shows

INFO LogMediator text = ** Unrecognized Company ID **

and the client gets a response which has following message.

** Unrecognized Company ID **

Sample 361: Introduction to dbreport mediator

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main">
        <in>
            <send>
                <endpoint>
                    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                </endpoint>
            </send>
        </in>

        <out>
            <log level="custom">
                <property name="text"
                          value="** Reporting to the Database **"/>
            </log>
            <dbreport xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <driver>org.apache.derby.jdbc.ClientDriver</driver>
                        <url>jdbc:derby://localhost:1527/esbdb;create=false</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>update company set price=? where name =?</sql>
                    <parameter expression="//m0:return/m1:last/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="DOUBLE"/>
                    <parameter expression="//m0:return/m1:symbol/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="VARCHAR"/>
                </statement>
            </dbreport>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Introduction to the dbreport mediator

Prerequisites: Setting up Derby database as above.

Start the Synapse configuration numbered 361: i.e. wso2esb-samples -sn 361

Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This sample demonstrate simple database write operations. The dbreport mediator writes (i.e. inserts one row) to a table using the message details. It works the same as the dblookup mediator. In this sample , dbreport mediator is used for updating the stock price of the company using the last quote value which is calculated by evaluating an XPath against the response message. After running this sample, user can check the company table using the Derby client tool. It will show the inserted value by the dbreport mediator.

Run the client using,

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=IBM

and then execute the following query using database client tool against synapsedb.

select price from company where name='IBM';

It will show some value as follows.

96.39535981018865

Sample 362: Action of dbreport and dblookup mediators together

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main">
        <in>
            <send>
                <endpoint>
                    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                </endpoint>
            </send>
        </in>

        <out>
            <log level="custom">
                <property name="text"
                          value="** Reporting to the Database **"/>
            </log>

            <dbreport xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <driver>org.apache.derby.jdbc.ClientDriver</driver>
                        <url>jdbc:derby://localhost:1527/esbdb;create=false</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>update company set price=? where name =?</sql>
                    <parameter expression="//m0:return/m1:last/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="DOUBLE"/>
                    <parameter expression="//m0:return/m1:symbol/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="VARCHAR"/>
                </statement>
            </dbreport>
            <log level="custom">
                <property name="text"
                          value="** Looking up from the Database **"/>
            </log>
            <dblookup xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <driver>org.apache.derby.jdbc.ClientDriver</driver>
                        <url>jdbc:derby://localhost:1527/esbdb;create=false</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>select * from company where name =?</sql>
                    <parameter expression="//m0:return/m1:symbol/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="VARCHAR"/>
                    <result name="stock_price" column="price"/>
                </statement>
            </dblookup>
            <log level="custom">
                <property name="text"
                          expression="fn:concat('Stock price - ',get-property('stock_price'))"/>
            </log>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Demonstrate the use of dbreport and dblookup mediators

Prerequisites: Setting up Derby database as above.

Start the Synapse configuration numbered 362: i.e. wso2esb-samples -sn 362

Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

In this sample ,the dbreport mediator works the same as the above sample. It updates the price for the given company using the response messages content. Then the dblookup mediator reads the last updated value from the company database and logs it.

When running client,

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=IBM

ESB console shows,

INFO LogMediator text = ** Reporting to the Database **

...

INFO LogMediator text = ** Looking up from the Database **

...

INFO LogMediator text = Stock price - 153.47886496064808

Sample 363: Reusable database connection pools

<!-- Reusable database connection pool -->
<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="myFaultHandler">
        <makefault>
            <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason expression="get-property('ERROR_MESSAGE')"/>
        </makefault>

        <property name="RESPONSE" value="true"/>
        <header name="To" expression="get-property('ReplyTo')"/>
        <send/>
        <drop/>
    </sequence>

    <sequence name="main" onError="myFaultHandler">
        <in>
            <log level="custom">
                <property name="text"
                          value="** Looking up from the Database **"/>
            </log>
            <dblookup>
                <connection>
                    <pool>
                        <dsName>lookupdb</dsName>
                        <icClass>com.sun.jndi.rmi.registry.RegistryContextFactory</icClass>
                        <url>rmi://localhost:2199</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>select * from company where name =?</sql>
                    <parameter expression="//m0:getQuote/m0:request/m0:symbol"
                               xmlns:m0="http://services.samples/xsd" type="VARCHAR"/>
                    <result name="company_id" column="id"/>
                </statement>
            </dblookup>

            <switch source="get-property('company_id')">
                <case regex="c1">
                    <log level="custom">
                        <property name="text"
                                  expression="fn:concat('Company ID - ',get-property('company_id'))"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
                <case regex="c2">
                    <log level="custom">
                        <property name="text"
                                  expression="fn:concat('Company ID - ',get-property('company_id'))"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
                <case regex="c3">
                    <log level="custom">
                        <property name="text"
                                  expression="fn:concat('Company ID - ',get-property('company_id'))"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
                <default>
                    <log level="custom">
                        <property name="text" value="** Unrecognized Company ID **"/>
                    </log>
                    <makefault>
                        <code value="tns:Receiver"
                              xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
                        <reason value="** Unrecognized Company ID **"/>
                    </makefault>
                    <property name="RESPONSE" value="true"/>
                    <header name="To" action="remove"/>
                    <send/>
                    <drop/>
                </default>
            </switch>
            <drop/>
        </in>

        <out>
            <log level="custom">
                <property name="text"
                          value="** Reporting to the Database **"/>
            </log>
            <dbreport>
                <connection>
                    <pool>
                        <dsName>reportdb</dsName>
                        <icClass>com.sun.jndi.rmi.registry.RegistryContextFactory</icClass>
                        <url>rmi://localhost:2199</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>update company set price=? where name =?</sql>
                    <parameter expression="//m0:return/m1:last/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="DOUBLE"/>
                    <parameter expression="//m0:return/m1:symbol/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="VARCHAR"/>
                </statement>
            </dbreport>
            <log level="custom">
                <property name="text"
                          value="** Looking up from the Database **"/>
            </log>
            <dblookup>
                <connection>
                    <pool>
                        <dsName>reportdb</dsName>
                        <icClass>com.sun.jndi.rmi.registry.RegistryContextFactory</icClass>
                        <url>rmi://localhost:2199</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>select * from company where name =?</sql>
                    <parameter expression="//m0:return/m1:symbol/child::text()"
                               xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd" type="VARCHAR"/>
                    <result name="stock_price" column="price"/>
                </statement>
            </dblookup>
            <log level="custom">
                <property name="text"
                          expression="fn:concat('Stock price - ',get-property('stock_price'))"/>
            </log>
            <send/>

        </out>

    </sequence>

</definitions>

Objective: Demonstrate the use of reusable database connection pools

Prerequisites: Setting up DataBase and DataSources according to the sample setup guide.

Start the Synapse configuration numbered 363: i.e. wso2esb-samples -sn 363

Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

Runs the client as follows

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/

Then the console output

 INFO LogMediator text = ** Looking up from the Database **
    ...
 INFO LogMediator text = Company ID - c1
    ...
 INFO LogMediator text = ** Reporting to the Database **
    ...
 INFO LogMediator text = ** Looking up from the Database **
    ...
 INFO LogMediator text = Stock price - 183.3635460215262

Sample 364: Executing database Stored Procedures

<definitions xmlns="http://ws.apache.org/ns/synapse"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://ws.apache.org/ns/synapse http://synapse.apache.org/ns/2010/04/configuration/synapse_config.xsd">

    <sequence name="main">
        <in>
            <send>
                <endpoint>
                    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                </endpoint>
            </send>
        </in>

        <out>
            <log level="custom">
                <property name="text" value="** Reporting to the Database **"/>
            </log>

            <dbreport>
                <connection>
                    <pool>
                        <driver>com.mysql.jdbc.Driver</driver>
                        <url>jdbc:mysql://localhost:3306/synapsedb</url>
                        <user>user</user>
                        <password>password</password>
                    </pool>
                </connection>
                <statement>
                    <sql>call updateCompany(?,?)</sql>
                    <parameter xmlns:m0="http://services.samples"
                               xmlns:m1="http://services.samples/xsd"
                               expression="//m0:return/m1:last/child::text()" type="DOUBLE"/>
                    <parameter xmlns:m0="http://services.samples"
                               xmlns:m1="http://services.samples/xsd"
                               expression="//m0:return/m1:symbol/child::text()" type="VARCHAR"/>
                </statement>
            </dbreport>
            <log level="custom">
                <property name="text" value="** Looking up from the Database **"/>
            </log>
            <dblookup>
                <connection>
                    <pool>
                        <driver>com.mysql.jdbc.Driver</driver>
                        <url>jdbc:mysql://localhost:3306/synapsedb</url>
                        <user>user</user>
                        <password>password</password>
                    </pool>
                </connection>
                <statement>
                    <sql>call getCompany(?)</sql>
                    <parameter xmlns:m0="http://services.samples"
                               xmlns:m1="http://services.samples/xsd"
                               expression="//m0:return/m1:symbol/child::text()" type="VARCHAR"/>
                    <result name="stock_prize" column="price"/>
                </statement>
            </dblookup>
            <log level="custom">
                <property name="text"
                          expression="fn:concat('Stock Prize - ',get-property('stock_prize'))"/>
            </log>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Demonstrate the use of dblookup and dbreport mediators to execute a database Stored Procedures

Prerequisites: Set up MySQL database server according to the sample setup guide.

Start the Synapse configuration numbered 364: i.e. wso2esb-samples -sn 364

Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

Runs the client as follows

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=IBM

Then you will get the following console output

INFO LogMediator text = ** Looking up from the Database ** ...
INFO LogMediator text = Company ID - c1 ...
INFO LogMediator text = Stock price - 183.3635460215262

Throttling messages (Throttle Mediator)

Sample 370: Introduction to throttle mediator and concurrency throttling

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <sequence name="main">
        <in>
            <throttle id="A">
                <policy>
                    <!-- define throttle policy -->
                    <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
                                xmlns:throttle="http://www.wso2.org/products/wso2commons/throttle">
                        <throttle:ThrottleAssertion>
                            <throttle:MaximumConcurrentAccess>10</throttle:MaximumConcurrentAccess>
                        </throttle:ThrottleAssertion>
                    </wsp:Policy>
                </policy>
                <onAccept>
                    <log level="custom">
                        <property name="text" value="**Access Accept**"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </onAccept>
                <onReject>
                    <log level="custom">
                        <property name="text" value="**Access Denied**"/>
                    </log>
                    <makefault>
                        <code value="tns:Receiver"
                              xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
                        <reason value="**Access Denied**"/>
                    </makefault>
                    <property name="RESPONSE" value="true"/>
                    <header name="To" action="remove"/>
                    <send/>
                    <drop/>
                </onReject>
            </throttle>
        </in>
        <out>
            <throttle id="A"/>
            <send/>
        </out>
    </sequence>
</definitions>

Objective: Demonstrate the use of throttle mediator for concurrency throttling

Prerequisites:

Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 370 (i.e. wso2esb-samples -sn 370).

Above configuration specifies a throttle mediator inside the in mediator. Therefore, all request messages directed to the main sequence will be subjected to throttling. Throttle mediator has 'policy', 'onAccept' and 'onReject' tags at top level. The 'policy' tag specifies the throttling policy for throttling messages. This sample policy only contains a component called "MaximumConcurrentAccess" .This indicates the maximum number of concurrent requests that can pass through Synapse on a single unit of time. To test concurrency throttling, it is required to send concurrent requests to Synapse. If Synapse with above configuration, receives 20 requests concurrently from clients, then approximately half of those will succeed while the others being throttled. The client command to try this is as follows.

ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8280/

Sample 371: Restricting requests based on policies

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <sequence name="main">
        <in>
            <throttle id="A">
                <policy>
                    <!-- define throttle policy -->
                    <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
                                xmlns:throttle="http://www.wso2.org/products/wso2commons/throttle">
                        <throttle:MediatorThrottleAssertion>
                            <wsp:Policy>
                                <throttle:ID throttle:type="IP">other</throttle:ID>
                                <wsp:Policy>
                                    <throttle:Control>
                                        <wsp:Policy>
                                            <throttle:MaximumCount>4</throttle:MaximumCount>
                                            <throttle:UnitTime>800000</throttle:UnitTime>
                                            <throttle:ProhibitTimePeriod wsp:Optional="true">1000
                                            </throttle:ProhibitTimePeriod>
                                        </wsp:Policy>
                                    </throttle:Control>
                                </wsp:Policy>
                            </wsp:Policy>
                            <wsp:Policy>
                                <throttle:ID throttle:type="IP">10.100.1.160 - 10.100.1.165</throttle:ID>
                                <wsp:Policy>
                                    <throttle:Control>
                                        <wsp:Policy>
                                            <throttle:MaximumCount>5</throttle:MaximumCount>
                                            <throttle:UnitTime>800000</throttle:UnitTime>
                                            <throttle:ProhibitTimePeriod wsp:Optional="true">100000
                                            </throttle:ProhibitTimePeriod>
                                        </wsp:Policy>
                                    </throttle:Control>
                                </wsp:Policy>
                            </wsp:Policy>
                        </throttle:MediatorThrottleAssertion>
                    </wsp:Policy>
                </policy>
                <onAccept>
                    <log level="custom">
                        <property name="text" value="**Access Accept**"/>
                    </log>
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                    </send>
                </onAccept>
                <onReject>
                    <log level="custom">
                        <property name="text" value="**Access Denied**"/>
                    </log>
                    <makefault>
                        <code value="tns:Receiver"
                              xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
                        <reason value="**Access Denied**"/>
                    </makefault>
                    <property name="RESPONSE" value="true"/>
                    <header name="To" action="remove"/>
                    <send/>
                    <drop/>
                </onReject>
            </throttle>
        </in>
        <out>
            <throttle id="A"/>
            <send/>
        </out>
    </sequence>
</definitions>

Objective: Demonstrate the use of throttle mediator for restricting request counts

Prerequisites:

Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 371 (i.e. wso2esb-samples -sn 371).

Above configuration specifies a throttle mediator inside the in mediator. Therefore, all request messages directed to the main sequence will be subjected to throttling. Throttle mediator has policy, onAccept and onReject tags at the top level. Policy tag specifies the throttling policy to be applied for messages. It contains some IP address ranges and the maximum number of messages to be allowed for those ranges within a time period given in "UnitTime" tag. "ProhibitTimePeriod" tag specifies the time period to prohibit further requests after the received request count exceeds the specified time. Now run the client 5 times repetitively using the following command to see how throttling works.

ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8280/

For the first four requests you will get the quote prices for IBM as follows.

[java] Standard :: Stock price = $177.20143371883802

You will receive the following response for the fifth request.

[java] org.apache.axis2.AxisFault: **Access Denied**

Maximum number of requests within 800000 milliseconds is specified as 4 for any server (including localhost) other than the explicitly specified ones. Therefore, our fifth request is denied by the throttle mediator. You can verify this by looking at the ESB console.

[HttpServerWorker-1] INFO  LogMediator - text = **Access Accept**
[HttpServerWorker-2] INFO  LogMediator - text = **Access Accept**
[HttpServerWorker-3] INFO  LogMediator - text = **Access Accept**
[HttpServerWorker-4] INFO  LogMediator - text = **Access Accept**
[HttpServerWorker-5] INFO  LogMediator - text = **Access Denied** 

Sample 372: Use of both concurrency throttling and request rate based throttling

<!-- Use of both concurrency throttling and request rate based throttling -->
<definitions xmlns="http://ws.apache.org/ns/synapse">

    <registry provider="org.wso2.carbon.mediation.registry.ESBRegistry">
        <!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
        <parameter name="root">file:repository/</parameter>
        <!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
        <parameter name="cachableDuration">150000</parameter>
    </registry>

    <sequence name="onAcceptSequence">
        <log level="custom">
            <property name="text" value="**Access Accept**"/>
        </log>
        <send>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
        </send>
    </sequence>
    <sequence name="onRejectSequence" trace="enable">
        <log level="custom">
            <property name="text" value="**Access Denied**"/>
        </log>
        <makefault>
            <code value="tns:Receiver"
                  xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason value="**Access Denied**"/>
        </makefault>
        <property name="RESPONSE" value="true"/>
        <header name="To" action="remove"/>
        <send/>
        <drop/>
    </sequence>
    <proxy name="StockQuoteProxy">
        <target>
             <inSequence>
                <throttle onReject="onRejectSequence" onAccept="onAcceptSequence" id="A">
                    <policy key="repository/samples/resources/policy/throttle_policy.xml"/>
                </throttle>
            </inSequence>
            <outSequence>
                <throttle id="A"/>
                <send/>
            </outSequence>
        </target>
        <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
    </proxy>
</definitions>

Objective: Use of both concurrency throttling and request rate based throttling

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 372 (i.e. wso2esb-samples -sn 372).

Throttle policy is loaded from the ?throttle_policy.xml? .That policy contains merging policy from sample 370 and 371. To check the functionality , it is need to run load test.The all enabled request from the concurrency throttling will be controlled by the access rate base throttling according to the policy.

Run the client as follows

ant stockquote -Daddurl=http://localhost:8280/services/StockQuoteProxy

You will get results same as sample 371.if you run the load test, results will be different due to affect of concurrency throttling.

Extending the mediation in java (Class Mediator)

Class mediator can be used to write your own custom mediation in Java and you have access to the SynapseMessageContext and to the full Synapse API in there. This is a useful extension mechanism within ESB to extend its functionality. This class can contain fields for which you can assign values at runtime through the configuration.

Sample 380: Writing your own custom mediation in Java

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="fault">
        <makefault>
            <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason value="Mediation failed."/>
        </makefault>
        <send/>
    </sequence>

    <sequence name="main" onError="fault">
        <in>
            <send>
                <endpoint name="stockquote">
                    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                </endpoint>
            </send>
        </in>
        <out>
            <class name="samples.mediators.DiscountQuoteMediator">
                <property name="discountFactor" value="10"/>
                <property name="bonusFor" value="5"/>
            </class>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Demonstrate the use of Class mediator to extend the mediation functionality

Prerequisites:

Make sure the synapse-samples-1.0.jar is in your class path (by default this jar is placed in the lib directory when installing ESB).

Start ESB with the sample configuration 380 (i.e. wso2esb-samples -sn 380)

Start the sample Axis2 server and deploy the SimpleStockQuoteService.

In this configuration, ESB hands over the request message to the specified endpoint, which sends it to the Axis2 server running on port 9000.

But the response message is passed through the class mediator before sending it back to the client. Two parameters named "discountFactor"

and "bonusFor" are passed to the instance mediator implementation class (i.e. samples.mediators.DiscountQuoteMediator) before each

invocation. Code of the mediator implementation class is shown below.

package samples.mediators;

import org.apache.synapse.MessageContext;
import org.apache.synapse.Mediator;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;

public class DiscountQuoteMediator implements Mediator {

    private static final Log log = LogFactory.getLog(DiscountQuoteMediator.class);

    private String discountFactor="10";

    private String bonusFor="10";

    private int bonusCount=0;

    public DiscountQuoteMediator(){}

    public boolean mediate(MessageContext mc) {

        String price= mc.getEnvelope().getBody().getFirstElement().getFirstElement().
                getFirstChildWithName(new QName("http://services.samples/xsd","last")).getText();

        //converting String properties into integers
        int discount=Integer.parseInt(discountFactor);
        int bonusNo=Integer.parseInt(bonusFor);
        double currentPrice=Double.parseDouble(price);

        //discounting factor is deducted from current price form every response
        Double lastPrice = new Double(currentPrice - currentPrice * discount / 100);

        //Special discount of 5% offers for the first responses as set in the bonusFor property
        if (bonusCount <= bonusNo) {
            lastPrice = new Double(lastPrice.doubleValue() - lastPrice.doubleValue() * 0.05);
            bonusCount++;
        }

        String discountedPrice = lastPrice.toString();

        mc.getEnvelope().getBody().getFirstElement().getFirstElement().getFirstChildWithName
                (new QName("http://services.samples/xsd","last")).setText(discountedPrice);

        System.out.println("Quote value discounted.");
        System.out.println("Original price: " + price);
        System.out.println("Discounted price: " + discountedPrice);

        return true;
    }

    public String getType() {
        return null;
    }

    public void setTraceState(int traceState) {
        traceState = 0;
    }

    public int getTraceState() {
        return 0;
    }

    public void setDiscountFactor(String discount) {
        discountFactor=discount;
    }

    public String getDiscountFactor() {
        return discountFactor;
    }

    public void setBonusFor(String bonus){
        bonusFor=bonus;
    }

    public String getBonusFor(){
        return bonusFor;
    }
}

All classes developed for class mediation should implement the Mediator interface, which contains the mediate(...) method. mediate(...) method of the above class is invoked for each response message mediated through the main sequence, with the message context of the current message as the parameter. All the details of the message including the SOAP headers, SOAP body and properties of the context hierarchy can be accessed from the message context. In this sample, the body of the message is retrieved and the discount percentage is subtracted from the quote price. If the quote request number is less than the number specified in the "bonusFor" property in the configuration, a special discount is given.

Now run the client using the following command.

ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8280

You will see the below output in the client console with the discounted quote value.

[java] Standard :: Stock price = $138.77458254967408

Now check the console running Synapse. You will see the original value and the discounted value for the requested quote as follows.

Quote value discounted.
Original price: 162.30945327447262
Discounted price: 138.77458254967408

Sample 381: Class mediator to CBR binary message

<definitions xmlns="http://ws.apache.org/ns/synapse"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://ws.apache.org/ns/synapse http://synapse.apache.org/ns/2010/04/configuration/synapse_config.xsd">

    <proxy name="JMSBinaryProxy" transports="jms">
        <target inSequence="BINARY_CBR_SEQ"/>
    </proxy>

    <sequence name="BINARY_CBR_SEQ">
        <in>
            <log level="full"/>
            <property action="set" name="OUT_ONLY" value="true"/>
            <class name="samples.mediators.BinaryExtractMediator">
                <property name="offset" value="11"/>
                <property name="length" value="4"/>
                <property name="variableName" value="symbol"/>
                <property name="binaryEncoding" value="utf-8"/>
            </class>
            <log level="custom">
                <property name="symbol" expression="get-property('symbol')"/>
            </log>
            <switch source="get-property('symbol')">
                <case regex="GOOG">
                    <send>
                        <endpoint>
                            <address
                                    uri="jms:/dynamicTopics/mdd.GOOG?transport.jms.ConnectionFactoryJNDIName=TopicConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=topic"/>
                        </endpoint>
                    </send>
                </case>
                <case regex="MSFT">
                    <send>
                        <endpoint>
                            <address
                                    uri="jms:/dynamicTopics/mdd.MSFT?transport.jms.ConnectionFactoryJNDIName=TopicConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=topic"/>
                        </endpoint>
                    </send>
                </case>
                <default/>
            </switch>
        </in>
    </sequence>

</definitions>

Objective: Demonstrate on CBR a message with binary payload

Prerequisites:

Make sure the synapse-samples-1.0.jar is in your class path (by default this jar is placed in the lib directory when installing Synapse)

Configure JMS transport using ActiveMQ (refer Sample Configuration Guide)

Start ESB with the sample configuration 381 (i.e. wso2esb-samples -sn 381)

Start the sample Axis2 server and deploy the SimpleStockQuoteService.

In this configuration, a proxy has configured to accept incoming JMS messages. JMS messages contains a binary payload. User configure the offset, length, binary encoding of the text literal that it need to use for CBR. And a variable name to set the decoded value as a property. Configuration simply route the messages based on the text to different endpoints.
A JMS producer and two instances of a consumer used to demonstrate the CBR functionality.


Now run the first consumer using the following command.

ant mddconsumer -Djms_topic=mdd.MSFT

Now run the second consumer using the following command.

ant mddconsumer -Djms_topic=mdd.GOOG

So, now both consumers are ready to listen the topic

Now run the market data producer to genenrate market data for symbol 'MSFT' using the following command.

ant mddproducer -Dsymbol=MSFT

Now run the market data producer to genenrate market data for symbol 'GOOG' using the following command.

ant mddproducer -Dsymbol=GOOG

You will see the below output in the client console(s) based on the symbol.

mddconsumer:
[java]  Market data recived for symbol : topic://mdd.MSFT
[java]  Market data recived for symbol : topic://mdd.MSFT
    

Evaluating XQuery for mediation (XQuery Mediator)

Sample 390: Introduction to the XQuery mediator

  <!-- Introduction to the XQuery mediator -->
<definitions xmlns="http://ws.apache.org/ns/synapse">

    <!-- the SimpleURLRegistry allows access to a URL based registry (e.g. file:/// or http://) -->
    <registry provider="org.wso2.esb.registry.ESBRegistry">
        <!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
        <parameter name="root">file:repository/samples/resources/</parameter>
        <!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
        <parameter name="cachableDuration">15000</parameter>
    </registry>

    <localEntry key="xquery-key-req"
                src="file:repository/samples/resources/xquery/xquery_req.xq"/>
    <proxy name="StockQuoteProxy">
        <target>
            <inSequence>
                <xquery key="xquery-key-req">
                    <variable name="payload" type="ELEMENT"/>
                </xquery>
                <send>
                    <endpoint>
                        <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                    </endpoint>
                </send>
            </inSequence>
            <outSequence>
                <out>
                    <xquery key="xquery/xquery_res.xq">
                        <variable name="payload" type="ELEMENT"/>
                        <variable name="code" type="STRING"
                                  expression="self::node()//m0:return/m0:symbol/child::text()"
                                  xmlns:m0="http://services.samples/xsd"/>
                        <variable name="price" type="DOUBLE"
                                  expression="self::node()//m0:return/m0:last/child::text()"
                                  xmlns:m0="http://services.samples/xsd"/>
                    </xquery>
                    <send/>
                </out>
            </outSequence>
        </target>
        <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
    </proxy>
</definitions> 

This example uses the XQuery mediator to perform transformations. This sample behaves the same as sample number 8 and the only difference is that this sample uses XQuery instead of XSLT for transformation.

Execute the custom quote client as 'ant stockquote -Dmode=customquote ...'

ant stockquote -Daddurl=http://localhost:8280/services/StockQuoteProxy -Dmode=customquote 

Sample 391: How to use data from an external XML document with in XQuery

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <!-- the SimpleURLRegistry allows access to  URL based registry (e.g. file:/// or http://) -->
    <registry provider="org.wso2.carbon.mediation.registry.ESBRegistry">
        <!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
        <parameter name="root">file:repository/samples/resources/</parameter>
        <!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
        <parameter name="cachableDuration">15000</parameter>
    </registry>

    <proxy name="StockQuoteProxy">
        <target>
            <inSequence>
                <send>
                    <endpoint>
                        <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                    </endpoint>
                </send>
            </inSequence>
            <outSequence>
                <out>
                    <xquery key="xquery/xquery_commisson.xq">
                        <variable name="payload" type="ELEMENT"></variable>
                            <variable name="commission" type="ELEMENT" key="misc/commission.xml"></variable>
                    </xquery>
                    <send/>
                </out>
            </outSequence>
        </target>
        <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
    </proxy>
</definitions>

Objective: Demonstrate the use of XQuery mediator to import external XML documents to the XQuery engine

Prerequisites:Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 391 (i.e. wso2esb-samples -sn 391).

In this sample, data from commission.xml document is used inside XQUERY document. The stock quote price from the response and commission from the commission.xml document will be added and given as a new price .

Invoke the client as follows.

ant stockquote -Daddurl=http://localhost:8280/services/StockQuoteProxy

Splitting messages in to parts and process in parallel (Iterate / Clone)

Sample 400: Message splitting and aggregating the responses

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <proxy name="SplitAggregateProxy">
        <target>
            <inSequence>
                <iterate expression="//m0:getQuote/m0:request" preservePayload="true"
                         attachPath="//m0:getQuote"
                         xmlns:m0="http://services.samples">
                    <target>
                        <sequence>
                            <send>
                                <endpoint>
                                    <address
                                        uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                                </endpoint>
                            </send>
                        </sequence>
                    </target>
                </iterate>
            </inSequence>
            <outSequence>
                <aggregate>
                    <onComplete expression="//m0:getQuoteResponse"
                                xmlns:m0="http://services.samples">
                        <send/>
                    </onComplete>
                </aggregate>
            </outSequence>
        </target>
    </proxy>
</definitions>

Objective: Demonstrate the use of Iterate mediator to split the messages in to parts and process them asynchronously and then aggregate the responses coming in to ESB

Prerequisites:Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 400 (i.e. wso2esb-samples -sn 400).

In this sample, the message sent to ESB has embedded with a number of elements of the same type in one message. When ESB received this message it will iterate through those elements and then sent to the specified endpoint. When all the responses appear in to ESB then those messages will be aggregated to form the resultant response and sent back to the client.

Invoke the client as follows.

ant stockquote -Daddurl=http://localhost:8280/services/SplitAggregateProxy -Ditr=4

Caching the responses over the requests (Cache Mediator)

Cache mediator can be used to utilize the network bandwidth, to protect the backend service from being loaded with the same type of requests like browser refresh actions and also to speed up the execution of the web service. This mediator should be used with sence, because it is not applicable for each and every service (for example services with dynamic responses for a particular release)

Sample 420: Simple cache implemented on ESB for the actual service

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <in>
        <cache timeout="20" scope="per-host" collector="false"
               hashGenerator="org.wso2.caching.digest.DOMHASHGenerator">
            <implementation type="memory" maxSize="100"/>
        </cache>
        <send>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
        </send>
    </in>
    <out>
        <cache collector="true"/>
        <send/>
    </out>
</definitions>

Objective: Demonstrate the use of Cache mediator in order to cache the response and use that cached response as the response for an identical xml request

Prerequisites:Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 420 (i.e. wso2esb-samples -sn 420).

In this sample, the message sent to ESB is checked for an existing cached response by calculating the hash value of the request. If there is a cache hit in ESB then this request will not be forwarded to the actual service, rather ESB respond to the client with the cached response. In case of a cache miss that particular message will be forwarded to the actual service and cached that response in the out path for the use of consecutive requests of the same type.

To observe this behaviour, invoke the client as follows.

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

You could notice that if you send more than one requests within 20 seconds only the first request is forwarded to the actual service, and the rest of the requests will be served by the cache inside ESB. You could observe this by looking at the printed line of the axis2 server, as well as by observing a constant rate as the response to the client instead of the random rate, which changes by each and every 20 seconds.

Synchronize web service invocation with Callout mediator

The Callout mediator calls the given service URL with the request message which is given by the source attribute, waits for the response and attaches the received response to the destination which is given by the target attribute. Both the source and the target can be a key or an XPath. In the case of the source, this key refers to either a message context property or to a local entry. For the target, this key refers to a message context property only.

Sample 430: Simple Callout Mediator for synchronizing web service invocation

    <!-- Simple callout  mediator -->
<definitions xmlns="http://ws.apache.org/ns/synapse">
    <callout serviceURL="http://localhost:9000/services/SimpleStockQuoteService"
             action="urn:getQuote">
        <source xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
        <target xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
    </callout>
    <property name="RESPONSE" value="true"/>
    <header name="To" action="remove"/>
    <send/>
    <drop/>
</definitions> 

Objective: Demonstrate the use of the Callout mediator for the synchronized web service invocation

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start Synapse with the sample configuration 430 (i.e. wso2esb-samples -sn 430).

In this sample, Callout mediator does the direct service invocation to the StockQuoteService using the client request, get the response and set it as the first child of the SOAP message body. Then using the send mediator, the message is sent back to the client.

Invoke the client as follows.

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/

Mediating JSON Messages

Supporting JSON messages in ESB

Sample 440: Exposing a SOAP Service Over JSON

<definitions xmlns="http://ws.apache.org/ns/synapse"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://ws.apache.org/ns/synapse http://synapse.apache.org/ns/2010/04/configuration/synapse_config.xsd">

    <proxy name="JSONProxy" transports="http https">
        <target>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
            <inSequence>
                <log level="full"/>
                <xslt key="in_transform"/>
                <property name="messageType" scope="axis2" value="text/xml"/>
            </inSequence>
            <outSequence>
                <log level="full"/>
                <xslt key="out_transform"/>
                <property name="messageType" scope="axis2" value="application/json"/>
                <send/>
            </outSequence>
        </target>
    </proxy>

    <localEntry key="in_transform">
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                        xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
                        xmlns:m0="http://services.samples" version="2.0" exclude-result-prefixes="m0 fn">
            <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
            <xsl:template match="*">
                <xsl:element name="{local-name()}" namespace="http://services.samples">
                    <xsl:copy-of select="attribute::*"/>
                    <xsl:apply-templates/>
                </xsl:element>
            </xsl:template>
        </xsl:stylesheet>
    </localEntry>

    <localEntry key="out_transform">
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
            <xsl:output method="xml" version="1.0" encoding="UTF-8"/>
            <xsl:template match="*">
                <xsl:element name="{local-name()}">
                    <xsl:apply-templates/>
                </xsl:element>
            </xsl:template>
        </xsl:stylesheet>
    </localEntry>

</definitions>

Objective: Demonstrate the ability to switch between JSON and XML/SOAP content interchange formats

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start Synapse with the sample configuration 440 (i.e. wso2esb-samples -sn 440).

Setup Synapse and the sample Axis2 client for JSON (Refer Synapse Samples Setup Guide for details)

Invoke the client as follows.

ant jsonclient -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/services/JSONProxy

JSON client will send a stockquote request to Synapse using the JSON content interchange format. Synapse will trnasform it into a SOAP request and forward to the Axis2 server. The SOAP response from the Axis2 server will be converted into a JSON message and sent back to the JSON client.

You may use a tool like TCPMon to monitor the JSON requests sent over the wire. A sample JSON request and response is shown below:

{"getQuote":{"request":{"symbol":"IBM"}}}
{"getQuoteResponse":{"return":{"change":3.853593376681722,"earnings":12.802850763714854,"high":67.92488310190126,"last":66.14619264746406,"lastTradeTimestamp":"Mon Aug 23 16:48:40 IST 2010","low":-66.04000424423522,"marketCap":-9334516.42324327,"name":"IBM Company","open":-64.61950137150009,"peRatio":-19.78600441437058,"percentageChange":5.411779328273005,"prevClose":71.2075112994578,"symbol":"IBM","volume":16842}}}

Modifying URLs with URL Rewrite Mediator

URL rewrite mediator enables modifying URL values in the message. The input URL could be taken from the 'To' header of the message or from a property available on the message. Once the input URL is selected, a series of user defined rewrite rules will be evaluated on the message. Depending on the outcome of these rule evaluations, the URL will be modified and set on the message.

URL rewrite mediator breaks the URL down to seven segments.

Note that this breakdown is inline with the URI specification (RFC2396). URL rewrite mediator enables rewriting each of the above segments separately and finally combining them to get the final URL value. It also supports rewriting the entire URL string at once.

Sample 450: Introduction to the URL Rewrite Mediator

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main">
        <in>
            <rewrite>
                <rewriterule>
                    <action type="replace" regex="soap" value="services" fragment="path"/>
                </rewriterule>
            </rewrite>
            <send/>
        </in>
        <out>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Demonstrate the basic functions of the URL rewrite mediator

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 450 (i.e. wso2esb-samples -sn 450).

Invoke the client as follows.

ant stockquote -Dtrpurl=http://localhost:8280 -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService

Note that the address URL of the client request contains the context 'soap'. But in the Axis2 server all the services are deployed under a context named 'services' by default. ESB will rewrite the To header of the request by replacing the 'soap' context with 'services. Hence the request will be delivered to the Axis2 server and the Axis2 client will receive a valid response.

Sample 451: Conditional URL Rewriting

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main">
        <in>
            <rewrite>
                <rewriterule>
                    <condition>
                        <and>
                            <equal type="url" source="host" value="localhost"/>
                            <not>
                                <equal type="url" source="protocol" value="https"/>
                            </not>
                        </and>
                    </condition>
                    <action fragment="protocol" value="https"/>
                    <action fragment="port" value="9002"/>
                </rewriterule>
            </rewrite>
            <send/>
        </in>
        <out>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Demonstrate the ability of the URL rewrite mediator to evaluate conditions on messages and perform rewrites based on the results.

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 451 (i.e. wso2esb-samples -sn 451).

Invoke the Axis2 client and send some requests to ESB with different address URL values. If the address URL value contains localhost as the hostname and https as the protocol prefix, ESB will route the message as it is. But if the hostname is localhost and the protocol is not https, Synapse will rewrite the URL by setting https as the protocol. The port number will also be set to the HTTPS port of the Axis2 server.

The condition evaluation feature is provided by the Synapse evaluator framework. Currently one can evaluate expressions on URL values, query parameters, transport headers, properties and SOAP envelope content using this framework. Hence URL rewriting can be done based on any of these aspects.

Sample 452: Conditional URL Rewriting with Multiple Rules

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main">
        <in>
            <property name="http.port" value="9000"/>
            <property name="https.port" value="9002"/>
            <rewrite>
                <rewriterule>
                    <action fragment="host" value="localhost"/>
                    <action fragment="path" type="prepend" value="/services"/>
                </rewriterule>
                <rewriterule>
                    <condition>
                        <equal type="url" source="protocol" value="http"/>
                    </condition>
                    <action fragment="port" xpath="get-property('http.port')"/>
                </rewriterule>
                <rewriterule>
                    <condition>
                        <equal type="url" source="protocol" value="https"/>
                    </condition>
                    <action fragment="port" xpath="get-property('https.port')"/>
                </rewriterule>
            </rewrite>
            <log level="full"/>
            <send/>
        </in>
        <out>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Demonstrate the ability of the URL rewrite mediator to perform rewrites based on multiple rules.

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 452 (i.e. wso2esb-samples -sn 452).

Invoke the Axis2 client as follows.

ant stockquote -Dtrpurl=http://localhost:8280 -Daddurl=http://test.com/SimpleStockQuoteService

The provided address URL does not contain a port number and the context. The URL rewrite mediator will replace the hostname to be 'localhost' and add the context '/services' to the path. Then it will add the appropriate port number to the URL by looking at the protocol prefix. Ultimately the service request will be routed the sample Axis2 server and the client will receive a valid response. Note that the Synapse configuration does not specify any endpoints explicitly. So the messages are sent to the rewritten To header.

Another important aspect shown by this sample is the ability of the URL rewrite mediator to obtain the necessary values by executing XPath expressions. The port numbers are calculated by executing an XPath on the messages.

Publishing Events to Topics Using the Event Mediator

WSO2 ESB can be used as an event broker. It comes with a built-in eventing implementation and a lightweight event broker based on Apache Qpid. You can use the ESB management console to create event topics and clients can subscribe to those topics by sending WS-Eventing subscription requests. The management console also allows creating static subscription.

WSO2 ESB is also equipped with an event mediator which can be used to publish messages to predefined topics. With this mediator it is possible for a sequence or a proxy service to directly publish a received request or a response to a topic as an event.

Sample 460: Introduction to Eventing and Event Mediator

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main">
        <log/>
        <event topic="stockquote"/>
    </sequence>

</definitions>

Objective: Demonstrate the usage of the event mediator to publish messages to event topics

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 460 (i.e. wso2esb-samples -sn 460).

Now sign in to the ESB management console can select 'Topics > Add' option from the 'Manage' menu. Enter the name 'stockquote' for the topic and click 'Add Topic'. This will create an event topic named 'stockquote' and you will be directed to the 'Topic Browser' tree view. The newly created topic will be shown on the tree. Click on this topic and select the 'Subscribe' option to create a static subscription. Enter the value 'http://localhost:9000/services/SimpleStockQuoteService' in the 'Event Sink URL' field and click 'Subscribe'.

Now run the sample client as follows to send a request to the main sequence.

ant stockquote -Dtrpurl=http://localhost:8280 -Dmode=placeorder

The request will be published to the 'stockquote' topic by the event mediator and as a result the subscriber (Axis2 server in this case) will receive a copy of the message. You will see a log entry in the Axis2 server console indicating the receipt of the place order request.

Note that the provided ESB configuration does not explicitly specify the endpoint of the Axis2 server. Also we don't set the actual EPR of the service on the request when sending the message from the client either. Therefore the only reason that Axis2 receives the message is because it is subscribed to the 'stockquote' event topic.

Spring

Sample 470: How to initialize and use a Spring Bean as a Mediator

<definitions xmlns="http://ws.apache.org/ns/synapse"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://ws.apache.org/ns/synapse http://synapse.apache.org/ns/2010/04/configuration/synapse_config.xsd">

    <registry provider="org.apache.synapse.registry.url.SimpleURLRegistry">
        <parameter name="root">file:repository/conf/sample/resources/</parameter>
        <parameter name="cachableDuration">15000</parameter>
    </registry>

    <sequence name="main">
        <!--Setting the Spring Mediator and its Spring Beans xml file location -->
        <!--Note that springtest is the bean id used in springCustomLogger.xml -->
        <spring bean="springtest" key="spring/springCustomLogger.xml"/>
        <send/>
    </sequence>

</definitions>

springCustomLogger.xml file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

   <bean id="springtest" class="samples.mediators.extensions.SpringCustomLogger" singleton="false">
	   <property name="userName"><value>"Synapse User"</value></property>
	   <property name="email"><value>"usr@synapse.org"</value></property>
   </bean>

</beans>

Objective: Demonstrate How to initialize and use a SpringBean as a mediator

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 470 (i.e. wso2esb-samples -sn 470).

In this sample, the Spring Bean, SpringCustomLogger get initialized using springCustomLogger.xml file and then it log the message Id.

Invoke the client as follows.

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/

If you have enabled logging for the samples.mediators package you will see an output similar to the following on the console:

    2010-09-26 20:46:57,946 [-] [HttpServerWorker-1]  INFO SpringCustomLogger Starting Spring Meditor
    2010-09-26 20:46:57,946 [-] [HttpServerWorker-1]  INFO SpringCustomLogger Bean in Initialized with User:["Synapse User"]
    2010-09-26 20:46:57,946 [-] [HttpServerWorker-1]  INFO SpringCustomLogger E-MAIL:["usr@synapse.org"]
    2010-09-26 20:46:57,946 [-] [HttpServerWorker-1]  INFO SpringCustomLogger Massage Id:  urn:uuid:383FA8B27D7CC549D91285514217720
    2010-09-26 20:46:57,946 [-] [HttpServerWorker-1]  INFO SpringCustomLogger Logged....