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&transport.jms.DestinationType=queue"
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.
<!-- Using the mail transport -->
<definitions xmlns="http://ws.apache.org/ns/synapse">
<proxy name="StockQuoteProxy" transports="mailto">
<parameter name="transport.mail.Address">synapse.demo.1@gmail.com</parameter>
<parameter name="transport.mail.Protocol">pop3</parameter>
<parameter name="transport.PollInterval">5</parameter>
<parameter name="mail.pop3.host">pop.gmail.com</parameter>
<parameter name="mail.pop3.port">995</parameter>
<parameter name="mail.pop3.user">synapse.demo.1</parameter>
<parameter name="mail.pop3.password">mailpassword</parameter>
<parameter name="mail.pop3.socketFactory.class">javax.net.ssl.SSLSocketFactory</parameter>
<parameter name="mail.pop3.socketFactory.fallback">false</parameter>
<parameter name="mail.pop3.socketFactory.port">995</parameter>
<target>
<inSequence>
<property name="senderAddress" expression="get-property('transport', 'From')"/>
<log level="full">
<property name="Sender Address" expression="get-property('senderAddress')"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<property name="Subject" value="Custom Subject for Response" scope="transport"/>
<header name="To" expression="fn:concat('mailto:', get-property('senderAddress'))"/>
<log level="full">
<property name="message" value="Response message"/>
<property name="Sender Address" expression="get-property('senderAddress')"/>
</log>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
Objective: Using the mail transport with Proxy
services
Prerequisites:
You will need access to an email account
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
Start the Synapse configuration numbered 256: i.e. synapse -sample 256
Send a plain/text email with the following body and any custom Subject
from your mail account.
<m0:getQuote xmlns:m0="http://services.samples/xsd"><m0:request><m0:symbol>IBM</m0:symbol></m0:request></m0:getQuote>
After a few seconds (e.g. 30s), you should receive a POX response in your email
account with the stock quote reply.
<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.
<!-- 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/soap/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-line Ruby
Script)
Prerequisites:
This sample uses Ruby so first setup support for this in Synapse as
described at Configuring
JRuby.
Start the Synapse configuration numbered 354: i.e. bin/synapse -sample
354
Start the Axis2 server and deploy the SimpleStockQuoteService if not already
done
This sample is functionally equivalent to the sample 353.
Run the client with
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -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/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
<!-- 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.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"/>
<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/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" collector="false"
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 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 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.
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/soap/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. synapse -sample
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/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/