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.
<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/xsd"> <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.
<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.
<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
<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.
<!-- 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
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.
<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 **
<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
<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
<!-- 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
<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/
<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**
<!-- 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="conf/sample/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.
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.
<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
<!-- 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
<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
<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
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)
<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.
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.
<!-- 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/