blob: b26494eab7321f7272436be3ca2dd711e3ad32b4 [file] [log] [blame]
<?xml version="1.0"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content=""/>
<title>
Synapse Samples
</title>
<style type="text/css" xml:space="preserve">
.command {
border: 1px dashed #3c78b5;
text-align: left;
background-color: #f0f0f0;
padding: 3px;
font-size: 11px;
font-family: Courier;
margin: 10px;
line-height: 13px;
}
.consoleOutput {
border: 1px dashed #3c78b5;
font-size: 11px;
font-family: Courier;
margin: 10px;
line-height: 13px;
background-color: #f0f0f0;
border-bottom: 1px dashed #3c78b5;
padding: 3px;
border-style: solid;
}
.info {
border-style: solid;
border-width: 1px;
border-color: #090;
background-color: #dfd;
text-align:left;
margin-top: 5px;
margin-bottom: 5px;
}
li {
font-family: Verdana, arial, sans-serif;
font-size: 11px;
line-height: 16px;
color: #000000;
font-weight: normal;
}
p {
font-family: Verdana, arial, sans-serif;
font-size: 11px;
line-height: 16px;
color: #000000;
font-weight: normal;
}
pre {
padding: 0px;
margin-top: 5px;
margin-left: 15px;
margin-bottom: 5px;
margin-right: 5px;
text-align: left;
background-color: #f0f0f0;
padding: 3px;
border: 1px dashed #3c78b5;
font-size: 11px;
font-family: Courier;
margin: 10px;
line-height: 13px;
}
h1 {
font-size: 24px;
line-height: normal;
font-weight: bold;
background-color: #f0f0f0;
color: #003366;
border-bottom: 1px solid #3c78b5;
padding: 2px;
margin: 36px 0px 4px 0px;
}
h2 {
font-size: 18px;
line-height: normal;
font-weight: bold;
background-color: #f0f0f0;
border-bottom: 1px solid #3c78b5;
padding: 2px;
margin: 27px 0px 4px 0px;
}
h3 {
font-size: 14px;
line-height: normal;
font-weight: bold;
background-color: #f0f0f0;
padding: 2px;
margin: 21px 0px 4px 0px;
}
h4 {
font-size: 12px;
line-height: normal;
font-weight: bold;
background-color: #f0f0f0;
padding: 2px;
margin: 18px 0px 4px 0px;
}</style>
</head>
<body>
<h1>
Running the Synapse Samples
</h1>
<h2>
<a name="TOC" id="TOC">Contents</a>
</h2>
<div class="section-content">
<ul>
<li>
<a href="samples_setup.html#Overview">Overview</a>
</li>
<li>
<a href="#MediationSamples">Message mediation samples</a>
<ul>
<li>
<a href="#Sample0">Sample 0: Introduction to Synapse</a>
</li>
<li>
<a href="#Sample1">Sample 1: Content based routing (CBR)</a>
</li>
<li>
<a href="#Sample2">Sample 2: CBR with the Switch-case mediator,
using message properties</a>
</li>
<li>
<a href="#Sample3">Sample 3: Local Registry entry definitions,
reusable endpoints and sequences</a>
</li>
<li>
<a href="#Sample4">Sample 4: Introduction to error handling</a>
</li>
<li>
<a href="#Sample5">Sample 5: Creating SOAP fault messages and
changing the direction of a message</a>
</li>
<li>
<a href="#Sample6">Sample 6: Manipulating SOAP headers, and
filtering incoming and outgoing messages</a>
</li>
<li>
<a href="#Sample7">Sample 7: Introduction to local Registry
entries and using Schema validation</a>
</li>
<li>
<a href="#Sample8">Sample 8: Introduction to static and dynamic
registry resources, and using XSLT transformations</a>
</li>
<li>
<a href="#Sample9">Sample 9: Introduction to dynamic sequences
with the Registry</a>
</li>
<li>
<a href="#Sample10">Sample 10: Introduction to dynamic
endpoints with the Registry</a>
</li>
<li>
<a href="#Sample11">Sample 11: A full registry based
configuration, and sharing a configuration between multiple
instances</a>
</li>
</ul>
</li>
<li>
<a href="#Endpoints">Endpoints</a>
<ul>
<li>
<a href="#Sample50">Sample 50: Using WS-Security for outgoing
messages</a>
</li>
<li>
<a href="#Sample51">Sample 51: MTOM and SwA optimizations and
request/response correlation</a>
</li>
<li>
<a href="#Sample52">Sample 52: POX to SOAP conversion</a>
</li>
<li>
<a href="#Sample53">Sample 53: Reliable message exchange
between Synapse and the back-end server using WS-ReliableMessaging</a>
</li>
<li>
<a href="#Sample54">Sample 54: Load balancing</a>
</li>
<li>
<a href="#Sample55">Sample 55: Failover</a>
</li>
<li>
<a href="#Sample56">Sample 56: Load balancing with session
affinity</a>
</li>
<li>
<a href="#Sample57">Sample 57: Load balancing with session
affinity among failover groups</a>
</li>
<li>
<a href="#Sample60">Sample 60: WSDL endpoint</a>
</li>
</ul>
</li>
<li>
<a href="#ProxyServices">Synapse Proxy service samples</a>
<ul>
<li>
<a href="#Sample100">Sample 100: Introduction to proxy services</a>
</li>
<li>
<a href="#Sample101">Sample 101: Custom sequences and endpoints
with proxy services</a>
</li>
<li>
<a href="#Sample102">Sample 102: Switching transports and
message format from SOAP to REST/POX</a>
</li>
<li>
<a href="#Sample103">Sample 103: Using WS-Security with policy
attachments for proxy services</a>
</li>
<li>
<a href="#Sample104">Sample 104: Reliable message exchange
between the client and proxy services using WS-ReliableMessaging</a>
</li>
</ul>
</li>
<li>
<a href="#Transport">Transport samples</a>
<ul>
<li>
<a href="#Sample110">Sample 110: Introduction to switching
transports - JMS to http/s</a>
</li>
<li>
<a href="#Sample111">Sample 111: Demonstrate switching from
http/s to JMS</a>
</li>
<li>
<a href="#Sample112">Sample 112: Demonstrate one way messaging
/ fireAndForget()</a>
</li>
<li>
<a href="#Sample113">Sample 113: Pure text/binary and POX
message support with JMS</a>
</li>
<li>
<a href="#Sample114">Sample 114: One way bridging from JMS to
http and replying with a 202 Accepted response</a>
</li>
</ul>
</li>
<li>
<a href="#ExtensionMediators">Extension Mediators</a>
<ul>
<li>
<a href="Synapse_Samples_Setup.html#ScriptSetup">Setting up
Script Mediators</a>
</li>
<li>
<a href="#Sample500">Sample 500: Introduction to script
mediators</a>
</li>
<li>
<a href="#Sample501">Sample 501: In-line script mediation</a>
</li>
<li>
<a href="#Sample502">Sample 502: Accessing Synapse message
context API methods</a>
</li>
<li>
<a href="#Sample503">Sample 503: Using Ruby scripts for
mediation</a>
</li>
<li>
<a href="#Sample510">Sample 510: Class mediator - Writting your
own mediation in Java</a>
</li>
</ul>
</li>
<li>
<a href="#AdvancedMediations">Advanced Mediations</a>
<ul>
<li>
<a href="#Sample600">Sample 600: Throttle mediator -
Restricting requests based on policies</a>
</li>
</ul>
</li>
</ul>
</div>
<h1>
<a name="MediationSamples" id="MediationSamples">Message Mediation
Samples</a>
</h1>
<h2>
<a name="Sample0" id="Sample0">Sample 0:</a>
</h2>
<pre xml:space="preserve">&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;!-- log all attributes of messages passing through --&gt;
&lt;log level="full"/&gt;
&lt;!-- Send the messageto implicit destination --&gt;
&lt;send/&gt;
&lt;/definitions&gt;
</pre>
<p>
<strong>Objective: Introduction to Synapse. Shows how a message could
be made to pass through Synapse </strong><strong>and logged
before it is delivered to its ultimate receiver.</strong>
</p>
<p>
The Stock quote client can operate in the following modes for this
example.
</p>
<ol>
<li>
Smart Client mode
</li>
<li>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ </pre>
</li>
<li>
Using Synapse as a HTTP Proxy
</li>
<li>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dprxurl=http://localhost:8080/</pre>
</li>
<li>
Gateway mode / Dumb Client
</li>
<li>
<p>
See sample # 1
</p>
</li>
</ol>
<p>
<strong>Pre-Requisites:<br/> </strong>Start the Synapse
configuration numbered 0: e.g. synapse -sample 0<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already deployed
</p>
<p>
<strong>Execute the Smart Client </strong>
</p>
<p>
By following through the execution of Synapse through the DEBUG level log
output to the system output stream (i.e. console), you will notice that
the client request arrived at Synapse with a WS-Addressing 'To' EPR of
http://localhost:9000/soap/SimpleStockQuoteService. The Synapse engine now
logs the message at the "full" log level (i.e. all message headers and the
body) and sends the message to its implicit 'To' address - which is
http://localhost:9000/soap/SimpleStockQuoteService. Then you will see on
the Axis2 server console, a message confirming that the message got routed
to the sample server and the sample service that was invoked generated a
stock quote for the requested symbol.
</p>
<pre xml:space="preserve">Sat Nov 18 21:01:23 IST 2006 SimpleStockQuoteService :: Generating quote for : IBM</pre>
<p>
The response message generated by the service is again received by
Synapse, and flows through the same mediation rules, which logs the
response message and then sends it back - this time to the client. On the
client console you should see an output similar to the following based on
the message received by the client.
</p>
<pre xml:space="preserve">Standard :: Stock price = $95.26454380258552</pre>
<p>
<strong>Execute the Proxy client </strong>
</p>
<p>
You will see the exact same behaviour as per the previous example when you
run this scenario. However this time the difference is at the client, as
it sends the message to the WS-Addressing 'To' address
http://localhost:9000/soap/SimpleStockQuoteService, but the transport
specifies Synapse as the http proxy.
</p>
<h2>
<a name="Sample1" id="Sample1">Sample 1:</a>
</h2>
<pre xml:space="preserve">&lt;!-- simple content based routing of messages --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;!-- filtering of messages with XPath and regex matches --&gt;
&lt;filter source="get-property('To')" regex=".*/StockQuote.*"&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;drop/&gt;
&lt;/filter&gt;
&lt;send/&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: Introduction to simple content based routing. Shows
how a message could be made to pass through Synapse using the Dumb Client
mode, where Synapse acts as a gateway to accept all messages and then
perform mediation and routing based on message properties or content.</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 1: i.e. synapse -sample 1<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already deployed<br/>
</p>
<p>
Execute the Dumb Client as:
</p>
<pre xml:space="preserve">ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuote<br/></pre>
<p>
This time you will notice that Synapse received a message for which
Synapse was set as the ultimate receiver of the message. Based on the 'To'
EPR of http://localhost:8080/soap/StockQuote, Synapse performes a match to
the path '/StockQuote' and as the request matched the XPath expression of
the filter mediator, the filter mediators' child mediators executes, and
thereby sending the message to a different endpoint as specified by the
endpoint definition. The 'drop' mediator terminates further processing of
the current message in a configuration. During response processing, the
filter condition fails, and thus the implicit 'send' mediator forwards the
reply back to the client.
</p>
<h2>
<a name="Sample2" id="Sample2">Sample 2:</a>
</h2>
<pre xml:space="preserve">&lt;!-- switch-case mediator and setting and reading of local properties on a message --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;switch source="//m0:getQuote/m0:request/m0:symbol" xmlns:m0="http://services.samples/xsd"&gt;
&lt;case regex="IBM"&gt;
&lt;!-- the property mediator sets a local property on the *current* message --&gt;
&lt;property name="symbol" value="Great stock - IBM"/&gt;
&lt;/case&gt;
&lt;case regex="MSFT"&gt;
&lt;property name="symbol" value="Are you sure? - MSFT"/&gt;
&lt;/case&gt;
&lt;default&gt;
&lt;!-- it is possible to assign the result of an XPath expression as well --&gt;
&lt;property name="symbol"
expression="fn:concat('Normal Stock - ', //m0:getQuote/m0:request/m0:symbol)"
xmlns:m0="http://services.samples/xsd"/&gt;
&lt;/default&gt;
&lt;/switch&gt;
&lt;log level="custom"&gt;
&lt;!-- the get-property() XPath extension function allows the lookup of local message properties
as well as properties from the Axis2 or Transport contexts (i.e. transport headers) --&gt;
&lt;property name="symbol" expression="get-property('symbol')"/&gt;
&lt;!-- the get-property() function supports the implicit message headers To/From/Action/FaultTo/ReplyTo --&gt;
&lt;property name="epr" expression="get-property('To')"/&gt;
&lt;/log&gt;
&lt;!-- Send the messages where they are destined to (i.e. the 'To' EPR of the message) --&gt;
&lt;send/&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Introduce switch-case mediator and writing and
reading of local properties set on a message instance</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 2: i.e. synapse -sample 2<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done.
</p>
<p>
Execute the 'ant stockquote ..' request again in the smart client mode,
specifying 'IBM', 'MSFT' and 'SUN' as the stock symbols. When the symbol
IBM is request, following through the mediation logs you will see that the
case statements' first case for 'IBM' executed and a local property named
'symbol' was set to 'Great stock - IBM'. Subsequently this local property
value is looked up by the log mediator and logged using the
'get-property()' XPath extension function.
</p>
<p>
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService
-Dtrpurl=http://localhost:8080/ -Dsymbol=IBM
</p>
<pre xml:space="preserve">INFO LogMediator - symbol = Great stock - IBM, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService </pre>
<p>
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService
-Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT
</p>
<pre xml:space="preserve">INFO LogMediator - symbol = Are you sure? - MSFT, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService</pre>
<h2>
<a name="Sample3" id="Sample3">Sample 3:</a>
</h2>
<pre xml:space="preserve">&lt;!-- illustration of local registry entry definitions, and reusable endpoints and sequences --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;!-- define a string resource entry to the local registry --&gt;
&lt;localEntry key="version"&gt;0.1&lt;/localEntry&gt;
&lt;!-- define a reuseable endpoint definition --&gt;
&lt;endpoint name="simple"&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;!-- define a reusable sequence --&gt;
&lt;sequence name="stockquote"&gt;
&lt;!-- log the message using the custom log level. illustrates custom properties for log --&gt;
&lt;log level="custom"&gt;
&lt;property name="Text" value="Sending quote request"/&gt;
&lt;property name="version" expression="get-property('version')"/&gt;
&lt;property name="direction" expression="get-property('direction')"/&gt;
&lt;/log&gt;
&lt;!-- send message to real endpoint referenced by key "simple" endpoint definition --&gt;
&lt;send&gt;
&lt;endpoint key="simple"/&gt;
&lt;/send&gt;
&lt;/sequence&gt;
&lt;sequence name="main"&gt;
&lt;in&gt;
&lt;property name="direction" value="incoming"/&gt;
&lt;sequence key="stockquote"/&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Illustrates local registry entry definitions,
reusable endpoints and sequences</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 3: i.e. synapse -sample 3<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
This example uses a sequence named as "main" that specifies the main
mediation rules to be executed. This is equivalent to directly specifying
the mediators of the main sequence within the &lt;definitions&gt; tags.
This is the recommended and also a neater approach for non trivial
configurations. Execute the 'ant stockquote ..' request again, and
following through the mediation logs you will now notice that the sequence
named "main" executed. Then for the incoming message flow the &lt;in&gt;
mediator executes, and it calls into the sequence named "stockquote"
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre>
<pre xml:space="preserve">DEBUG SequenceMediator - Sequence mediator &lt;main&gt; :: mediate()<br/>DEBUG InMediator - In mediator mediate()<br/>DEBUG SequenceMediator - Sequence mediator &lt;stockquote&gt; :: mediate()</pre>
<p>
As the "stockquote" sequence executes, the log mediator dumps a simple
text/string property, an XPath evaluation result - that picks up the key
named "version", and a second XPath evaluation result that picks up a
local message property set previously by the &lt;property&gt; mediator.
The get-property() XPath extension function is able to read message
properties local to the current message, local or remote registry entries,
Axis2 message context properties as well as transport headers. The local
entry definition for "version" defines a simple text/string registry entry
for that is visible to all messages that passes through Synapse.
</p>
<pre xml:space="preserve">[HttpServerWorker-1] INFO LogMediator - Text = Sending quote request, version = 0.1, direction = incoming
[HttpServerWorker-1] DEBUG SendMediator - Send mediator :: mediate()
[HttpServerWorker-1] DEBUG AddressEndpoint - Sending To: http://localhost:9000/soap/SimpleStockQuoteService </pre>
<h2>
<a name="Sample4" id="Sample4">Sample 4:</a>
</h2>
<pre xml:space="preserve">&lt;!-- introduction to error handling --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;!-- the default fault handling sequence used by Synapse - named 'fault' --&gt;
&lt;sequence name="fault"&gt;
&lt;log level="custom"&gt;
&lt;property name="text" value="An unexpected error occured"/&gt;
&lt;property name="message" expression="get-property('ERROR_MESSAGE')"/&gt;
&lt;/log&gt;
&lt;drop/&gt;
&lt;/sequence&gt;
&lt;sequence name="sunErrorHandler"&gt;
&lt;log level="custom"&gt;
&lt;property name="text" value="An unexpected error occured for stock SUN"/&gt;
&lt;property name="message" expression="get-property('ERROR_MESSAGE')"/&gt;
&lt;/log&gt;
&lt;drop/&gt;
&lt;/sequence&gt;
&lt;!-- default message handling sequence used by Synapse - named 'main' --&gt;
&lt;sequence name="main"&gt;
&lt;in&gt;
&lt;switch source="//m0:getQuote/m0:request/m0:symbol" xmlns:m0="http://services.samples/xsd"&gt;
&lt;case regex="IBM"&gt;
&lt;send&gt;
&lt;endpoint&gt;&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/case&gt;
&lt;case regex="MSFT"&gt;
&lt;send&gt;
&lt;endpoint key="bogus"/&gt;
&lt;/send&gt;
&lt;/case&gt;
&lt;case regex="SUN"&gt;
&lt;sequence key="sunSequence"/&gt;
&lt;/case&gt;
&lt;/switch&gt;
&lt;drop/&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;sequence name="sunSequence" onError="sunErrorHandler"&gt;
&lt;send&gt;
&lt;endpoint key="sunPort"/&gt;
&lt;/send&gt;
&lt;/sequence&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: Introduction to error handling with the 'fault'
sequence</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 4: i.e. synapse -sample 4<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
When the IBM stock quote is requested, the configuration routes it to the
endpoint defined as the 'simple' endpoint, which routes the message to the
SimpleStockQuoteService on the local Axis2 instance. Hence a valid
response message is shown at the client.
</p>
<p>
If you lookup a stock quote for 'MSFT', Synapse is instructed to route the
message to the endpoint defined as the 'bogus' endpoint, which does not
exist. Synapse executes the specified error handler sequence closest to
the point where the error was encountered. In this case, the currently
executing sequence is 'main' and it does not specify an 'onError'
attribute. Whenever Synapse cannot find an error handler, it looks up for
a sequence named 'fault'. Thus the 'fault' sequence can be seen executing,
and writing the generic error message into the logs.
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT</pre>
<pre xml:space="preserve">[HttpServerWorker-1] DEBUG SendMediator - Send mediator :: mediate()
[HttpServerWorker-1] ERROR IndirectEndpoint - Reference to non-existent endpoint for key : bogus
[HttpServerWorker-1] DEBUG MediatorFaultHandler - MediatorFaultHandler :: handleFault
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator &lt;fault&gt; :: mediate()
[HttpServerWorker-1] DEBUG LogMediator - Log mediator :: mediate()
[HttpServerWorker-1] INFO LogMediator - text = An unexpected error occured, message = Reference to non-existent endpoint for key : bogus</pre>
<p>
When the 'SUN' quote is requested, a custom sequence 'sunSequence' is
invoked, and it specifies 'sunErrorHandler' as its error handler. Hence
when the send fails, now you could see the proper error handler invocation
and the custom error message as follows:
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN</pre>
<pre xml:space="preserve">[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator &lt;sunSequence&gt; :: mediate()
[HttpServerWorker-1] DEBUG SequenceMediator - Setting the onError handler for the sequence
[HttpServerWorker-1] DEBUG AbstractListMediator - Implicit Sequence &lt;SequenceMediator&gt; :: mediate()
[HttpServerWorker-1] DEBUG SendMediator - Send mediator :: mediate()
[HttpServerWorker-1] ERROR IndirectEndpoint - Reference to non-existent endpoint for key : sunPort
[HttpServerWorker-1] DEBUG MediatorFaultHandler - MediatorFaultHandler :: handleFault
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator &lt;sunErrorHandler&gt; :: mediate()
[HttpServerWorker-1] DEBUG AbstractListMediator - Implicit Sequence &lt;SequenceMediator&gt; :: mediate()
[HttpServerWorker-1] DEBUG LogMediator - Log mediator :: mediate()
[HttpServerWorker-1] INFO LogMediator - text = An unexpected error occured for stock SUN, message = Reference to non-existent endpoint for key : sunPort</pre>
<h2>
<a name="Sample5" id="Sample5">Sample 5:</a>
</h2>
<pre xml:space="preserve">&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="myFaultHandler"&gt;
&lt;makefault&gt;
&lt;code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/&gt;
&lt;reason expression="get-property('ERROR_MESSAGE')"/&gt;
&lt;/makefault&gt;
&lt;property name="RESPONSE" value="true"/&gt;
&lt;header name="To" expression="get-property('ReplyTo')"/&gt;
&lt;send/&gt;
&lt;/sequence&gt;
&lt;sequence name="main" onError="myFaultHandler"&gt;
&lt;in&gt;
&lt;switch source="//m0:getQuote/m0:request/m0:symbol"
xmlns:m0="http://services.samples/xsd"&gt;
&lt;case regex="MSFT"&gt;
&lt;send&gt;
&lt;endpoint&gt;&lt;address uri="http://bogus:9000/soap/NonExistentStockQuoteService"/&gt;&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/case&gt;
&lt;case regex="SUN"&gt;
&lt;send&gt;
&lt;endpoint&gt;&lt;address uri="http://localhost:9009/soap/NonExistentStockQuoteService"/&gt;&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/case&gt;
&lt;/switch&gt;
&lt;drop/&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Makefault mediator and sending back error responses
</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 5: i.e. synapse -sample 5<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
When the MSFT stock quote is requested, an unknown host exception would be
caused, and a connection refused exception would be caused for the SUN
stock. This information is captured and returned back to the original
client as a SOAP fault in this example.
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT</pre>
<p>
Returns:
</p>
<pre xml:space="preserve">&lt;soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;&lt;faultcode&gt;soapenv:Client&lt;/faultcode&gt;
&lt;faultstring&gt;java.net.UnknownHostException: bogus&lt;/faultstring&gt;&lt;detail /&gt;&lt;/soapenv:Fault&gt;</pre>
<p>
And
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN</pre>
<p>
Returns:
</p>
<pre xml:space="preserve">&lt;soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;&lt;faultcode&gt;soapenv:Client&lt;/faultcode&gt;
&lt;faultstring&gt;java.net.ConnectException: Connection refused&lt;/faultstring&gt;&lt;detail /&gt;&lt;/soapenv:Fault&gt;</pre>
<h2>
<a name="Sample6" id="Sample6">Sample 6:</a>
</h2>
<pre xml:space="preserve">&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;in&gt;
&lt;header name="To" value="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/in&gt;
&lt;send/&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Introduction to header, in (out) mediators</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 6: i.e. synapse -sample 6<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
In this example we use the stockquote client in the dumb client mode,
setting the 'To' EPR of the message to Synapse. Then the 'in' mediator
processes the incoming messages, and manipulates the 'To' header to refer
to the stock quote service on the sample Axis2 server. Thus it is now
possible to request for a stock quote as follows:
</p>
<pre xml:space="preserve">ant stockquote -Dtrpurl=http://localhost:8080/soap/SimpleStockQuoteService</pre>
<h2>
<a name="Sample7" id="Sample7">Sample 7:</a>
</h2>
<pre xml:space="preserve">&lt;!-- introduction of static inline XML properties and the validation mediator --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;localEntry key="validate_schema"&gt;
&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.apache-synapse.org/test" elementFormDefault="qualified"
attributeFormDefault="unqualified"
targetNamespace="http://services.samples/xsd"&gt;
&lt;xs:element name="getQuote"&gt;
&lt;xs:complexType&gt;
&lt;xs:sequence&gt;
&lt;xs:element name="request"&gt;
&lt;xs:complexType&gt;
&lt;xs:sequence&gt;
&lt;xs:element name="stocksymbol" type="xs:string"/&gt;
&lt;/xs:sequence&gt;
&lt;/xs:complexType&gt;
&lt;/xs:element&gt;
&lt;/xs:sequence&gt;
&lt;/xs:complexType&gt;
&lt;/xs:element&gt;
&lt;/xs:schema&gt;
&lt;/localEntry&gt;
&lt;in&gt;
&lt;validate&gt;
&lt;schema key="validate_schema"/&gt;
&lt;on-fail&gt;
&lt;!-- if the request does not validate againt schema throw a fault --&gt;
&lt;makefault&gt;
&lt;code value="tns:Receiver"
xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/&gt;
&lt;reason value="Invalid custom quote request"/&gt;
&lt;/makefault&gt;
&lt;property name="RESPONSE" value="true"/&gt;
&lt;header name="To" expression="get-property('ReplyTo')"/&gt;
&lt;/on-fail&gt;
&lt;/validate&gt;
&lt;/in&gt;
&lt;send/&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: Introduction to local (static) registry entries and
the validate mediator</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 7: i.e. synapse -sample 7<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
This example shows how a static XML fragment could be made available to
the Synapse local registry. Resources defined to the local registry are
static (i.e. never changes over the lifetime of the configuration) and may
be specified as a source URL, inline-text or inline-xml. In this example
the schema is made available under the key 'validate_schema'.
</p>
<p>
The validate mediator by default operates on the first child element of
the SOAP body. You may specify an XPath expression using the 'source'
attribute to override this behaviour. The validate mediator now uses the
'validate_schema' resource to validate the incoming message, and if the
message is in error invokes on the 'on-fail' sequence of mediators.
</p>
<p>
If you send a stockquote request using 'ant stockquote ..' you will now
get a fault back with a message 'Invalid custom quote request' as the
schema validation failed. This is because the schema used in the example
expects a slightly different message than what is created by the stock
quote client. (i.e. expects a 'stocksymbol' element instead of 'symbol' to
specify thestock symbol)
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre>
<h2>
<a name="Sample8" id="Sample8">Sample 8:</a>
</h2>
<pre xml:space="preserve">&lt;!-- introduction to static and dynamic registry resources and the XSLT mediator --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;!-- the SimpleURLRegistry allows access to a URL based registry (e.g. file:/// or http://) --&gt;
&lt;registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"&gt;
&lt;!-- the root property of the simple URL registry helps resolve a resource URL as root + key --&gt;
&lt;parameter name="root"&gt;file:./repository/conf/sample/resources/&lt;/parameter&gt;
&lt;!-- all resources loaded from the URL registry would be cached for this number of milli seconds --&gt;
&lt;parameter name="cachableDuration"&gt;15000&lt;/parameter&gt;
&lt;/registry&gt;
&lt;!-- define the request processing XSLT resource as a static URL source --&gt;
&lt;localEntry key="xslt-key-req" src="file:repository/conf/sample/resources/transform/transform.xslt"/&gt;
&lt;in&gt;
&lt;!-- transform the custom quote request into a standard quote requst expected by the service --&gt;
&lt;xslt key="xslt-key-req"/&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- transform the standard response back into the custom format the client expects --&gt;
&lt;!-- the key is looked up in the remote registry and loaded as a 'dynamic' registry resource --&gt;
&lt;xslt key="transform/transform_back.xslt"/&gt;
&lt;/out&gt;
&lt;send/&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Introduction to static and dynamic registry
resources and the XSLT mediator</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 8: i.e. synapse -sample 8<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
This example uses the XSLT mediator to perform transformations, and the
xslt tranformations are specified as registry resources. The first
resource 'xslt-key-req' is specified as a 'local' registry entry. Local
entries do not place the resource on the registry, but simply makes it
available to the local configuration. If a local entry is defined with a
key that already exists in the remote registry, the local entry will have
preference and hide the existence of the remote resource.
</p>
<p>
In this example you will notice the new 'registry' definition. Synapse
comes with a simple URL based registry implementation SimpleURLRegistry.
During initialization of the registry, the SimpleURLRegistry expects to
find a property named 'root', which specifies a prefix for the registry
keys used later. When the SimpleURLRegistry is used, this root is prefixed
to the entry keys to form the complete URL for the resource being looked
up. The registry caches a resource once requested, and caches it
internally for a specified duration. Once this period expires, it will
reload the meta information about the resource and reload its cached copy
if necessary, the next time the resource is requested.
</p>
<p>
Hence the second XSLT resource key 'transform/transform_back.xslt'
concatenated with the 'root' of the SimpleURLRegistry
'file:repository/conf/sample/resources/' forms the complete URL of the
resource as
'file:repository/conf/sample/resources/transform/transform_back.xslt' and
caches its value for a period of 15000 ms.
</p>
<p>
Execute the custom quote client as 'ant stockquote -Dmode=customquote ..'
and analyze the the Synapse debug log output as shown below
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote</pre>
<pre xml:space="preserve">[HttpServerWorker-1] DEBUG XSLTMediator - Performing XSLT transformation against property with key : xslt-key-req
[HttpServerWorker-1] DEBUG XSLTMediator - Transformation source :
&lt;m0:CheckPriceRequest xmlns:m0="http://www.apache-synapse.org/test"&gt;&lt;m0:Code&gt;IBM&lt;/m0:Code&gt;&lt;/m0:CheckPriceRequest&gt;
[HttpServerWorker-1] DEBUG XSLTMediator - Transformation result : &lt;m:getQuote xmlns:m="http://services.samples/xsd"&gt;</pre>
<p>
The incoming message is now transformed into a standard stock quote
request as expected by the SimpleStockQuoteService deployed on the local
Axis2 instance, by the XSLT mediator. The XSLT mediator uses Xalan-J to
perform the transformations. It is possible to configure the underlying
transformation engine using properties where necessary. The response from
the SimpleStockQuoteService is converted back into the custom format as
expected by the client during the out message processing.
</p>
<p>
During the response processing you could notice the SimpleURLRegistry
fetching the resource as shown by the log message below
</p>
<pre xml:space="preserve">[HttpClientWorker-1] INFO SimpleURLRegistry - ==&gt; Repository fetch of resource with key : transform/transform_back.xslt</pre>
<p>
If you re-run the client again immidiately (i.e within 15 seconds of the
first request) you will not see the resource being re-loaded by the
registry as the cached value would be still valid.
</p>
<p>
However if you leave the system idle for 15 seconds or more and then retry
the same request, you will now notice that the registry noticed the cache
expiry and checked the meta information about the resource to check if the
resource itself has changes and requires a fresh fetch from the source
URL. If the meta data / version number indicates that a reload of the
cached resource is not necessary (i.e. unless the resource itself actually
changed) the updated meta information is used and the cache lease extended
as appropriate.
</p>
<pre xml:space="preserve">[HttpClientWorker-1] DEBUG AbstractRegistry - Cached object has expired for key : transform/transform_back.xslt
[HttpClientWorker-1] DEBUG SimpleURLRegistry - Perform RegistryEntry lookup for key : transform/transform_back.xslt
[HttpClientWorker-1] DEBUG AbstractRegistry - Expired version number is same as current version in registry
[HttpClientWorker-1] DEBUG AbstractRegistry - Renew cache lease for another 15s </pre>
<p>
Now edit the
repository/conf/sample/resources/transform/transform_back.xslt file and
add a blank line at the end. Now when you run the client again, and if the
cache is expired, the resource would be re-fetched from its URL by the
registry and this can be seen by the following debug log messages
</p>
<pre xml:space="preserve">[HttpClientWorker-1] DEBUG AbstractRegistry - Cached object has expired for key : transform/transform_back.xslt
[HttpClientWorker-1] DEBUG SimpleURLRegistry - Perform RegistryEntry lookup for key : transform/transform_back.xslt
[HttpClientWorker-1] INFO SimpleURLRegistry - ==&gt; Repository fetch of resource with key : transform/transform_back.xslt </pre>
<p>
Thus the SimpleURLRegistry allows resource to be cached, and updates
detected so that changes could be reloaded without restarting the Synapse
instance.
</p>
<h2>
<a name="Sample9" id="Sample9">Sample 9:</a>
</h2>
<pre xml:space="preserve">&lt;!-- introduction dynamic sequences --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"&gt;
&lt;parameter name="root"&gt;file:./repository/conf/sample/resources/&lt;/parameter&gt;
&lt;parameter name="cachableDuration"&gt;15000&lt;/parameter&gt;
&lt;/registry&gt;
&lt;sequence key="sequence/dynamic_seq_1.xml"/&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: Introduction to dynamic sequences with a Registry</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 9: i.e. synapse -sample 9<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
This example introduces the dynamic behaviour of Synapse through the use
of a Registry. Synapse supports dynamic definitions for sequences &amp;
endpoints, and as seen before, for resources. In this example we define a
Synapse configuration which references a sequence definition specified as
a registry key. The registry key resolves to the actual content of the
sequence which would be loaded dynamically by Synapse at runtime, and
cached appropriately as per its definition in the registry. Once the cache
expires, Synapse would recheck the meta information for the definition and
re-load the sequence definition if necessary and re-cache it again.
</p>
<p>
Once Synapse is started, execute the stock quote client as 'ant
stockquote..'. You will notice that that Synapse fetches the definition of
the sequence from the registry and executes its rules as follows:
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre>
<pre xml:space="preserve">[HttpServerWorker-1] INFO SimpleURLRegistry - ==&gt; Repository fetch of resource with key : sequence/dynamic_seq_1.xml
...
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator &lt;dynamic_sequence&gt; :: mediate()
...
[HttpServerWorker-1] INFO LogMediator - message = *** Test Message 1 ***</pre>
<p>
Now if you execute the client immidiately (i.e. within 15 seconds of the
last execution) you will notice that the sequence was not reloaded. If you
edit the sequence definition in
repository/conf/sample/resources/sequence/dynamic_seq_1.xml and edit the
log message to read as "*** Test Message 2 ***" and execute the client
again, you will notice that the new message is not yet visible (i.e. if
you execute this within 15 seconds of loading the resource for the first
time) However, after 15 seconds have elapsed since the original caching of
the sequence, you will notice that the new sequence is loaded and executed
by Synapse from the following log messages:
</p>
<pre xml:space="preserve">[HttpServerWorker-1] INFO SimpleURLRegistry - ==&gt; Repository fetch of resource with key : sequence/dynamic_seq_1.xml
...
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator &lt;dynamic_sequence&gt; :: mediate()
...
[HttpServerWorker-1] INFO LogMediator - message = *** Test Message 2 ***</pre>
<p>
The cache timeout could be tuned appropriately by configuring the URL
registry to suite the environment and the needs.
</p>
<h2>
<a name="Sample10" id="Sample10">Sample 10:</a>
</h2>
<pre xml:space="preserve">&lt;!-- introduction dynamic endpoints --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"&gt;
&lt;parameter name="root"&gt;file:repository/conf/sample/resources/&lt;/parameter&gt;
&lt;parameter name="cachableDuration"&gt;15000&lt;/parameter&gt;
&lt;/registry&gt;
&lt;in&gt;
&lt;send&gt;
&lt;endpoint key="endpoint/dynamic_endpt_1.xml"/&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: Introduction to dynamic endpoints with the Registry</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 10: i.e. synapse -sample 10<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done<br/>
Start a second Axis2 server on http port 9001 and https port 9003 as
follows:
</p>
<pre xml:space="preserve">./axis2server.sh -http 9001 -https 9003</pre>
<p>
This example introduces dynamic endpoints, where the definition of an
endpoint is stored in the Registry. To follow this example execute the
stock quote client as 'ant stockquote..' and see that the message is
routed to the SimpleStockQuoteService on the default Axis2 instance on
http port 9000. Repeat the above example immidiately again, and notice
that the endpoint is cached and reused by Synapse - similarly to example #
8.
</p>
<pre xml:space="preserve">ant stockquote -Dtrpurl=http://localhost:8080/</pre>
<p>
Now edit the repository/conf/sample/resources/endpoint/dynamic_endpt_1.xml
definition and update the address to
"http://localhost:9001/soap/SimpleStockQuoteService". After the cached
expires, the Registry loads the new definition of the endpoint, and then
the messages can be seen being routed to the second sample Axis2 server on
http port 9001.
</p>
<h2>
<a name="Sample11" id="Sample11">Sample 11:</a>
</h2>
<pre xml:space="preserve">&lt;!-- a full registry based configuration --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"&gt;
&lt;parameter name="root"&gt;file:./repository/conf/sample/resources/&lt;/parameter&gt;
&lt;parameter name="cachableDuration"&gt;15000&lt;/parameter&gt;
&lt;/registry&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: A full registry based configuration</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 11: i.e. synapse -sample 11<br/> Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
</p>
<p>
This example shows a full registry based Synapse configuration. Thus it is
possible to start a remote configuration from multiple instances of
Synapse in a clustered environment easily, and allow the configuration to
be reloaded as well. The Synapse configuration held on a node hosting
Synapse simply points to the registry and looks up the actual
configuration by requesting the key ''synapse.xml'.
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre>
<pre xml:space="preserve">[HttpServerWorker-1] INFO LogMediator - message = This is a dynamic Synapse configuration</pre>
<p>
The actual synapse.xml loaded is:
</p>
<pre xml:space="preserve">&lt;!-- a registry based Synapse configuration --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;log level="custom"&gt;
&lt;property name="message" value="This is a dynamic Synapse configuration $$$"/&gt;
&lt;/log&gt;
&lt;send/&gt;
&lt;/definitions&gt;</pre>
<p/>
<h1>
<a name="Endpoints" id="Endpoints">Endpoints</a>
</h1>
<h2>
<a name="Sample50" id="Sample50">Sample 50:</a>
</h2>
<pre xml:space="preserve">&lt;!-- Connecting to endpoints with WS-Security for outgoing messages --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;localEntry key="sec_policy" src="file:repository/conf/sample/resources/policy/policy_3.xml"/&gt;
&lt;in&gt;
&lt;send&gt;
&lt;endpoint name="secure"&gt;
&lt;address uri="http://localhost:9000/soap/SecureStockQuoteService"&gt;
&lt;enableSec policy="sec_policy"/&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;header name="wsse:Security" action="remove"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Connecting to endpoints with WS-Security for
outgoing messages</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/>
</p>
<p>
You may also need to download and install the unlimited strength policy
files for your JDK before using Apache Rampart (e.g. see
http://java.sun.com/javase/downloads/index_jdk5.jsp)
</p>
<p>
Start the Synapse configuration numbered 50: i.e. synapse -sample 50<br/>
Start the Axis2 server and deploy the SecureStockQuoteService if not
already done
</p>
<p/>
<p>
Use the stock quote client to send a request without WS-Security. Synapse
is configured to enable WS-Security as per the policy specified by
'policy_3.xml' for the outgoing messages to the SecureStockQuoteService
endpoint hosted on the Axis2 instance. The debug log messages on Synapse
shows the encrypted message flowing to the service and the encrypted
response being received by Synapse. The wsse:Security header is then
removed from the decrypted message and the response is delivered back to
the client, as expected. You may execute the client as follows:
</p>
<pre xml:space="preserve">ant stockquote -Dtrpurl=http://localhost:8080/</pre>
<p>
The message sent by Synapse to the secure service can be seen as follows,
when TCPMon is used.
</p>
<pre xml:space="preserve">POST http://localhost:9001/soap/SecureStockQuoteService HTTP/1.1
Host: 127.0.0.1
SOAPAction: urn:getQuote
Content-Type: text/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: Keep-Alive
User-Agent: Synapse-HttpComponents-NIO
800
&lt;?xml version='1.0' encoding='UTF-8'?&gt;
&lt;soapenv:Envelope xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsa="http://www.w3.org/2005/08/addressing" ..&gt;
&lt;soapenv:Header&gt;
&lt;wsse:Security ..&gt;
&lt;wsu:Timestamp ..&gt;
...
&lt;/wsu:Timestamp&gt;
&lt;xenc:EncryptedKey..&gt;
...
&lt;/xenc:EncryptedKey&gt;
&lt;wsse:BinarySecurityToken ...&gt;
&lt;ds:SignedInfo&gt;
...
&lt;/ds:SignedInfo&gt;
&lt;ds:SignatureValue&gt;
...
&lt;/ds:SignatureValue&gt;
&lt;ds:KeyInfo Id="KeyId-29551621"&gt;
...
&lt;/ds:KeyInfo&gt;
&lt;/ds:Signature&gt;
&lt;/wsse:Security&gt;
&lt;wsa:To&gt;http://localhost:9001/soap/SecureStockQuoteService&lt;/wsa:To&gt;
&lt;wsa:MessageID&gt;urn:uuid:1C4CE88B8A1A9C09D91177500753443&lt;/wsa:MessageID&gt;
&lt;wsa:Action&gt;urn:getQuote&lt;/wsa:Action&gt;
&lt;/soapenv:Header&gt;
&lt;soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-3789605"&gt;
&lt;xenc:EncryptedData Id="EncDataId-3789605" Type="http://www.w3.org/2001/04/xmlenc#Content"&gt;
&lt;xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" /&gt;
&lt;xenc:CipherData&gt;
&lt;xenc:CipherValue&gt;Layg0xQcnH....6UKm5nKU6Qqr&lt;/xenc:CipherValue&gt;
&lt;/xenc:CipherData&gt;
&lt;/xenc:EncryptedData&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;0</pre>
<h2>
<a name="Sample51" id="Sample51">Sample 51:</a>
</h2>
<pre xml:space="preserve">&lt;!-- MTOM and SwA and message properties to correlate requests and responses --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;in&gt;
&lt;filter source="get-property('Action')" regex="urn:uploadFileUsingMTOM"&gt;
&lt;property name="example" value="mtom"/&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/MTOMSwASampleService" optimize="mtom"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/filter&gt;
&lt;filter source="get-property('Action')" regex="urn:uploadFileUsingSwA"&gt;
&lt;property name="example" value="swa"/&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/MTOMSwASampleService" optimize="swa"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/filter&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;filter source="get-property('example')" regex="mtom"&gt;
&lt;property name="enableMTOM" value="true" scope="axis2"/&gt;
&lt;/filter&gt;
&lt;filter source="get-property('example')" regex="swa"&gt;
&lt;property name="enableSwA" value="true" scope="axis2"/&gt;
&lt;/filter&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: MTOM and SwA optimizations and request/response
correlation</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 51: i.e. synapse -sample 51<br/> Start the Axis2
server and deploy the MTOMSwASampleService if not already done
</p>
<p>
Execute the 'ant optimizeclient' specifying MTOM optimization as follows:
</p>
<pre xml:space="preserve">ant optimizeclient -Dopt_mode=mtom</pre>
<p>
The configuration now sets a local message context property, and forwards
the message to 'http://localhost:9000/soap/MTOMSwASampleService'
optimizing bindary content as MTOM. By sending this message through TCPMon
you would be able to see the actual message sent over the http transport
if required. Thus during response processing, by checking the local
message property Synapse could identify the past information about the
current message context, and uses this knowledge to transform the response
back to the client in the same format as the original request.
</p>
<p>
When the client executes successfully, it will upload a file containing
the ASF logo and receive its response back again and save it into a
temporary file.
</p>
<pre xml:space="preserve">[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as MTOM</pre>
<pre xml:space="preserve">[java] Saved response to file : /tmp/mtom-36877.gif</pre>
<p>
Next try SwA as:
</p>
<pre xml:space="preserve">ant optimizeclient -Dopt_mode=swa</pre>
<pre xml:space="preserve">[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as SwA
[java] Saved response to file : /tmp/swa-47549.gif</pre>
<p>
By using TCPMon and sending the message through it, one can inspect that
the requests and responses sent are indeed MTOM optimized or sent as http
attachments as follows:
</p>
<pre xml:space="preserve">POST http://localhost:9000/soap/MTOMSwASampleService HTTP/1.1
Host: 127.0.0.1
SOAPAction: urn:uploadFileUsingMTOM
Content-Type: multipart/related; boundary=MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177413845353; type="application/xop+xml";
start="&lt;0.urn:uuid:B94996494E1DD5F9B51177413845354@apache.org&gt;"; start-info="text/xml"; charset=UTF-8
Transfer-Encoding: chunked
Connection: Keep-Alive
User-Agent: Synapse-HttpComponents-NIO
--MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177413845353241
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID:
&lt;0.urn:uuid:B94996494E1DD5F9B51177413845354@apache.org&gt;221b1
&lt;?xml version='1.0' encoding='UTF-8'?&gt;
&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Body&gt;
&lt;m0:uploadFileUsingMTOM xmlns:m0="http://www.apache-synapse.org/test"&gt;
&lt;m0:request&gt;
&lt;m0:image&gt;
&lt;xop:Include href="cid:1.urn:uuid:78F94BC50B68D76FB41177413845003@apache.org" xmlns:xop="http://www.w3.org/2004/08/xop/include" /&gt;
&lt;/m0:image&gt;
&lt;/m0:request&gt;
&lt;/m0:uploadFileUsingMTOM&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;
--MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177413845353217
Content-Type: image/gif
Content-Transfer-Encoding: binary
Content-ID:
&lt;1.urn:uuid:78F94BC50B68D76FB41177413845003@apache.org&gt;22800GIF89a... &lt;&lt; binary content &gt;&gt;</pre>
<pre xml:space="preserve">POST http://localhost:9000/soap/MTOMSwASampleService HTTP/1.1
Host: 127.0.0.1
SOAPAction: urn:uploadFileUsingSwA
Content-Type: multipart/related; boundary=MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177414170491; type="text/xml";
start="&lt;0.urn:uuid:B94996494E1DD5F9B51177414170492@apache.org&gt;"; charset=UTF-8
Transfer-Encoding: chunked
Connection: Keep-Alive
User-Agent: Synapse-HttpComponents-NIO
--MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177414170491225
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID:
&lt;0.urn:uuid:B94996494E1DD5F9B51177414170492@apache.org&gt;22159
&lt;?xml version='1.0' encoding='UTF-8'?&gt;
&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Body&gt;
&lt;m0:uploadFileUsingSwA xmlns:m0="http://www.apache-synapse.org/test"&gt;
&lt;m0:request&gt;
&lt;m0:imageId&gt;urn:uuid:15FD2DA2584A32BF7C1177414169826&lt;/m0:imageId&gt;
&lt;/m0:request&gt;
&lt;/m0:uploadFileUsingSwA&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;22--34MIMEBoundaryurn_uuid_B94996494E1DD5F9B511774141704912
17
Content-Type: image/gif
Content-Transfer-Encoding: binary
Content-ID:
&lt;urn:uuid:15FD2DA2584A32BF7C1177414169826&gt;22800GIF89a... &lt;&lt; binary content &gt;&gt;</pre>
<h2>
<a name="Sample52" id="Sample52">Sample 52:</a>
</h2>
<pre xml:space="preserve">&lt;!-- POX to SOAP conversion --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;!-- filtering of messages with XPath and regex matches --&gt;
&lt;filter source="get-property('To')" regex=".*/StockQuote.*"&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="soap"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;drop/&gt;
&lt;/filter&gt;
&lt;send/&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: POX to SOAP conversion</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 52: i.e. synapse -sample 52\
</p>
<p>
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
</p>
<p>
Execute the 'ant stockquote' specifying that the request should be a REST
request as follows:
</p>
<pre xml:space="preserve">ant stockquote -Dtrpurl=http://localhost:8081/soap/StockQuote -Drest=true</pre>
<p>
This example shows a http REST request (as shown below) being transformed
into a SOAP request and forwarded to the stock quote service.
</p>
<pre xml:space="preserve">POST /soap/StockQuote HTTP/1.1
Content-Type: application/xml; charset=UTF-8;action="urn:getQuote";
SOAPAction: urn:getQuote
User-Agent: Axis2
Host: 127.0.0.1
Transfer-Encoding: chunked
75
&lt;m0:getQuote xmlns:m0="http://services.samples/xsd"&gt;
&lt;m0:request&gt;
&lt;m0:symbol&gt;IBM&lt;/m0:symbol&gt;
&lt;/m0:request&gt;
&lt;/m0:getQuote&gt;0</pre>
<h2>
<a name="Sample53" id="Sample53">Sample 53:</a>
</h2>
<pre xml:space="preserve">&lt;!-- RMSequence example --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;in&gt;
&lt;RMSequence single="true" version="1.0"/&gt;
&lt;send&gt;
&lt;endpoint name="reliable"&gt;
&lt;address uri="http://localhost:9000/soap/ReliableStockQuoteService"&gt;
&lt;enableRM/&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;header name="wsrm:SequenceAcknowledgement" action="remove"
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/&gt;
&lt;header name="wsrm:Sequence" action="remove"
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/definitions&gt;</pre>
<strong>Objective: Demonstrate the message exchange between Synapse and
the server using WS-ReliableMessaging (WS-RM)</strong>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Deploy the ReliableStockQuoteService in the sample Axis2 server by
switching to the samples/axis2Server/src/ReliableStockQuoteService
directory and running ant.
</p>
<p>
Start the sample Axis2 server on port 9000.
</p>
<p>
Start Synapse with the sample configuration 53 (i.e. synapse -sample 53).
</p>
<p/>
<p>
In the above configuration, WS-RM is engaged to the endpoint using the
&lt;enableRM/&gt; tag. It is possible to engage WS-RM to both Address and
WSDL endpoints using this tag. In addition to the RM enabled endpoint,
RMSequence mediator is specified before the send mediator. This mediator
is used to specify the set of messages to be sent using a single RM
sequence. In this sample it is specified as single message per sequence.
It also specifies the version of the WS-RM to be used. Refer to the
Synapse configuration language documentation for more information about
the RMSequence mediator. RM related SOAP headers are removed form the
message in the out mediator as WS-RM message exchange happens only between
the Synapse and the server. Now run the sample client using the following
command.
</p>
<pre xml:space="preserve">ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080</pre>
<p>
You can observer the client output displaying the quote price for IBM as
follows:
</p>
<pre xml:space="preserve">[java] Standard :: Stock price = $189.2521262517493</pre>
<p>
There is no difference to be observed between the normal message exchange
and WS-RM enabled message exchange as far as client and server outputs are
considered. But if you look at the wire level messages, you would observe
additional WS-RM messages and WS-RM elements. Synapse, the initiator of
the RM sequence, first try to create a sequence by sending a message with
CreateSequence element.
</p>
<pre xml:space="preserve">...
&lt;soapenv:Body&gt;
&lt;wsrm:CreateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"&gt;
&lt;wsrm:AcksTo&gt;
&lt;wsa:Address&gt;http://www.w3.org/2005/08/addressing/anonymous&lt;/wsa:Address&gt;
&lt;/wsrm:AcksTo&gt;
&lt;wsrm:Offer&gt;
&lt;wsrm:Identifier&gt;urn:uuid:546F6F33FB7D8BBE351179807372769&lt;/wsrm:Identifier&gt;
&lt;/wsrm:Offer&gt;
&lt;/wsrm:CreateSequence&gt;
&lt;/soapenv:Body&gt;
...</pre>
<p>
Sample Axis2 server responds to CreateSequence request with the following
message:
</p>
<pre xml:space="preserve">...
&lt;soapenv:Body&gt;
&lt;wsrm:CreateSequenceResponse xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"&gt;
&lt;wsrm:Identifier&gt;urn:uuid:879853A6871A66641C1179807373270&lt;/wsrm:Identifier&gt;
&lt;wsrm:Accept&gt;
&lt;wsrm:AcksTo&gt;
&lt;wsa:Address&gt;http://localhost:9000/soap/ReliableStockQuoteService&lt;/wsa:Address&gt;
&lt;/wsrm:AcksTo&gt;
&lt;/wsrm:Accept&gt;
&lt;/wsrm:CreateSequenceResponse&gt;
&lt;/soapenv:Body&gt;
...</pre>
<p>
Once the sequence is established, Synapse sends the request to the server
with the pre-negotiated sequence ID.
</p>
<pre xml:space="preserve">&lt;soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Header&gt;
&lt;wsa:To&gt;http://localhost:9000/soap/ReliableStockQuoteService&lt;/wsa:To&gt;
&lt;wsa:MessageID&gt;urn:uuid:DB9A5257B637DDA38B1179807372560712002-1515891720&lt;/wsa:MessageID&gt;
&lt;wsa:Action&gt;urn:getQuote&lt;/wsa:Action&gt;
&lt;wsrm:Sequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
soapenv:mustUnderstand="1"&gt;
&lt;wsrm:Identifier&gt;urn:uuid:879853A6871A66641C1179807373270&lt;/wsrm:Identifier&gt;
&lt;wsrm:MessageNumber&gt;1&lt;/wsrm:MessageNumber&gt;
&lt;wsrm:LastMessage/&gt;
&lt;/wsrm:Sequence&gt;
&lt;/soapenv:Header&gt;
&lt;soapenv:Body&gt;
&lt;m0:getQuote xmlns:m0="http://services.samples/xsd"&gt;
&lt;m0:request&gt;
&lt;m0:symbol&gt;IBM&lt;/m0:symbol&gt;
&lt;/m0:request&gt;
&lt;/m0:getQuote&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p>
Synapse keeps on sending above message till the server responds with a
valid response message with 200 OK HTTP header. If the server is not ready
with a response, it will respond with 202 Accepted HTTP header for all
requests. Once the server is ready with a response it will send the
response message with sequence ID as follows.
</p>
<pre xml:space="preserve">&lt;soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Header&gt;
&lt;wsa:MessageID&gt;urn:uuid:879853A6871A66641C1179807373804&lt;/wsa:MessageID&gt;
&lt;wsa:Action&gt;http://services.samples/ReliableStockQuoteServicePortType/getQuoteResponse
&lt;/wsa:Action&gt;
&lt;wsa:RelatesTo&gt;urn:uuid:DB9A5257B637DDA38B1179807372560712002-1515891720&lt;/wsa:RelatesTo&gt;
&lt;wsrm:Sequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
soapenv:mustUnderstand="1"&gt;
&lt;wsrm:Identifier&gt;urn:uuid:546F6F33FB7D8BBE351179807372769&lt;/wsrm:Identifier&gt;
&lt;wsrm:MessageNumber&gt;1&lt;/wsrm:MessageNumber&gt;
&lt;wsrm:LastMessage/&gt;
&lt;/wsrm:Sequence&gt;
&lt;wsrm:SequenceAcknowledgement xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
soapenv:mustUnderstand="1"&gt;
&lt;wsrm:Identifier&gt;urn:uuid:879853A6871A66641C1179807373270&lt;/wsrm:Identifier&gt;
&lt;wsrm:AcknowledgementRange Lower="1" Upper="1"/&gt;
&lt;/wsrm:SequenceAcknowledgement&gt;
&lt;/soapenv:Header&gt;
&lt;soapenv:Body&gt;
&lt;ns:getQuoteResponse xmlns:ns="http://services.samples/xsd"&gt;
...</pre>
<p>
Now both Synapse and the server are done with the actual message exchange.
Then Synapse sends a request to terminate the sequence as follows:
</p>
<pre xml:space="preserve">&lt;soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Header&gt;
&lt;wsa:To&gt;http://localhost:9000/soap/ReliableStockQuoteService&lt;/wsa:To&gt;
&lt;wsa:MessageID&gt;urn:uuid:546F6F33FB7D8BBE351179807379591&lt;/wsa:MessageID&gt;
&lt;wsa:Action&gt;http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence&lt;/wsa:Action&gt;
&lt;wsrm:SequenceAcknowledgement xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
soapenv:mustUnderstand="1"&gt;
&lt;wsrm:Identifier&gt;urn:uuid:546F6F33FB7D8BBE351179807372769&lt;/wsrm:Identifier&gt;
&lt;wsrm:AcknowledgementRange Lower="1" Upper="1"/&gt;
&lt;/wsrm:SequenceAcknowledgement&gt;
&lt;/soapenv:Header&gt;
&lt;soapenv:Body&gt;
&lt;wsrm:TerminateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"&gt;
&lt;wsrm:Identifier&gt;urn:uuid:879853A6871A66641C1179807373270&lt;/wsrm:Identifier&gt;
&lt;/wsrm:TerminateSequence&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p>
Server responds to the sequence termination message, accepting to
terminate the sequence as follows.
</p>
<pre xml:space="preserve">&lt;soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Header&gt;
&lt;wsa:ReplyTo&gt;
&lt;wsa:Address&gt;http://localhost:9000/soap/ReliableStockQuoteService&lt;/wsa:Address&gt;
&lt;/wsa:ReplyTo&gt;
&lt;wsa:MessageID&gt;urn:uuid:879853A6871A66641C1179807380190&lt;/wsa:MessageID&gt;
&lt;wsa:Action&gt;http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence&lt;/wsa:Action&gt;
&lt;/soapenv:Header&gt;
&lt;soapenv:Body&gt;
&lt;wsrm:TerminateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"&gt;
&lt;wsrm:Identifier&gt;urn:uuid:546F6F33FB7D8BBE351179807372769&lt;/wsrm:Identifier&gt;
&lt;/wsrm:TerminateSequence&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p>
Note that although each of above messages are separate SOAP messages, in
most cases they will be exchanged in a single socket connection as HTTP
Keep-Alive header is used.
</p>
<h2>
<a name="Sample54" id="Sample54">Sample 54:</a>
</h2>
<pre xml:space="preserve">&lt;!-- demonstrates simple session less load balancing between 3 endpoints --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="main" onError="errorHandler"&gt;
&lt;in&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;loadbalance&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9001/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;suspendDurationOnFailure&gt;60&lt;/suspendDurationOnFailure&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9002/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;suspendDurationOnFailure&gt;60&lt;/suspendDurationOnFailure&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9003/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;suspendDurationOnFailure&gt;60&lt;/suspendDurationOnFailure&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;/loadbalance&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- Send the messages where they have been sent (i.e. implicit To EPR) --&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;sequence name="errorHandler"&gt;
&lt;makefault&gt;
&lt;code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/&gt;
&lt;reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/&gt;
&lt;/makefault&gt;
&lt;header name="To" action="remove"/&gt;
&lt;property name="RESPONSE" value="true"/&gt;
&lt;send/&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Demonstrate the simple load balancing among set of
endpoints</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start Synapse with sample configuration 54. (i.e. synapse -sample 54)
</p>
<p>
Deploy the LoadbalanceFailoverService by switching to &lt;synapse
installation directory&gt;/samples/axis2Server/src/LoadbalanceFailoverService
directory and running ant.
</p>
<p>
Start three instances of sample Axis2 server on HTTP ports 9001, 9002 and
9003 and give some unique names to each server.
</p>
<p>
Example commands to run sample Axis2 servers in Linux is listed below:
</p>
<pre xml:space="preserve">axis2Server.sh -http 9001 -https 9005 -name MyServer1
axis2Server.sh -http 9002 -https 9006 -name MyServer2
axis2Server.sh -http 9003 -https 9007 -name MyServer3</pre>
<p>
Now we are done with setting up the environment for load balance sample.
Start the load balance and failover client using the following command:
</p>
<pre xml:space="preserve">ant loadbalancefailover -Di=100</pre>
<p>
This client sends 100 requests to the LoadbalanceFailoverService through
Synapse. Synapse will distribute the load among the three endpoints
mentioned in the configuration in round robin manner.
LoadbalanceFailoverService appends the name of the server to the response,
so that client can determine which server has processed the message. If
you examine the console output of the client, you can see that requests
are processed by three servers as follows:
</p>
<pre xml:space="preserve">[java] Request: 1 ==&gt; Response from server: MyServer1
[java] Request: 2 ==&gt; Response from server: MyServer2
[java] Request: 3 ==&gt; Response from server: MyServer3
[java] Request: 4 ==&gt; Response from server: MyServer1
[java] Request: 5 ==&gt; Response from server: MyServer2
[java] Request: 6 ==&gt; Response from server: MyServer3
[java] Request: 7 ==&gt; Response from server: MyServer1
...</pre>
<p>
Now run the client without the -Di=100 parameter to send infinite
requests. While running the client shutdown the server named MyServer1.
You can observe that requests are only distributed among MyServer2 and
MyServer3 after shutting down MyServer1. Console output before and after
shutting down MyServer1 is listed below (MyServer1 was shutdown after
request 63):
</p>
<pre xml:space="preserve">...
[java] Request: 61 ==&gt; Response from server: MyServer1
[java] Request: 62 ==&gt; Response from server: MyServer2
[java] Request: 63 ==&gt; Response from server: MyServer3
[java] Request: 64 ==&gt; Response from server: MyServer2
[java] Request: 65 ==&gt; Response from server: MyServer3
[java] Request: 66 ==&gt; Response from server: MyServer2
[java] Request: 67 ==&gt; Response from server: MyServer3
...</pre>
<p>
Now restart MyServer1. You can observe that requets will be again sent to
all three servers roughly after 60 seconds. This is because we have
specified &lt;suspendDurationOnFailure&gt; as 60 seconds in the
configuration. Therefore, load balance endpoint will suspend any failed
child endpoint only for 60 seconds after detecting the failure.
</p>
<h2>
<a name="Sample55" id="Sample55">Sample 55:</a>
</h2>
<pre xml:space="preserve">&lt;!-- Demontrates failover sending among 3 endpoints. --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="main" onError="errorHandler"&gt;
&lt;in&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;failover&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9001/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;suspendDurationOnFailure&gt;60&lt;/suspendDurationOnFailure&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9002/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;suspendDurationOnFailure&gt;60&lt;/suspendDurationOnFailure&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9003/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;suspendDurationOnFailure&gt;60&lt;/suspendDurationOnFailure&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;/failover&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- Send the messages where they have been sent (i.e. implicit To EPR) --&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;sequence name="errorHandler"&gt;
&lt;makefault&gt;
&lt;code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/&gt;
&lt;reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/&gt;
&lt;/makefault&gt;
&lt;header name="To" action="remove"/&gt;
&lt;property name="RESPONSE" value="true"/&gt;
&lt;send/&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Demonstrate the failover sending</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start Synapse with sample configuration 55 (i.e. synapse -sample 55)
</p>
<p>
Deploy the LoadbalanceFailoverService and start three instances of sample
Axis2 server as mentioned in sample 54.
</p>
<p/>
<p>
Above configuration sends messages with the failover behavior. Initially
the server at port 9001 is treated as primary and other two are treated as
back ups. Messages are always directed only to the primary server. If the
primary server has failed, next listed server is selected as the primary.
Thus, messages are sent successfully as long as there is at least one
active server. To test this, run the loadbalancefailover client to send
infinite requests as follows:
</p>
<pre xml:space="preserve">ant loadbalancefailover</pre>
<p>
You can see that all requests are processed by MyServer1. Now shutdown
MyServer1 and inspect the console output of the client. You will observe
that all subsequent requests are processed by MyServer2.
</p>
<p>
The console output with MyServer1 shutdown after request 127 is listed
below:
</p>
<pre xml:space="preserve">...
[java] Request: 125 ==&gt; Response from server: MyServer1
[java] Request: 126 ==&gt; Response from server: MyServer1
[java] Request: 127 ==&gt; Response from server: MyServer1
[java] Request: 128 ==&gt; Response from server: MyServer2
[java] Request: 129 ==&gt; Response from server: MyServer2
[java] Request: 130 ==&gt; Response from server: MyServer2
...</pre>
<p>
You can keep on shutting down servers like this. Client will get a
response till you shutdown all listed servers. Once all servers are
shutdown, the error sequence is activated and a fault message is sent to
the client as follows:
</p>
<pre xml:space="preserve">[java] COULDN'T SEND THE MESSAGE TO THE SERVER.</pre>
<p>
Once a server is detected as failed, it will be added to the active
servers list again after 60 seconds (specified in &lt;suspendDurationOnFailure&gt;
in the configuration). Therefore, if you have restarted any of the stopped
servers and shutdown all other servers, messages will be directed to the
newly started server.
</p>
<h2>
<a name="Sample56" id="Sample56">Sample 56:</a>
</h2>
<pre xml:space="preserve">&lt;!-- Demontrates session affinity load balancing between 3 endpoints. We are using client
initiated session for this sample. --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="main" onError="errorHandler"&gt;
&lt;in&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;!-- specify the session as the simple client session provided by Synapse for
testing purpose --&gt;
<strong>&lt;session type="simpleClientSession"/&gt;</strong>
&lt;loadbalance&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9001/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9002/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9003/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;/loadbalance&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- Send the messages where they have been sent (i.e. implicit To EPR) --&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;sequence name="errorHandler"&gt;
&lt;makefault&gt;
&lt;code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/&gt;
&lt;reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/&gt;
&lt;/makefault&gt;
&lt;header name="To" action="remove"/&gt;
&lt;property name="RESPONSE" value="true"/&gt;
&lt;send/&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Demonstrate the load balancing with session affinity
using client initiated sessions</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start Synapse with sample configuration 56 (i.e. synapse -sample 56).
</p>
<p>
Deploy the LoadbalanceFailoverService and start three instances of the
sample Axis2 server as in sample 54.
</p>
<p/>
<p>
Above configuration is same as the load balancing configuration in sample
54, except that the session type is specified as "simpleClientSession".
This is a client initiated session, which means that the client generates
the session identifier and send it to with each request. In this sample
session type, client adds a SOAP header named ClientID containing the
identifier of the client. Synapse binds this ID with a server on the first
request and sends all seccessive requests containing that ID to the same
server. Now switch to samples/axis2Client directory and run the client
using the following command to check this in action.
</p>
<pre xml:space="preserve">ant loadbalancefailover -Dmode=session</pre>
<p>
In the session mode, client continuesly sends requests with three diferent
client (session) IDs. One ID is selected among these three IDs for each
request randomly. Then client prints the session ID with the responded
server for each request. Client output for the first 10 requests are shown
below.
</p>
<pre xml:space="preserve">[java] Request: 1 Session number: 1 Response from server: MyServer3
[java] Request: 2 Session number: 2 Response from server: MyServer2
[java] Request: 3 Session number: 0 Response from server: MyServer1
[java] Request: 4 Session number: 2 Response from server: MyServer2
[java] Request: 5 Session number: 1 Response from server: MyServer3
[java] Request: 6 Session number: 2 Response from server: MyServer2
[java] Request: 7 Session number: 2 Response from server: MyServer2
[java] Request: 8 Session number: 1 Response from server: MyServer3
[java] Request: 9 Session number: 0 Response from server: MyServer1
[java] Request: 10 Session number: 0 Response from server: MyServer1
... </pre>
<p>
You can see that session number 0 is always directed to the server named
MyServer1. That means session number 1 is bound to MyServer3. Similarly
session 1 and 2 are bound to MyServer3 and MyServer2 respectively.
</p>
<h2>
<a name="Sample57" id="Sample57">Sample 57:</a>
</h2>
<pre xml:space="preserve">&lt;!-- Demontrates the session affinity load balancing between fail over endpoints. If endpoint servers
maintain session specific data, such data have to replicated among the failover endpoints. --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="main" onError="errorHandler"&gt;
&lt;in&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;!-- specify the session as the simple client session provided by Synapse for
testing purpose --&gt;
<strong>&lt;session type="simpleClientSession"/&gt;</strong>
&lt;loadbalance&gt;
&lt;endpoint&gt;
&lt;failover&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9001/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9002/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;/failover&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;failover&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9003/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9004/soap/LBService1"&gt;
&lt;enableAddressing/&gt;
&lt;/address&gt;
&lt;/endpoint&gt;
&lt;/failover&gt;
&lt;/endpoint&gt;
&lt;/loadbalance&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- Send the messages where they have been sent (i.e. implicit To EPR) --&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;sequence name="errorHandler"&gt;
&lt;makefault&gt;
&lt;code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/&gt;
&lt;reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/&gt;
&lt;/makefault&gt;
&lt;header name="To" action="remove"/&gt;
&lt;property name="RESPONSE" value="true"/&gt;
&lt;send/&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Demonstrate the session affinity based load
balancing with failover capability</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start Synapse with sample configuration 57 (i.e. synapse -sample 57).
</p>
<p>
Deploy the LoadbalanceFailoverService and start four sample Axis2 servers
on http ports 9001, 9002, 9003 and 9004 respectively (make sure to specify
unconflicting https ports).
</p>
<p/>
<p>
This configuration also uses "simpleClientSession" to bind sessions as in
the previous sample. But failover endpoints are specified as the child
endpoints of the load balance endpoint. Therefore sessions are bound to
the failover endpoints. Session information has to be replicated among the
servers listed under each failover endpoint using some clustering
mechanism. Therefore, if one endpoint bound to a session failed,
successive requets for that session will be directed to the next endpoint
in that failover group. Run the client using the following command to
observe this behavoir.
</p>
<pre xml:space="preserve">ant loadbalancefailover -Dmode=session</pre>
<p>
You can see a client output as shown below.
</p>
<pre xml:space="preserve">...
[java] Request: 222 Session number: 0 Response from server: MyServer1
[java] Request: 223 Session number: 0 Response from server: MyServer1
[java] Request: 224 Session number: 1 Response from server: MyServer1
[java] Request: 225 Session number: 2 Response from server: MyServer3
[java] Request: 226 Session number: 0 Response from server: MyServer1
[java] Request: 227 Session number: 1 Response from server: MyServer1
[java] Request: 228 Session number: 2 Response from server: MyServer3
[java] Request: 229 Session number: 1 Response from server: MyServer1
[java] Request: 230 Session number: 1 Response from server: MyServer1
[java] Request: 231 Session number: 2 Response from server: MyServer3
...</pre>
<p>
Note that session 0 is always directed to MyServer1 and session 1 is
directed to MyServer3. No requests are directed to MyServer2 and MyServer4
as they are kept as backups by failover endpoints. Now shutdown the server
named MyServer1 while running the sample. You will observer that all
successive requests for session 0 is now directed to MyServer2, which is
the backup server for MyServer1's group. This is shown below, where
MyServer1 was shutdown after the request 534.
</p>
<pre xml:space="preserve">...
[java] Request: 529 Session number: 2 Response from server: MyServer3
[java] Request: 530 Session number: 1 Response from server: MyServer1
[java] Request: 531 Session number: 0 Response from server: MyServer1
[java] Request: 532 Session number: 1 Response from server: MyServer1
[java] Request: 533 Session number: 1 Response from server: MyServer1
[java] Request: 534 Session number: 1 Response from server: MyServer1
[java] Request: 535 Session number: 0 Response from server: MyServer2
[java] Request: 536 Session number: 0 Response from server: MyServer2
[java] Request: 537 Session number: 0 Response from server: MyServer2
[java] Request: 538 Session number: 2 Response from server: MyServer3
[java] Request: 539 Session number: 0 Response from server: MyServer2
...</pre>
<h2>
<a name="Sample60" id="Sample60">Sample 60:</a>
</h2>
<pre xml:space="preserve">&lt;!-- demonstrates wsdl endpoint --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="main"&gt;
&lt;in&gt;
&lt;send&gt;
&lt;!-- get epr from the given wsdl --&gt;
&lt;endpoint&gt;
&lt;wsdl uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl" service="SimpleStockQuoteService" port="SimpleStockQuoteServiceSOAP11port_http"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Demonstrate the use of WSDL endpoints</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start the Synapse configuration numbered 60 (i.e. synapse -sample 60).
</p>
<p>
Deploy the SimpleStockQuoteService and start the sample Axis2 server.
</p>
<p>
This sample uses a WSDL endpoint inside the send mediator. WSDL endpoints
can extract endpoint's address from the given WSDL. As WSDL documents can
have many services and many ports inside each service, the service and
port of the required endpoint has to be specified. As with address
endpoints, QoS parameters for the endpoint can be specified inline in the
configuration. An excerpt taken from the sample_proxy_1.wsdl containing
the specified service and port is listed below.
</p>
<pre xml:space="preserve">&lt;wsdl:service name="SimpleStockQuoteService"&gt;
&lt;wsdl:port name="SimpleStockQuoteServiceSOAP11port_http"
binding="axis2:SimpleStockQuoteServiceSOAP11Binding"&gt;
&lt;soap:address location="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/wsdl:port&gt;
&lt;wsdl:port name="SimpleStockQuoteServiceSOAP12port_http"
binding="axis2:SimpleStockQuoteServiceSOAP12Binding"&gt;
&lt;soap12:address location="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/wsdl:port&gt;
&lt;/wsdl:service&gt;</pre>
<p>
Specified service and port refers to the endpoint address
"http://localhost:9000/soap/SimpleStockQuoteService" according to the
above WSDL. Now run the client using the below command.
</p>
<pre xml:space="preserve">ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080</pre>
<p>
Client will print the quote price for IBM received from the server running
on port 9000. Observe the Axis2 console and the Synapse console to verify
this behavoir.
</p>
<h1>
<a name="ProxyServices" id="ProxyServices">Proxy services</a>
</h1>
<h2>
<a name="Sample100" id="Sample100">Sample 100:</a>
</h2>
<pre xml:space="preserve">&lt;!-- introduction to Synapse proxy services --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;proxy name="StockQuoteProxy"&gt;
&lt;target&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Introduction to Synapse proxy services</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 100: i.e. synapse -sample 100<br/> Start the
Axis2 server and deploy the SimpleStockQuoteService if not already done
</p>
<p/>
<p>
Once Synapse starts, you could go to
http://localhost:8080/soap/StockQuoteProxy?wsdl and view the WSDL
generated for the proxy service defined in the configuration. This WSDL is
based on the source WSDL supplied in the proxy service definition, and is
updated to reflect the proxy service EPR.
</p>
<p>
Execute the stock quote client by requesting for a stock quote on the
proxy service as follows:
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy</pre>
<p>
An 'inSequence' or 'endpoint' or both of these would decide how the
message would be handled after the proxy service receives the message. In
the above example, the request received is forwarded to the sample service
hosted on Axis2. The 'outSequence' defines how the response is handled
before it is sent back to the client. By default, a proxy service is
exposed over all transports configured for Synapse, unless these are
specifically mentioned through the 'transports' attribute.
</p>
<h2>
<a name="Sample101" id="Sample101">Sample 101:</a>
</h2>
<pre xml:space="preserve">&lt;!-- using custom sequences for incoming and outgoing message mediation with proxy services --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="proxy_1"&gt;
&lt;send&gt;
&lt;endpoint&gt;&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/sequence&gt;
&lt;sequence name="out"&gt;
&lt;send/&gt;
&lt;/sequence&gt;
&lt;endpoint name="proxy_2_endpoint"&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;localEntry key="proxy_wsdl" src="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;proxy name="StockQuoteProxy1"&gt;
&lt;publishWSDL key="proxy_wsdl"/&gt;
&lt;target inSequence="proxy_1" outSequence="out"/&gt;
&lt;/proxy&gt;
&lt;proxy name="StockQuoteProxy2"&gt;
&lt;publishWSDL key="proxy_wsdl"/&gt;
&lt;target endpoint="proxy_2_endpoint" outSequence="out"/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Using custom sequences and endpoints for message
mediation with proxy services</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 101: i.e. synapse -sample 101<br/> Start the
Axis2 server and deploy the SimpleStockQuoteService if not already done
</p>
<p/>
<p>
This configuration creates two proxy services.. The first proxy service
'StockQuoteProxy1' uses the sequence named 'proxy_1' to process incoming
messages and the sequence named "out" to process outgoing responses. The
second proxy service 'StockQuoteProxy2' is set to directly forward
messages that are received to the endpoint named 'proxy_2_endpoint'
without any mediation.
</p>
<p>
You could send a stock quote request to each of these proxy services and
receive the reply generated by the actual service hosted on the Axis2
instance.
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy1<br/>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy2</pre>
<h2>
<a name="Sample102" id="Sample102">Sample 102:</a>
</h2>
<pre xml:space="preserve">&lt;!-- switching from https to REST/POX --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;proxy name="StockQuoteProxy" transports="https"&gt;
&lt;target&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="pox"/&gt;
&lt;/endpoint&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Switching transports and from SOAP to REST/POX</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Synapse
configuration numbered 102: i.e. synapse -sample 102
</p>
<p>
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
</p>
<p/>
<p>
This configuration demonstrates how a proxy service could be exposed on a
subset of available transports, and how it could switch from one transport
to another. This example exposes the created proxy service only on https,
and thus if the user tries to access it over http, would result in a
fault.
</p>
<pre xml:space="preserve">ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy
...
[java] org.apache.axis2.AxisFault: The service cannot be found for the endpoint reference (EPR) /soap/StockQuoteProxy</pre>
<p/>
<p>
Accessing this over https (ant stockquote
-Dtrpurl=https://localhost:8443/soap/StockQuoteProxy) causes the proxy
service to access the SimpleStockQuoteService on the sample Axis2 server
using REST/POX. This could be seen if the message exchange was captured
using TCPMon as follows. The REST/POX response is now transformed back
into a SOAP message and returned to the client.
</p>
<pre xml:space="preserve">POST http://localhost:9000/soap/SimpleStockQuoteService HTTP/1.1
Host: 127.0.0.1
SOAPAction: urn:getQuote
Content-Type: application/xml; charset=UTF-8;action="urn:getQuote";
Transfer-Encoding: chunked
Connection: Keep-Alive
User-Agent: Synapse-HttpComponents-NIO
75
&lt;m0:getQuote xmlns:m0="http://services.samples/xsd"&gt;
&lt;m0:request&gt;
&lt;m0:symbol&gt;IBM&lt;/m0:symbol&gt;
&lt;/m0:request&gt;
&lt;/m0:getQuote&gt;</pre>
<pre xml:space="preserve">HTTP/1.1 200 OK
Content-Type: application/xml; charset=UTF-8;action="http://services.samples/SimpleStockQuoteServicePortType/getQuoteResponse";
Date: Tue, 24 Apr 2007 14:42:11 GMT
Server: Synapse-HttpComponents-NIO
Transfer-Encoding: chunked
Connection: Keep-Alive
2b3
&lt;ns:getQuoteResponse xmlns:ns="http://services.samples/xsd"&gt;
&lt;ns:return&gt;
&lt;ns:change&gt;3.7730036841862384&lt;/ns:change&gt;
&lt;ns:earnings&gt;-9.950236235550818&lt;/ns:earnings&gt;
&lt;ns:high&gt;-80.23868444613285&lt;/ns:high&gt;
&lt;ns:last&gt;80.50750970812187&lt;/ns:last&gt;
&lt;ns:lastTradeTimestamp&gt;Tue Apr 24 20:42:11 LKT 2007&lt;/ns:lastTradeTimestamp&gt;
&lt;ns:low&gt;-79.67368355714606&lt;/ns:low&gt;
&lt;ns:marketCap&gt;4.502043663670823E7&lt;/ns:marketCap&gt;
&lt;ns:name&gt;IBM Company&lt;/ns:name&gt;
&lt;ns:open&gt;-80.02229531286982&lt;/ns:open&gt;
&lt;ns:peRatio&gt;25.089295161182022&lt;/ns:peRatio&gt;
&lt;ns:percentageChange&gt;4.28842665653824&lt;/ns:percentageChange&gt;
&lt;ns:prevClose&gt;87.98107059692451&lt;/ns:prevClose&gt;
&lt;ns:symbol&gt;IBM&lt;/ns:symbol&gt;
&lt;ns:volume&gt;19941&lt;/ns:volume&gt;
&lt;/ns:return&gt;&lt;/ns:getQuoteResponse&gt;</pre>
<p/>
<h2>
<a name="Sample103" id="Sample103">Sample 103:</a>
</h2>
<pre xml:space="preserve">&lt;!-- attaching service level WS-Security policies to proxy services --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;localEntry key="sec_policy" src="file:repository/conf/sample/resources/policy/policy_3.xml"/&gt;
&lt;proxy name="StockQuoteProxy"&gt;
&lt;target&gt;
&lt;inSequence&gt;
&lt;header name="wsse:Security" action="remove"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/inSequence&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;policy key="sec_policy"/&gt;
&lt;enableSec/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Using WS-Security signing and encryption with proxy
services through WS-Policy</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> You may also need to
download and install the unlimited strength policy files for your JDK
before using Apache Rampart (e.g. see
http://java.sun.com/javase/downloads/index_jdk5.jsp)
</p>
<p>
Start the Synapse configuration numbered 103: i.e. synapse -sample 103<br/>
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
</p>
<p/>
<p>
The proxy service expects to receive a signed and encrypted message as
specified by the security policy. Please see Apache Rampart and Axis2
documentation on the format of the policy file. The element 'engageSec'
specifies that Apache Rampart should be engaged on this proxy service.
Hence if Rampart rejects any request messages that does not conform to the
specified policy, those messages will never reach the 'inSequence' to be
processed. Since the proxy service is forwarding the received request to
the simple stock quote service that does not use WS-Security, we are
instructing Synapse to remove the wsse:Security header from the outgoing
message. To execute the client, send a stock quote request to the proxy
service, and sign and encrypt the request by specifying the client side
security policy as follows:
</p>
<pre xml:space="preserve">ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy -Dpolicy=./../../repository/conf/sample/resources/policy/client_policy_3.xml</pre>
<p>
By following through the debug logs or TCPMon output, you could see that
the request received by the proxy service was signed and encrypted. Also,
looking up the WSDL of the proxy service by requesting the
URLhttp://localhost:8080/soap/StockQuoteProxy?wsdl reveals the security
policy attachment to the supplied base WSDL. When sending the message to
the backend service, you could verify that the security headers were
removed, and that the response received does not use WS-Security, but that
the response being forwarded back to the client is signed and encrypted as
expected by the client.
</p>
<h2>
<a name="Sample104" id="Sample104">Sample 104:</a>
</h2>
<pre xml:space="preserve">&lt;!-- attaching service level WS-RM policies to proxy services --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;proxy name="StockQuoteProxy"&gt;
&lt;target&gt;
&lt;inSequence&gt;
&lt;header name="wsrm:SequenceAcknowledgement" action="remove"
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/&gt;
&lt;header name="wsrm:Sequence" action="remove"
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/inSequence&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;enableRM/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<strong>Objective: Demonstrate the reliable message exchange between the
client and Synapse using WS-ReliableMessaging (WS-RM)</strong>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Deploy the SimpleStockQuoteService in the sample Axis2 server and start it
on port 9000.
</p>
<p>
Start Synapse with the sample configuration number 104 (i.e. synapse
-sample 104).
</p>
<p/>
<p>
In the above configuration, a proxy service is created with WS-RM enabled
using the &lt;enableRM/&gt; tag. Therefore, this proxy service is capable
of communicating with a WS-RM client. It also removes the WS-RM headers in
the In Sequence before the message is sent to the back end server. This is
required as the reliable messaging is applicable only between the client
and Synapse. Now start the client with WS-RM as follows:
</p>
<pre xml:space="preserve">ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8081/soap/StockQuoteProxy -Dwsrm=true</pre>
<p>
In this case, client sends WS-RM enabled request to Synapse where Synapse
sends normal request to the server. This can be observed by examining the
wire level messages between the client and Synapse. These messages would
be similar to the wire level messages shown in sample 53. Each message
would perform a similar function to the messages discussed in sample 53.
</p>
<p/>
<h1>
<a name="Transport" id="Transport">Transports</a>
</h1>
<h2>
<a name="Sample110" id="Sample110">Sample 110:</a>
</h2>
<pre xml:space="preserve">&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;proxy name="StockQuoteProxy" transports="jms"&gt;
&lt;target&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Introduction to switching transports with proxy
services</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Axis2 server
and deploy the SimpleStockQuoteService (Refer steps above)<br/>
Download, install and start a JMS server, and configure Synapse to listen
on JMS (refer notes below)<br/> Start the Synapse configuration
numbered 110: i.e. synapse -sample 110<br/> For this example we would
use ActiveMQ as the JMS provider. Once ActiveMQ is installed and started
you should get a message as follows:
</p>
<pre xml:space="preserve">INFO BrokerService - ActiveMQ JMS Message Broker (localhost) started</pre>
<p>
You will now need to configure the Axis2 instance used by Synapse (not the
sample Axis2 server) to enable JMS support using the above provider. Refer
to the Axis2 documentation on setting up JMS for more details
(http://ws.apache.org/axis2/1_1/jms-transport.html). You will also need to
copy the ActiveMQ client jar files activeio-core-3.0-beta1.jar,
activemq-core-4.0-RC2.jar, geronimo-jms_1.1_spec-1.0.jar and
geronimo-j2ee-management_1.0_spec-1.0.jar into the lib directory to allow
Synapse to connect to the JMS provider.
</p>
<p>
For a default ActiveMQ v4.0 installation, you may uncomment the Axis2
transport listener configuration found at repository/conf/axis2.xml as
</p>
<pre xml:space="preserve">&lt;transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener"&gt; ...</pre>
<p>
Once you start the Synapse configuration and request for the WSDL of the
proxy service (http://localhost:8080/soap/StockQuoteProxy?wsdl) you will
notice that its exposed only on the JMS transport. This is because the
configuration specified this requirement in the proxy service definition.
</p>
<p>
Now lets send a stock quote request on JMS, using the dumb stock quote
client as follows:
</p>
<pre xml:space="preserve">ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/StockQuoteProxy -Djms_payload=MSFT</pre>
<p>
On the Synapse debug log you will notice that the JMS listener received
the request message as:
</p>
<pre xml:space="preserve">[JMSWorker-1] DEBUG ProxyServiceMessageReceiver -Proxy Service StockQuoteProxy received a new message...</pre>
<p>
Now if you examine the console running the sample Axis2 server, you will
see a message indicating that the server has accepted an order as follows:
</p>
<pre xml:space="preserve">Accepted order for : 16517 stocks of MSFT at $ 169.14622538721846</pre>
<p>
In this sample, client sends the request message to the proxy service
exposed in JMS in Synsape. Synapse forwards this message to the HTTP EPR
of the simple stock quote service hosted on the sample Axis2 server, and
returns the reply back to the client through a JMS temporary queue.
</p>
<p>
Note: It is possible to instruct a JMS proxy service to listen to an
already existing destination without creating a new one. To do this, use
the property elements on the proxy service definition to specify the
destination and connection factory etc.
</p>
<p>
e.g.
</p>
<pre xml:space="preserve">&lt;property name="transport.jms.Destination" value="dynamicTopics/something.TestTopic"/&gt;</pre>
<h2>
<a name="Sample111" id="Sample111">Sample 111:</a>
</h2>
<pre xml:space="preserve">&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;proxy name="StockQuoteProxy" transports="http"&gt;
&lt;target&gt;
&lt;endpoint&gt;
&lt;address uri="jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;amp;
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;amp;java.naming.provider.url=tcp://localhost:61616"/&gt;
&lt;/endpoint&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Demonstrate switching from HTTP to JMS</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Download, install and
start a JMS server
</p>
<p>
Configure sample Axis2 server for JMS (refer notes above)<br/> Start
the Axis2 server and deploy the SimpleStockQuoteService (see below)<br/>
Configure the Synase JMS transport (refer notes above - sample 110)<br/>
Start the Synapse configuration numbered 111: i.e. synapse -sample 111
</p>
<p>
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:
</p>
<pre xml:space="preserve">jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName=
QueueConnectionFactory&amp;java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;
java.naming.provider.url=tcp://localhost:61616</pre>
<p>
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.
</p>
<p>
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:
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dmode=placeorder -Dsymbol=MSFT</pre>
<p>
The sample Axis2 server console will print a message indicating that it
has accepted the order as follows:
</p>
<pre xml:space="preserve">Accepted order for : 18406 stocks of MSFT at $ 83.58806051152119</pre>
<h2>
<a name="Sample112" id="Sample112">Sample 112:</a>
</h2>
<p>
<strong>Objective: Demonstrate one way messaging / fireAndForget()</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Axis2 server
and deploy the SimpleStockQuoteService (Refer steps above)<br/> Start
the Synapse configuration numbered 1: i.e. synapse -sample 1
</p>
<p>
This example invokes the one-way 'placeOrder' operation on the
SimpleStockQuoteService using the custom client which uses the Axis2
ServiceClient.fireAndForget() API. To test this, use 'ant
-Dmode=placeorder...' and you will notice the one way message flowing
through Synapse into the sample Axis2 server instance, which reports the
acceptance of the order as follows:
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dmode=placeorder</pre>
<pre xml:space="preserve">SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733</pre>
<p>
If you send your client request through TCPmon, you will notice that the
SimpleStockQuoteService replies to Synapse with a HTTP 202 reply, and that
Synapse in-turn replies to the client with a HTTP 202 acknowledgement
</p>
<h2>
<a name="Sample113" id="Sample113">Sample 113:</a>
</h2>
<pre xml:space="preserve">&lt;!-- demonstrate JMS pure text, binary and POX message support --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;sequence name="text_proxy"&gt;
&lt;header name="Action" value="urn:placeOrder"/&gt;
&lt;script language="js"&gt;&lt;![CDATA[
var args = mc.getPayloadXML().toString().split(" ");
mc.setPayloadXML(
&lt;m:placeOrder xmlns:m="http://services.samples/xsd"&gt;
&lt;m:order&gt;
&lt;m:price&gt;{args[0]}&lt;/m:price&gt;
&lt;m:quantity&gt;{args[1]}&lt;/m:quantity&gt;
&lt;m:symbol&gt;{args[2]}&lt;/m:symbol&gt;
&lt;/m:order&gt;
&lt;/m:placeOrder&gt;);
]]&gt;&lt;/script&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/sequence&gt;
&lt;sequence name="mtom_proxy"&gt;
&lt;header name="Action" value="urn:oneWayUploadUsingMTOM"/&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/MTOMSwASampleService" optimize="mtom"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/sequence&gt;
&lt;sequence name="pox_proxy"&gt;
&lt;header name="Action" value="urn:placeOrder"/&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="soap"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/sequence&gt;
&lt;sequence name="out"&gt;
&lt;send/&gt;
&lt;/sequence&gt;
&lt;proxy name="JMSFileUploadProxy" transports="jms"&gt;
&lt;target inSequence="mtom_proxy" outSequence="out"/&gt;
&lt;parameter name="transport.jms.Wrapper"&gt;{http://services.samples/xsd}element&lt;/parameter&gt;
&lt;/proxy&gt;
&lt;proxy name="JMSTextProxy" transports="jms"&gt;
&lt;target inSequence="text_proxy" outSequence="out"/&gt;
&lt;parameter name="transport.jms.Wrapper"&gt;{http://services.samples/xsd}text&lt;/parameter&gt;
&lt;/proxy&gt;
&lt;proxy name="JMSPoxProxy" transports="jms"&gt;
&lt;target inSequence="pox_proxy" outSequence="out"/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Pure POX/Text and Binary JMS Proxy services -
including MTOM</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Configure JMS for
Synapse (Refer notes)<br/> Start the Synapse configuration numbered
113: i.e. synapse -sample 113<br/> Start the Axis2 server and deploy
the SimpleStockQuoteService and the MTOMSwASampleService if not already
done
</p>
<p/>
<p>
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 "&lt;price&gt; &lt;qty&gt;
&lt;symbol&gt;". 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.
</p>
<p/>
<p>
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
</p>
<pre xml:space="preserve">ant jmsclient -Djms_type=text -Djms_payload="12.33 1000 ACP" -Djms_dest=dynamicQueues/JMSTextProxy</pre>
<p>
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.
</p>
<pre xml:space="preserve">[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Body&gt;&lt;axis2ns1:text xmlns:axis2ns1="http://services.samples/xsd"&gt;12.33 1000 ACP&lt;/axis2ns1:text&gt;&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p>
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.
</p>
<pre xml:space="preserve">[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 :
&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;&lt;soapenv:Body&gt;
&lt;m:placeOrder xmlns:m="http://services.samples/xsd"&gt;&lt;m:order&gt;&lt;m:price&gt;12.33&lt;/m:price&gt;&lt;m:quantity&gt;1000&lt;/m:quantity&gt;&lt;m:symbol&gt;ACP&lt;/m:symbol&gt;&lt;/m:order&gt;
&lt;/m:placeOrder&gt;&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;</pre>
<p>
The sample Axis2 server would now accept the one way message and issue the
following message:
</p>
<pre xml:space="preserve">Wed Apr 25 19:50:56 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 1000 stocks of ACP at $ 12.33</pre>
<p/>
<p>
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:
</p>
<pre xml:space="preserve">ant jmsclient -Djms_type=binary -Djms_dest=dynamicQueues/JMSFileUploadProxy -Djms_payload=./../../repository/conf/sample/resources/mtom/asf-logo.gif</pre>
<p>
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:
</p>
<pre xml:space="preserve">[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Proxy Service JMSFileUploadProxy received a new message...
...
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soapenv:Body&gt;&lt;axis2ns1:element xmlns:axis2ns1="http://services.samples/xsd"&gt;R0lGODlhgw...AAOw==&lt;/axis2ns1:element&gt;&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p>
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.
</p>
<pre xml:space="preserve">Wrote to file : /tmp/mtom-60319.gif</pre>
<p/>
<p>
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:
</p>
<pre xml:space="preserve">ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/JMSPoxProxy -Djms_payload=MSFT</pre>
<p>
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'.
</p>
<p/>
<pre xml:space="preserve">[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Proxy Service JMSPoxProxy received a new message...
...
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;&lt;soapenv:Body&gt;&lt;m:placeOrder xmlns:m="http://services.samples/xsd"&gt;
&lt;m:order&gt;
&lt;m:price&gt;172.39703010684752&lt;/m:price&gt;
&lt;m:quantity&gt;19211&lt;/m:quantity&gt;
&lt;m:symbol&gt;MSFT&lt;/m:symbol&gt;
&lt;/m:order&gt;
&lt;/m:placeOrder&gt;&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;
[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 :
&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;&lt;soapenv:Body&gt;&lt;m:placeOrder xmlns:m="http://services.samples/xsd"&gt;
&lt;m:order&gt;
&lt;m:price&gt;172.39703010684752&lt;/m:price&gt;
&lt;m:quantity&gt;19211&lt;/m:quantity&gt;
&lt;m:symbol&gt;MSFT&lt;/m:symbol&gt;
&lt;/m:order&gt;
&lt;/m:placeOrder&gt;&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;
[JMSWorker-1] DEBUG Axis2FlexibleMEPClient - sending [add = false] [sec = false] [rm = false] [ mtom = false] [ swa = false] [ force soap=true; pox=false] [ to null] </pre>
<p>
The sample Axis2 server displays a successful message on the receipt of
the message as:
</p>
<pre xml:space="preserve">Wed Apr 25 20:24:50 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 19211 stocks of MSFT at $ 172.39703010684752</pre>
<h2>
<a name="Sample114" id="Sample114">Sample 114:</a>
</h2>
<pre xml:space="preserve">&lt;!-- one-way message bridging between JMS to HTTP and sending a 202 Accepted --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;proxy name="JMStoHTTPStockQuoteProxy" transports="jms"&gt;
&lt;target&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9001/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;/proxy&gt;
&lt;proxy name="OneWayProxy" transports="http"&gt;
&lt;target&gt;
&lt;inSequence&gt;
&lt;log level="full"/&gt;
&lt;property name="RESPONSE" value="true"/&gt;
&lt;header name="To" value="http://www.w3.org/2005/08/addressing/anonymous"/&gt;
&lt;property name="SC_ACCEPTED" value="true" scope="axis2"/&gt;
&lt;send/&gt;
&lt;/inSequence&gt;
&lt;outSequence&gt;
&lt;send/&gt;
&lt;/outSequence&gt;
&lt;/target&gt;
&lt;publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/&gt;
&lt;/proxy&gt;
&lt;/definitions&gt;</pre>
<p>
<strong>Objective: Demonstrate one way message bridging from JMS to
http and replying with a http 202 Accepted response</strong>
</p>
<p>
<strong>Pre-Requisites:</strong><br/> Start the Axis2 server
and deploy the SimpleStockQuoteService if not already done
</p>
<p>
Start the Synapse configuration numbered 114: i.e. synapse -sample 114
</p>
<p/>
<p>
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.
</p>
<pre xml:space="preserve">ant stockquote -Dmode=placeorder -Dtrpurl="jms:/JMStoHTTPStockQuoteProxy?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;java.naming.provider.url=tcp://localhost:61616"</pre>
<pre xml:space="preserve">SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733</pre>
<p>
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
</p>
<pre xml:space="preserve">ant stockquote -Dmode=placeorder -Dtrpurl=http://localhost:8080/soap/OneWayProxy</pre>
<pre xml:space="preserve">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</pre>
<h1>
<a name="ExtensionMediators" id="ExtensionMediators">Extension
mediators</a>
</h1>
<p>
Synapse supports Mediators implemented in a variety of scripting languages
such as JavaScript, Python or Ruby. Implementing a Mediator with a script
language can have advantages over using the built in Synapse Mediator
types or implementing a custom Java class Mediator. Script Mediators have
all the flexibility of a class Mediator with access to the Synapse
MessageContext and SynapseEnvironment APIs, and the ease of use and
dynamic nature of scripting languages allows rapid development and
prototyping of custom mediators. An additional benefit of some scripting
languages is that they have very simple and elegant XML manipulation
capabilities, for example JavaScript E4X or Ruby REXML, so this makes them
well suited for use in the Synapse mediation environment.
</p>
<h2>
<a name="ScriptSetup" id="ScriptSetup">Configuring Synapse for Script
Mediator support</a>
</h2>
<p>
The Synapse Script Mediator is a Synapse extension, and thus all
pre-requisites 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 detailed in the <a
href="Synapse_Samples_Setup.html#script">Samples Setup guide</a>.
</p>
<h2>
<a name="Sample500" id="Sample500">Sample 500:</a>
</h2>
<pre xml:space="preserve">&lt;!-- Introduction to the script mediator --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;localEntry key="stockquoteScript" src="file:repository/conf/sample/resources/script/stockquoteTransformRequest.js"/&gt;
&lt;in&gt;
&lt;!-- transform the custom quote request into a standard quote request expected by the service --&gt;
&lt;script language="js" key="stockquoteScript" function="transformRequest"/&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- transform the standard response back into the custom format the client expects --&gt;
&lt;script language="js" key="stockquoteScript" function="transformResponse"/&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/definitions&gt; </pre>
<p/>
<pre xml:space="preserve">&lt;x&gt;&lt;![CDATA[
function transformRequest(mc) {
var symbol = mc.getPayloadXML()..*::Code.toString();
mc.setPayloadXML(
&lt;m:getQuote xmlns:m="http://services.samples/xsd"&gt;
&lt;m:request&gt;
&lt;m:symbol&gt;{symbol}&lt;/m:symbol&gt;
&lt;/m:request&gt;
&lt;/m:getQuote&gt;);
}
function transformResponse(mc) {
var symbol = mc.getPayloadXML()..*::symbol.toString();
var price = mc.getPayloadXML()..*::last.toString();
mc.setPayloadXML(
&lt;m:CheckPriceResponse xmlns:m="http://www.apache-synapse.org/test"&gt;
&lt;m:Code&gt;{symbol}&lt;/m:Code&gt;
&lt;m:Price&gt;{price}&lt;/m:Price&gt;
&lt;/m:CheckPriceResponse&gt;);
}
]]&gt;&lt;/x&gt;</pre>
<p>
<strong>Objective: Introduction to script mediators</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start the Synapse configuration numbered 500: i.e. synapse -sample 500<br/>
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
</p>
<p/>
<p>
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 as follows to issue a custom quote client:
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote</pre>
<p>
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 back and sent back to the client.
</p>
<h2>
<a name="Sample501" id="Sample501">Sample 501:</a>
</h2>
<pre xml:space="preserve">&lt;!-- introduction to inline script mediation --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;in&gt;
&lt;!-- transform the custom quote request into a standard quote requst expected by the service --&gt;
&lt;script language="js"&gt;&lt;![CDATA[
var symbol = mc.getPayloadXML()..*::Code.toString();
mc.setPayloadXML(
&lt;m:getQuote xmlns:m="http://services.samples/xsd"&gt;
&lt;m:request&gt;
&lt;m:symbol&gt;{symbol}&lt;/m:symbol&gt;
&lt;/m:request&gt;
&lt;/m:getQuote&gt;);
]]&gt;&lt;/script&gt;
&lt;send&gt;
&lt;endpoint&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- transform the standard response back into the custom format the client expects --&gt;
&lt;script language="js"&gt;&lt;![CDATA[
var symbol = mc.getPayloadXML()..*::symbol.toString();
var price = mc.getPayloadXML()..*::last.toString();
mc.setPayloadXML(
&lt;m:CheckPriceResponse xmlns:m="http://www.apache-synapse.org/test"&gt;
&lt;m:Code&gt;{symbol}&lt;/m:Code&gt;
&lt;m:Price&gt;{price}&lt;/m:Price&gt;
&lt;/m:CheckPriceResponse&gt;);
]]&gt;&lt;/script&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: Introduction to in-line script mediation</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start the Synapse configuration numbered 501: i.e. synapse -sample 501<br/>
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
</p>
<p/>
<p>
This example is functionally equivalent to sample # 500 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.
</p>
<p/>
<h2>
<a name="Sample502" id="Sample502">Sample 502</a>
</h2>
<pre xml:space="preserve">&lt;!-- accessing the Synapse APIs from scripting languages --&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;in&gt;
&lt;!-- change the MessageContext into a response and set a response payload --&gt;
&lt;script language="js"&gt;&lt;![CDATA[
mc.setTo(mc.getReplyTo());
mc.setProperty("RESPONSE", "true");
mc.setPayloadXML(
&lt;ns:getQuoteResponse xmlns:ns="http://services.samples/xsd"&gt;
&lt;ns:return&gt;
&lt;ns:last&gt;99.9&lt;/ns:last&gt;
&lt;/ns:return&gt;
&lt;/ns:getQuoteResponse&gt;);
]]&gt;&lt;/script&gt;
&lt;/in&gt;
&lt;send/&gt;
&lt;/definitions&gt; </pre>
<p>
<strong>Objective: Accessing the Synapse APIs from scripting languages</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
Start the Synapse configuration numbered 502: i.e. bin/synapse -sample 502<br/>
</p>
<p/>
<p>
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.
</p>
<pre xml:space="preserve">ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
...
stockquote:
[java] Standard :: Stock price = $99.9</pre>
<h2>
<a name="Sample503" id="Sample503">Sample 503:</a>
</h2>
<pre xml:space="preserve">&lt;!-- Introduction to the script mediator with Ruby scripts--&gt;
&lt;definitions xmlns="http://ws.apache.org/ns/synapse"&gt;
&lt;localEntry key="stockquoteScript" src="file:repository/conf/sample/resources/script/stockquoteTransform.rb"/&gt;
&lt;in&gt;
&lt;!-- transform the custom quote request into a standard quote request expected by the service --&gt;
&lt;script language="rb" key="stockquoteScript" function="transformRequest"/&gt;
&lt;!-- send message to real endpoint referenced by name "stockquote" and stop --&gt;
&lt;send&gt;
&lt;endpoint name="stockquote"&gt;
&lt;address uri="http://localhost:9000/soap/SimpleStockQuoteService"/&gt;
&lt;/endpoint&gt;
&lt;/send&gt;
&lt;/in&gt;
&lt;out&gt;
&lt;!-- transform the standard response back into the custom format the client expects --&gt;
&lt;script language="rb" key="stockquoteScript" function="transformResponse"/&gt;
&lt;send/&gt;
&lt;/out&gt;
&lt;/definitions&gt; </pre>
<pre xml:space="preserve">&lt;x&gt;&lt;![CDATA[
require 'rexml/document'
include REXML
def transformRequest(mc)
newRequest= Document.new '&lt;m:getQuote xmlns:m="http://services.samples/xsd"&gt;'&lt;&lt;
'&lt;m:request&gt;&lt;m:symbol&gt;&lt;/m:symbol&gt;&lt;/m:request&gt;&lt;/m:getQuote&gt;'
newRequest.root.elements[1].elements[1].text = mc.getPayloadXML().root.elements[1].get_text
mc.setPayloadXML(newRequest)
end
def transformResponse(mc)
newResponse = Document.new '&lt;m:CheckPriceResponse xmlns:m="http://www.apache-synapse.org/test"&gt;&lt;m:Code&gt;' &lt;&lt;
'&lt;/m:Code&gt;&lt;m:Price&gt;&lt;/m:Price&gt;&lt;/m:CheckPriceResponse&gt;'
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
]]&gt;&lt;/x&gt;</pre>
<p>
<strong>Objective: Script mediators using Ruby</strong>
</p>
<p>
<strong>Pre-Requisites:</strong>
</p>
<p>
This sample uses Ruby so first setup support for this in Synapse as
described at <a href="#ScriptSetupRuby">Configuring JRuby</a>.
</p>
<p>
Start the Synapse configuration numbered 503: i.e. bin/synapse -sample 503<br/>
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
</p>
<p/>
<p>
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.
</p>
<p/>