To switch from HTTP to JMS, edit the
samples/axis2Server/repository/conf/axis2.xml for the sample Axis2 server
and enable JMS (refer notes above), and restart the server. Now you can
see that the simple stock quote service is available in both JMS and HTTP
in the sample Axis2 server. To see this, point your browser to the WSDL of
the service at http://localhost:9000/soap/SimpleStockQuoteService?wsdl.
JMS URL for the service is mentioned as below:
You may also notice that the simple stock quote proxy service exposed in
Synapse is now available only in HTTP as we have specified transport for
that service as HTTP. To observe this, access the WSDL of stock quote
proxy service at http://localhost:8080/soap/StockQuoteProxy?wsdl.
This Synapse configuration creates a proxy service over HTTP and forwards
received messages to the above EPR using JMS, and sends back the response
to the client over HTTP once the simple stock quote service responds with
the stock quote reply over JMS to the Synapse server. To test this, send a
place order request to Synapse using HTTP as follows:
The sample Axis2 server console will print a message indicating that it
has accepted the order as follows:
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="text_proxy">
<header name="Action" value="urn:placeOrder"/>
<script language="js"><![CDATA[
var args = mc.getPayloadXML().toString().split(" ");
mc.setPayloadXML(
<m:placeOrder xmlns:m="http://services.samples/xsd">
<m:order>
<m:price>{args[0]}</m:price>
<m:quantity>{args[1]}</m:quantity>
<m:symbol>{args[2]}</m:symbol>
</m:order>
</m:placeOrder>);
]]></script>
<property action="set" name="OUT_ONLY" value="true"/>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</sequence>
<sequence name="mtom_proxy">
<property action="set" name="OUT_ONLY" value="true"/>
<header name="Action" value="urn:oneWayUploadUsingMTOM"/>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/MTOMSwASampleService" optimize="mtom"/>
</endpoint>
</send>
</sequence>
<sequence name="pox_proxy">
<property action="set" name="OUT_ONLY" value="true"/>
<header name="Action" value="urn:placeOrder"/>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="soap11"/>
</endpoint>
</send>
</sequence>
<sequence name="out">
<send/>
</sequence>
<proxy name="JMSFileUploadProxy" transports="jms">
<target inSequence="mtom_proxy" outSequence="out"/>
<parameter name="transport.jms.Wrapper">{http://services.samples/xsd}element</parameter>
</proxy>
<proxy name="JMSTextProxy" transports="jms">
<target inSequence="text_proxy" outSequence="out"/>
<parameter name="transport.jms.Wrapper">{http://services.samples/xsd}text</parameter>
</proxy>
<proxy name="JMSPoxProxy" transports="jms">
<target inSequence="pox_proxy" outSequence="out"/>
</proxy>
</definitions>
Objective: Pure POX/Text and Binary JMS Proxy services -
including MTOM
Prerequisites:
Configure JMS for Synapse
(Refer notes)
Start the Synapse configuration numbered 252: i.e.
synapse -sample 252
Start the Axis2 server and deploy the
SimpleStockQuoteService and the MTOMSwASampleService if not already done
This configuration creates three JMS proxy services named
JMSFileUploadProxy, JMSTextProxy and JMSPoxProxy exposed over JMS queues
with the same names as the services. The first part of this example
demonstrates the pure text message support with JMS, where a user sends a
space separated text JMS message of the form "<price> <qty>
<symbol>". Synapse converts this message into a SOAP message and
sends this to the SimpleStockQuoteServices' placeOrder operation. Synapse
uses the script mediator to transform the text message into a XML payload
using the Javascript support available to tokenize the string. The proxy
service property named "transport.jms.Wrapper" defines a custom wrapper
element QName, to be used when wrapping text/binary content into a SOAP
envelope.
Execute JMS client as follows. This will post a pure text JMS message with
the content defined (e.g. "12.33 1000 ACP") to the specified JMS
destination - dynamicQueues/JMSTextProxy
ant jmsclient -Djms_type=text -Djms_payload="12.33 1000 ACP" -Djms_dest=dynamicQueues/JMSTextProxy
Following the debug logs, you could notice that Synapse received the JMS
text message and transformed it into a SOAP payload as follows. Notice
that the wrapper element "{http://services.samples/xsd}text" has been used
to hold the text message content.
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body><axis2ns1:text xmlns:axis2ns1="http://services.samples/xsd">12.33 1000 ACP</axis2ns1:text></soapenv:Body>
</soapenv:Envelope>
Now, you could see how the script mediator created a stock quote request
by tokenizing the text as follows, and sent the message to the placeOrder
operation of the SimpleStockQuoteService.
[JMSWorker-1] DEBUG AddressEndpoint - Sending message to endpoint :: name = AnonymousEndpoints resolved address = http://localhost:9000/soap/SimpleStockQuoteService
[JMSWorker-1] DEBUG AddressEndpoint - SOAPAction: urn:placeOrder
[JMSWorker-1] DEBUG AddressEndpoint - WSA-Action: urn:placeOrder
[JMSWorker-1] DEBUG AddressEndpoint - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body>
<m:placeOrder xmlns:m="http://services.samples/xsd"><m:order><m:price>12.33</m:price><m:quantity>1000</m:quantity><m:symbol>ACP</m:symbol></m:order>
</m:placeOrder></soapenv:Body></soapenv:Envelope>
The sample Axis2 server would now accept the one way message and issue the
following message:
Wed Apr 25 19:50:56 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 1000 stocks of ACP at $ 12.33
The next section of this example demonstrates how a pure binary JMS
message could be received and processed through Synapse. The configuration
creates a proxy service named 'JMSFileUploadProxy' that accepts binary
messages and wraps them into a custom element
'{http://services.samples/xsd}element'. The received message is then
forwarded to the MTOMSwASampleService using the SOAP action
'urn:oneWayUploadUsingMTOM' and optimizing binary conent using MTOM. To
execute this sample, use the JMS client to publish a pure binary JMS
message containing the file
'./../../repository/conf/sample/resources/mtom/asf-logo.gif' to the JMS
destination 'dynamicQueues/JMSFileUploadProxy' as follows:
ant jmsclient -Djms_type=binary -Djms_dest=dynamicQueues/JMSFileUploadProxy -Djms_payload=./../../repository/conf/sample/resources/mtom/asf-logo.gif
Examining the Synapse debug logs reveals that the binary content was
received over JMS and wrapped with the specified element into a SOAP
infoset as follows:
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Proxy Service JMSFileUploadProxy received a new message...
...
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body><axis2ns1:element xmlns:axis2ns1="http://services.samples/xsd">R0lGODlhgw...AAOw==</axis2ns1:element></soapenv:Body>
</soapenv:Envelope>
Thereafter the message was sent as a MTOM optimized message as specified
by the 'format=mtom' attribute of the endpoint, to the
MTOMSwASampleService using the SOAP action 'urn:oneWayUploadUsingMTOM'.
Once received by the sample service, it is saved into a temporary file and
could be verified for correctness.
Wrote to file : /tmp/mtom-60319.gif
The final section of this example shows how a POX JMS message received by
Synapse is sent to the SimpleStockQuoteService as a SOAP message. Use the
JMS client as follows to create a POX (Plain Old XML) message with a stock
quote request payload (without a SOAP envelope), and send it to the JMS
destination 'dynamicQueues/JMSPoxProxy' as follows:
ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/JMSPoxProxy -Djms_payload=MSFT
You can see that Synapse received the POX message and displays it as
follows in the debug logs, and then converts it into a SOAP payload and
sends to the SimpleStockQuoteService after setting the SOAP action as
'urn:placeOrder'.
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Proxy Service JMSPoxProxy received a new message...
...
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><m:placeOrder xmlns:m="http://services.samples/xsd">
<m:order>
<m:price>172.39703010684752</m:price>
<m:quantity>19211</m:quantity>
<m:symbol>MSFT</m:symbol>
</m:order>
</m:placeOrder></soapenv:Body></soapenv:Envelope>
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Using the sequence named pox_proxy for message mediation
...
[JMSWorker-1] DEBUG HeaderMediator - Setting header : Action to : urn:placeOrder
...
[JMSWorker-1] DEBUG AddressEndpoint - Sending message to endpoint :: name = AnonymousEndpoints resolved address = http://localhost:9000/soap/SimpleStockQuoteService
[JMSWorker-1] DEBUG AddressEndpoint - SOAPAction: urn:placeOrder
[JMSWorker-1] DEBUG AddressEndpoint - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><m:placeOrder xmlns:m="http://services.samples/xsd">
<m:order>
<m:price>172.39703010684752</m:price>
<m:quantity>19211</m:quantity>
<m:symbol>MSFT</m:symbol>
</m:order>
</m:placeOrder></soapenv:Body></soapenv:Envelope>
[JMSWorker-1] DEBUG Axis2FlexibleMEPClient - sending [add = false] [sec = false] [rm = false] [ mtom = false] [ swa = false] [ force soap=true; pox=false] [ to null]
The sample Axis2 server displays a successful message on the receipt of
the message as:
Wed Apr 25 20:24:50 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 19211 stocks of MSFT at $ 172.39703010684752
<definitions xmlns="http://ws.apache.org/ns/synapse">
<proxy name="JMStoHTTPStockQuoteProxy" transports="jms">
<target>
<inSequence>
<property action="set" name="OUT_ONLY" value="true"/>
</inSequence>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
<proxy name="OneWayProxy" transports="http">
<target>
<inSequence>
<log level="full"/>
<property name="RESPONSE" value="true"/>
<header name="To" value="http://www.w3.org/2005/08/addressing/anonymous"/>
<property name="SC_ACCEPTED" value="true" scope="axis2"/>
<property action="set" name="OUT_ONLY" value="true"/>
<send/>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
Objective: Demonstrate one way message bridging from JMS to
http and replying with a http 202 Accepted response
Prerequisites:
Start the Axis2 server
and deploy the SimpleStockQuoteService if not already done
Start the Synapse configuration numbered 253: i.e. synapse -sample 253
This example invokes the one-way 'placeOrder' operation on the
SimpleStockQuoteService using the Axis2 ServiceClient.fireAndForget() API
at the client. To test this, use 'ant -Dmode=placeorder...' and you will
notice the one way JMS message flowing through Synapse into the sample
Axis2 server instance over http, and Axis2 acknowledging it with a http
202 Accepted response.
ant stockquote -Dmode=placeorder -Dtrpurl="jms:/JMStoHTTPStockQuoteProxy?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616"
SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733
The second example shows how Synapse could be made to respond with a http
202 Accepted response to a request received. The proxy service simply logs
the message received and acknowledges it. On the Synapse console you could
see the logged message, and if TCPMon was used at the client, you would
see the 202 Accepted response sent back to the client from Synapse
ant stockquote -Dmode=placeorder -Dtrpurl=http://localhost:8080/soap/OneWayProxy
HTTP/1.1 202 Accepted
Content-Type: text/xml; charset=UTF-8
Host: 127.0.0.1
SOAPAction: "urn:placeOrder"
Date: Sun, 06 May 2007 17:20:19 GMT
Server: Synapse-HttpComponents-NIO
Transfer-Encoding: chunked
0
<definitions xmlns="http://ws.apache.org/ns/synapse">
<proxy name="StockQuoteProxy" transports="vfs">
<parameter name="transport.vfs.FileURI">file:///home/user/test/in</parameter> <!--CHANGE-->
<parameter name="transport.vfs.ContentType">text/xml</parameter>
<parameter name="transport.vfs.FileNamePattern">.*\.xml</parameter>
<parameter name="transport.PollInterval">15</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file:///home/user/test/original</parameter> <!--CHANGE-->
<parameter name="transport.vfs.MoveAfterFailure">file:///home/user/test/original</parameter> <!--CHANGE-->
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<target>
<endpoint>
<address format="soap12" uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
<outSequence>
<property name="transport.vfs.ReplyFileName"
expression="fn:concat(fn:substring-after(get-property('MessageID'), 'urn:uuid:'), '.xml')" scope="transport"/>
<send>
<endpoint>
<address uri="vfs:file:///home/user/test/out"/> <!--CHANGE-->
</endpoint>
</send>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
Objective: Using the file system as transport medium using VFS
transport listener and sender
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
Create three new directories in a test directory. e.g. in, out, original
in /home/user/test. Open
SYNAPSE_HOME/repository/conf/sample/synapse_sample_115.xml and edit the
following values. Change transport.vfs.FileURI,
transport.vfs.MoveAfterProcess, transport.vfs.MoveAfterFailure parameter
values to the above in, original, original directories respectively.
Change outSequence endpoint address uri to out directory with the prefeix
vfs:. Values you have to change are marked with <!--CHANGE-->.
Start the Synapse configuration numbered 254: i.e. synapse -sample 254
Copy SYNAPSE_HOME/repository/conf/sample/resources/vfs/test.xml to the
directory given in transport.vfs.FileURI above.
test.xml file content is as follows
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Body>
<m0:getQuote xmlns:m0="http://services.samples/xsd">
<m0:request>
<m0:symbol>IBM</m0:symbol>
</m0:request>
</m0:getQuote>
</soapenv:Body>
</soapenv:Envelope>
VFS transport listener will pick the file from in
directory and send it to the Axis2 service. The request XML file will be
moved to original directory. The response from the Axis2
server will be saved to out directory.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<proxy name="StockQuoteProxy" transports="vfs">
<parameter name="transport.vfs.FileURI">vfs:ftp://guest:guest@localhost/test?vfs.passive=true</parameter> <!--CHANGE-->
<parameter name="transport.vfs.ContentType">text/xml</parameter>
<parameter name="transport.vfs.FileNamePattern">.*\.xml</parameter>
<parameter name="transport.PollInterval">15</parameter>
<target>
<inSequence>
<header name="Action" value="urn:getQuote"/>
</inSequence>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
<outSequence>
<property action="set" name="OUT_ONLY" value="true"/>
<send>
<endpoint>
<address uri="mailto:user@host"/> <!--CHANGE-->
</endpoint>
</send>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
Objective: Switching from ftp transport listener to mail
transport sender
Prerequisites:
You will need access to
an FTP server and an SMTP server to try this sample.
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
Enable mail transport sender in the Synapse axis2.xml. See Setting up mail transport
sender
Create a new test directory in the FTP server. Open
SYNAPSE_HOME/repository/conf/sample/synapse_sample_116.xml and edit the
following values. Change transport.vfs.FileURI parameter value point to
the test directory at the FTP server. Change outSequence endpoint address
uri email address to a working email address. Values you have to change
are marked with <!--CHANGE-->.
Start the Synapse configuration numbered 255: i.e. synapse -sample 255
Copy SYNAPSE_HOME/repository/conf/sample/resources/vfs/test.xml to the ftp
directory given in transport.vfs.FileURI above.
VFS transport listener will pick the file from the directory in the ftp
server and send it to the Axis2 service. The file in the ftp directory
will be deleted. The response will be sent to the given email address.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<task class="org.apache.synapse.startup.tasks.MessageInjector" name="CheckPrice">
<property name="to" value="http://localhost:9000/soap/SimpleStockQuoteService"/>
<property name="soapAction" value="urn:getQuote"/>
<property name="message">
<m0:getQuote xmlns:m0="http://services.samples/xsd">
<m0:request>
<m0:symbol>IBM</m0:symbol>
</m0:request>
</m0:getQuote>
</property>
<trigger interval="5000"/>
</task>
<in>
<send/>
</in>
<out>
<log level="custom">
<property name="Stock Quote on" expression="//ns:return/ns:lastTradeTimestamp/child::text()" xmlns:ns="http://services.samples/xsd"/>
<property name="For the organization" expression="//ns:return/ns:name/child::text()" xmlns:ns="http://services.samples/xsd"/>
<property name="Last Value" expression="//ns:return/ns:last/child::text()" xmlns:ns="http://services.samples/xsd"/>
</log>
</out>
</definitions>
Objective: Introduce the concept of tasks and how simple
trigger works
Prerequisites:
You will need access to
build the SimpleStockQuoteService as mentioned in the above and start the
sample axis2 server before staring synapse.
When ever synapse gets started and initialized, this task will run
periodically in 5 second intervals. You could limit the number of times
that you want to run this task by adding a count attribute with an integer
as the value, if the count is not present as in this sample this task will
run forever.
One can write his own task class implementing the
org.apache.synapse.startup.Task interface and implementing the execute
method to do the task. For this particular sample we have used the
MessageInjector which just injects a message specified in to the synapse
environment.
The Synapse Script Mediator is a Synapse extension, and thus all
prerequisites are not bundled by default with the Synapse distribution.
Before you use some script mediators you may need to manually add the
required jar files to the Synapse 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/conf/sample/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/soap/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://www.apache-synapse.org/test">
<m:Code>{symbol}</m:Code>
<m:Price>{price}</m:Price>
</m:CheckPriceResponse>);
}
]]></x>
Objective: Introduction to script mediators
Prerequisites:
Start the Synapse configuration numbered 350: i.e. synapse -sample 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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote
Synapse 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/soap/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://www.apache-synapse.org/test">
<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. synapse -sample 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 Synapse. Use the stock quote
client to send a custom quote as in example # 500 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. bin/synapse -sample 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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
...
stockquote:
[java] Standard :: Stock price = $99.9
<definitions xmlns="http://ws.apache.org/ns/synapse">
<localEntry key="stockquoteScript" src="file:repository/conf/sample/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/soap/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://www.apache-synapse.org/test"><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 Synapse as
described at Configuring
JRuby.
Start the Synapse configuration numbered 353: i.e. bin/synapse -sample 353
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This sample is functionally equivalent to sample # 500 (#501 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 #500
and check the received stock quote response.
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/synapsedb;create=false</url>
<user>synapse</user>
<password>synapse</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/soap/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/soap/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/soap/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. synapse -sample 360
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This sample demonstrates simple database read operations through Synapse.
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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM
Synapse 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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN
Synapse 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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT
INFO LogMediator text = ** Looking up from the Database **INFO LogMediator text = Company ID – c2
For any other symbols, Synapse 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/soap/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/synapsedb;create=false</url>
<user>synapse</user>
<password>synapse</password>
</pool>
</connection>
<statement>
<sql>update company set price=? where name =?</sql>
<parameter expression="//m0:return/m0:last/child::text()"
xmlns:m0="http://services.samples/xsd" type="DOUBLE"/>
<parameter expression="//m0:return/m0:symbol/child::text()"
xmlns:m0="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. synapse -sample 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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -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.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main">
<in>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/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/synapsedb;create=false</url>
<user>synapse</user>
<password>synapse</password>
</pool>
</connection>
<statement>
<sql>update company set price=? where name =?</sql>
<parameter expression="//m0:return/m0:last/child::text()"
xmlns:m0="http://services.samples/xsd" type="DOUBLE"/>
<parameter expression="//m0:return/m0:symbol/child::text()"
xmlns:m0="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/synapsedb;create=false</url>
<user>synapse</user>
<password>synapse</password>
</pool>
</connection>
<statement>
<sql>select * from company where name =?</sql>
<parameter expression="//m0:return/m0:symbol/child::text()"
xmlns:m0="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. synapse -sample 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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM
Synapse console shows,
INFO LogMediator text = ** Reporting to the Database **...INFO LogMediator text = ** Looking up from the Database **...INFO LogMediator text = Stock price - 153.47886496064808
<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/soap/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 Synapse with the sample configuration 370 (i.e. synapse -sample
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. Policy tag specifies the throttling policy to
be applied for messages. In this sample policy contains only component
called "MaximumConcurrentAccess" .This indicates the maximum number of
concurrent request that may have passed through the synapse on a single
unit of time. To test concurrency throttling ,it is required to send
concurrent request to synapse. For synapse with above configuration ,if
client send 20 request concurrently ,then approximately half of those will
success. The client command is as follows.
ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/
<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> <wsp:All>
<throttle:ID throttle:type="IP">Other</throttle:ID>
<wsp:ExactlyOne>
<wsp:All>
<throttle:MaximumCount>4</throttle:MaximumCount>
<throttle:UnitTime>800000</throttle:UnitTime>
<throttle:ProhibitTimePeriod wsp:Optional="true">10000</throttle:ProhibitTimePeriod>
</wsp:All>
<throttle:IsAllow>true</throttle:IsAllow>
</wsp:ExactlyOne>
</wsp:All>
<wsp:All>
<throttle:ID throttle:type="IP">192.168.8.200-192.168.8.222</throttle:ID>
<wsp:ExactlyOne>
<wsp:All>
<throttle:MaximumCount>8</throttle:MaximumCount>
<throttle:UnitTime>800000</throttle:UnitTime>
<throttle:ProhibitTimePeriod wsp:Optional="true">10</throttle:ProhibitTimePeriod>
</wsp:All>
<throttle:IsAllow>true</throttle:IsAllow>
</wsp:ExactlyOne>
</wsp:All>
<wsp:All>
<throttle:ID throttle:type="IP">192.168.8.201</throttle:ID>
<wsp:ExactlyOne>
<wsp:All>
<throttle:MaximumCount>200</throttle:MaximumCount>
<throttle:UnitTime>600000</throttle:UnitTime>
<throttle:ProhibitTimePeriod wsp:Optional="true"></throttle:ProhibitTimePeriod>
</wsp:All>
<throttle:IsAllow>true</throttle:IsAllow>
</wsp:ExactlyOne>
</wsp:All>
<wsp:All>
<throttle:ID throttle:type="IP">192.168.8.198</throttle:ID>
<wsp:ExactlyOne>
<wsp:All>
<throttle:MaximumCount>50</throttle:MaximumCount>
<throttle:UnitTime>500000</throttle:UnitTime>
<throttle:ProhibitTimePeriod wsp:Optional="true"></throttle:ProhibitTimePeriod>
</wsp:All>
<throttle:IsAllow>true</throttle:IsAllow>
</wsp:ExactlyOne>
</wsp:All>
</throttle:ThrottleAssertion>
</wsp:Policy>
</policy>
<onAccept>
<log level="custom">
<property name="text" value="**Access Accept**"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/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 Synapse with the sample configuration 371 (i.e. synapse -sample
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:8080/
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 Synapse 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.apache.synapse.registry.url.SimpleURLRegistry">
<!-- 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/soap/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/conf/sample/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 Synapse with the sample configuration 372 (i.e. synapse -sample
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:8080/soap/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 all the Synapse API in
there. This is a useful extension mechanism within Synapse 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/soap/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 Synapse).
Start Synapse with the sample configuration 380 (i.e. synapse -sample 380)
Start the sample Axis2 server and deploy the SimpleStockQuoteService.
In this configuration, Synapse 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:8080
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
<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.apache.synapse.registry.url.SimpleURLRegistry">
<!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
<parameter name="root">file:repository/conf/sample/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/conf/sample/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/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<out>
<xquery key="xquery/xquery_res.xq">
<variable name="payload" type="ELEMENT"/>
</xquery>
<send/>
</out>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/></proxy></definitions>
Objective: Introduction transformation using XQuery mediator
Prerequisites:Start the Synapse configuration numbered
390: i.e. synapse -sample 390
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done.
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:8080/soap/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.apache.synapse.registry.url.SimpleURLRegistry">
<!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
<parameter name="root">file:repository/conf/sample/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/soap/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/conf/sample/resources/proxy/sample_proxy_1.wsdl"/></proxy></definitions> ns>
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 Synapse with the sample configuration 391 (i.e. synapse -sample
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:8080/soap/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/xsd">
<target>
<sequence>
<send>
<endpoint>
<address
uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence>
<aggregate>
<onComplete expression="//m0:getQuoteResponse"
xmlns:m0="http://services.samples/xsd">
<send/>
</onComplete>
<invalidate>
<log level="full"/>
<drop/>
</invalidate>
</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 synapse
Prerequisites:Deploy the SimpleStockQuoteService
in sample Axis2 server and start it on port 9000.
Start Synapse with the sample configuration 400 (i.e. synapse -sample
400).
In this sample, the message sent to synapse has embedded with a number of
elements of the same type in one message. When synapse received this
message it will iterate through those elements and then sent to the
specified endpoint. When all the responses appear in to synapse 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:8080/soap/SplitAggregateProxy -Ditr=4
Cached 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="20000" scope="per-host"
hashGenerator="org.wso2.caching.digest.DOMHASHGenerator">
<implementation type="memory" maxSize="100"/>
</cache>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</in>
<out>
<cache/>
<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 Synapse with the sample configuration 420 (i.e. synapse -sample
420).
In this sample, the message sent to synapse is checked for an existing
cached response by calculating the hash value of the request. If there is
a cache hit in synapse then this request will not be forwarded to the
actual service, rather synapse 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:8080/
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 Synapse. 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.