Running the WSO2 Enterprise Service Bus (ESB) v1.6 Samples
While the Samples Setup Guide
document above gives you a generic description on how to set up and and
run the WSO2 ESB samples, this document takes each sample, one by one and
discusses the objective of the sample, its prerequisites, and its expected
behavior when the sample is built.
Note: The ESB configurations listed below, with
each sample, is the raw source XML serialization of the sample
configuration. This may be viewed graphically through the WSO2 ESB
administration console after logging into the console.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- log all attributes of messages passing through -->
<log level="full"/>
<!-- Send the messageto implicit destination -->
<send/>
</definitions>
Objective: Introduction to ESB. Shows how a message could be
made to pass through ESB and logged before it is
delivered to its ultimate receiver.
The Stock quote client can operate in the following modes for this
example.
Smart Client mode
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
Using ESB as a HTTP Proxy
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dprxurl=http://localhost:8080/
Gateway Mode / Dumb Client
See sample # 1
Prerequisites: Start the Synapse
configuration numbered 0: e.g. wso2-esb -sample 0 Start the Axis2
server and deploy the SimpleStockQuoteService if not already deployed
Execute the Smart Client
By tracing the execution of ESB with the log output level set to DEBUG,
you will see the client request arriving at ESB with a WS-Addressing 'To'
set to EPR http://localhost:9000/soap/SimpleStockQuoteService. The ESB
engine logs the message at the "full" log level (i.e. all the message
headers and the body) then sends the message to its implicit 'To' address
which is http://localhost:9000/soap/SimpleStockQuoteService. You will see
a message in the Axis2 server console confirming that the message got
routed to the sample server and the sample service hosted at the sample
server generating a stock quote for the requested symbol.
Sat Nov 18 21:01:23 IST 2006 SimpleStockQuoteService :: Generating quote for : IBM
The response message generated by the service is again received by ESB,
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.
Standard :: Stock price = $95.26454380258552
Execute the Proxy Client
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 ESB as the http proxy.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- filtering of messages with XPath and regex matches -->
<filter source="get-property('To')" regex=".*/StockQuote.*">
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
<drop/>
</filter>
<send/>
</definitions>
Objective: Introduction to simple content based routing. Shows
how a message could be made to pass through ESB using the Dumb Client
mode, where ESB acts as a gateway to accept all messages and then perform
mediation and routing based on message properties or content.Prerequisites: Start the Synapse
configuration numbered 1: i.e. wso2-esb -sample 1 Start the Axis2
server and deploy the SimpleStockQuoteService if not already deployed
Execute the Dumb Client as:
ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuote
This time you will see ESB receiving a message for which ESB was set as
the ultimate receiver of the message. Based on the 'To' EPR of
http://localhost:8080/soap/StockQuote, ESB performs a match to the path
'/StockQuote' and as the request matches the XPath expression of the
filter mediator, the filter mediator's child mediators execute. This sends
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
response back to the client.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<switch source="//m0:getQuote/m0:request/m0:symbol" xmlns:m0="http://services.samples/xsd">
<case regex="IBM">
<!-- the property mediator sets a local property on the *current* message -->
<property name="symbol" value="Great stock - IBM"/>
</case>
<case regex="MSFT">
<property name="symbol" value="Are you sure? - MSFT"/>
</case>
<default>
<!-- it is possible to assign the result of an XPath expression as well -->
<property name="symbol"
expression="fn:concat('Normal Stock - ', //m0:getQuote/m0:request/m0:symbol)"
xmlns:m0="http://services.samples/xsd"/>
</default>
</switch>
<log level="custom">
<!-- 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) -->
<property name="symbol" expression="get-property('symbol')"/>
<!-- the get-property() function supports the implicit message headers To/From/Action/FaultTo/ReplyTo -->
<property name="epr" expression="get-property('To')"/>
</log>
<!-- Send the messages where they are destined to (i.e. the 'To' EPR of the message) -->
<send/>
</definitions>
Objective: Introduce switch-case mediator and writing and
reading of local properties set on a message instancePrerequisites: Start the Synapse
configuration numbered 2: i.e. wso2-esb -sample 2 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done.
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 requested, viewing the mediation logs you will see that the case
statements' first case for 'IBM' is 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.
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService
-Dtrpurl=http://localhost:8080/ -Dsymbol=IBM
INFO LogMediator - symbol = Great stock - IBM, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService
-Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT
INFO LogMediator - symbol = Are you sure? - MSFT, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- define a string resource entry to the local registry -->
<localEntry key="version">0.1</localEntry>
<!-- define a reuseable endpoint definition -->
<endpoint name="simple">
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
<!-- define a reusable sequence -->
<sequence name="stockquote">
<!-- log the message using the custom log level. illustrates custom properties for log -->
<log level="custom">
<property name="Text" value="Sending quote request"/>
<property name="version" expression="get-property('version')"/>
<property name="direction" expression="get-property('direction')"/>
</log>
<!-- send message to real endpoint referenced by key "simple" endpoint definition -->
<send>
<endpoint key="simple"/>
</send>
</sequence>
<sequence name="main">
<in>
<property name="direction" value="incoming"/>
<sequence key="stockquote"/>
</in>
<out>
<send/>
</out>
</sequence>
</definitions>
Objective: Illustrates local registry entry definitions,
reusable endpoints and sequencesPrerequisites: Start the Synapse
configuration numbered 3: i.e. wso2-esb -sample 3 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
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 <definitions> tags.
This is the recommended and also a better 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" is executed. Then for the incoming message flow the <in>
mediator executes, and it calls into the sequence named "stockquote".
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
As the "stockquote" sequence executes, the log mediator dumps a simple
text/string property, result of an XPath evaluation, that picks up the key
named "version", and a second result of an XPath evaluation that picks up
a local message property set previously by the <property> 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 which is visible to all messages that pass through ESB.
[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
Objective: Introduction to error handling with the 'fault'
sequencePrerequisites: Start the Synapse
configuration numbered 4: i.e. wso2-esb -sample 4 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
When the IBM stock quote is requested, the configuration routes it to the
defined inline endpoint, which routes the message to the
SimpleStockQuoteService on the local Axis2 instance. Hence a valid
response message is shown at the client.
If you lookup a stock quote for 'MSFT', ESB is instructed to route the
message to the endpoint defined as the 'bogus' endpoint, which does not
exist. ESB 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 ESB cannot find an error handler, it looks for a
sequence named 'fault'. Thus the 'fault' sequence can be seen executing,
and writing the generic error message to the logs.
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT
[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 <fault> :: 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
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, you could see the proper error handler invocation and
the custom error message printed as follows.
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <sunSequence> :: mediate()
[HttpServerWorker-1] DEBUG SequenceMediator - Setting the onError handler for the sequence
[HttpServerWorker-1] DEBUG AbstractListMediator - Implicit Sequence <SequenceMediator> :: 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 <sunErrorHandler> :: mediate()
[HttpServerWorker-1] DEBUG AbstractListMediator - Implicit Sequence <SequenceMediator> :: 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
Objective: Makefault mediator and sending back error responses
Prerequisites: Start the Synapse
configuration numbered 5: i.e. wso2-esb -sample 5 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
When the MSFT stock quote is requested, an unknown host exception would be
generated. A connection refused exception would be generated for the SUN
stock request. This error message is captured and returned to the original
client as a SOAP fault in this example.
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT
Objective: Introduction to header, in (out) mediatorsPrerequisites: Start the Synapse
configuration numbered 6: i.e. wso2-esb -sample 6 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
In this example we use the stockquote client in the dumb client mode,
setting the 'To' EPR of the message to ESB. 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.
Objective: Introduction to local (static) registry entries and
the validate mediatorPrerequisites: Start the Synapse
configuration numbered 7: i.e. wso2-esb -sample 7 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
This example shows how a static XML fragment could be made available to
the ESB local registry. Resources defined in 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'.
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 validatation fails it invokes the 'on-fail' sequence of mediators.
If you send a stockquote request using 'ant stockquote ...' you will get a
fault back with the 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)
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- the SimpleURLRegistry allows access to a URL based registry (e.g. file:/// or http://) -->
<registry provider="org.apache.synapse.registry.url.SimpleURLRegistry">
<!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
<parameter name="root">file:./repository/conf/sample/resources/</parameter>
<!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
<parameter name="cachableDuration">15000</parameter>
</registry>
<!-- define the request processing XSLT resource as a static URL source -->
<localEntry key="xslt-key-req" src="file:repository/conf/sample/resources/transform/transform.xslt"/>
<in>
<!-- transform the custom quote request into a standard quote requst expected by the service -->
<xslt key="xslt-key-req"/>
</in>
<out>
<!-- transform the standard response back into the custom format the client expects -->
<!-- the key is looked up in the remote registry and loaded as a 'dynamic' registry resource -->
<xslt key="transform/transform_back.xslt"/>
</out>
<send/>
</definitions>
Objective: Introduction to static and dynamic registry
resources and the XSLT mediatorPrerequisites: Start the Synapse
configuration numbered 8: i.e. wso2-esb -sample 8 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
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 make 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
higher preference and override the remote resource.
In this example you will notice the new 'registry' definition. ESB 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.
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.
Execute the custom quote client as 'ant stockquote -Dmode=customquote ...'
and analyze the the ESB debug log output
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote
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.
During the response processing you could see the SimpleURLRegistry
fetching the resource as shown by the log message below
[HttpClientWorker-1] INFO SimpleURLRegistry - ==> Repository fetch of resource with key : transform/transform_back.xslt
If you run the client again immediately (i.e within 15 seconds of the
first request) you will not see the resource being reloaded by the
registry as the cached value would be still valid.
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 cached
resource has expired and will check the meta information about the
resource to check if the resource itself has changed and will require 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.
[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
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
[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 - ==> Repository fetch of resource with key : transform/transform_back.xslt
Thus the SimpleURLRegistry allows resource to be cached, and updates
detected so that the changes could be reloaded without restarting the ESB
instance.
Objective: Introduction to dynamic sequences with a RegistryPrerequisites: Start the Synapse
configuration numbered 9: i.e. wso2-esb -sample 9 Start the Axis2
server and deploy the SimpleStockQuoteService if not already done
This example introduces the dynamic behaviour of ESB through the use of a
Registry. ESB supports dynamic definitions for sequences and 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 ESB at runtime, and cached
appropriately as per its definition in the registry. Once the cache
expires, ESB would recheck the meta information for the definition and
re-load the sequence definition if necessary and re-cache it again.
Once ESB is started, execute the stock quote client as 'ant stockquote..'.
You will notice that that ESB fetches the definition of the sequence from
the registry and executes its rules as follows:
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
[HttpServerWorker-1] INFO SimpleURLRegistry - ==> Repository fetch of resource with key : sequence/dynamic_seq_1.xml
...
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <dynamic_sequence> :: mediate()
...
[HttpServerWorker-1] INFO LogMediator - message = *** Test Message 1 ***
Now if you execute the client immediately (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 (i.e. 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 elapsed since the original caching of the
sequence, you will notice that the new sequence is loaded and executed by
ESB from the following log messages.
[HttpServerWorker-1] INFO SimpleURLRegistry - ==> Repository fetch of resource with key : sequence/dynamic_seq_1.xml
...
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <dynamic_sequence> :: mediate()
...
[HttpServerWorker-1] INFO LogMediator - message = *** Test Message 2 ***
The cache timeout could be tuned appropriately by configuring the URL
registry to suite the environment and the needs.
Objective: Introduction to dynamic endpoints with the RegistryPrerequisites: Start the Synapse
configuration numbered 10: i.e. wso2-esb -sample 10 Start the
Axis2 server and deploy the SimpleStockQuoteService if not already done
Start a second Axis2 server on http port 9001 and https port 9003 as
follows:
./axis2server.sh -http 9001 -https 9003
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 immediately again, and notice
that the endpoint is cached and reused by ESB - similarly to example # 8.
ant stockquote -Dtrpurl=http://localhost:8080/
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.
Objective: A full registry based configurationPrerequisites: Start the Synapse
configuration numbered 11: i.e. wso2-esb -sample 11 Start the
Axis2 server and deploy the SimpleStockQuoteService if not already done
This example shows a full registry based ESB configuration. Thus it is
possible to start a remote configuration from multiple instances of ESB in
a clustered environment easily. The Synapse configuration held on a node
hosting ESB simply points to the registry and looks up the actual
configuration by requesting the key 'synapse.xml'.
(Note: Full registry based configuration is not dynamic atleast for the
moment. i.e. it is not reloading itself)
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
[HttpServerWorker-1] INFO LogMediator - message = This is a dynamic Synapse configuration
The actual synapse.xml loaded is:
<!-- a registry based Synapse configuration -->
<definitions xmlns="http://ws.apache.org/ns/synapse">
<log level="custom">
<property name="message" value="This is a dynamic Synapse configuration $$$"/>
</log>
<send/>
</definitions>
Objective: Demonstrate one way messaging / fireAndForget
through ESBPrerequisites: Start the Axis2 server
and deploy the SimpleStockQuoteService (Refer steps above) Start
the Synapse configuration numbered 1: i.e. wso2-esb -sample 1
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 ESB into the sample Axis2 server instance, which reports the
acceptance of the order as follows:
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=placeorder
SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733
If you send your client request through TCPmon, you will notice that the
SimpleStockQuoteService replies to ESB with a HTTP 202 reply, and that ESB
in-turn replies to the client with a HTTP 202 acknowledgement
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- filtering of messages with XPath and regex matches -->
<filter source="get-property('To')" regex=".*/StockQuote.*">
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="soap11"/>
</endpoint>
</send>
<drop/>
</filter>
<send/>
</definitions>
Objective: POX to SOAP conversionPrerequisites: Start the Synapse
configuration numbered 50: i.e. wso2-esb -sample 50
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
Execute the 'ant stockquote' specifying that the request should be a REST
request as follows:
ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuote -Drest=true
This example shows a http REST request (as shown below) being transformed
into a SOAP request and forwarded to the stock quote service.
Objective: MTOM and SwA optimizations and request/response
correlation
Prerequisites: Start the Synapse
configuration numbered 51: i.e. wso2-esb -sample 51 Start the
Axis2 server and deploy the MTOMSwASampleService if not already done
Execute the 'ant optimizeclient' specifying MTOM optimization as follows:
ant optimizeclient -Dopt_mode=mtom
The configuration now sets a local message context property, and forwards
the message to 'http://localhost:9000/soap/MTOMSwASampleService'
optimizing binary 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 ESB 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.
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.
[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as MTOM
[java] Saved response to file : /tmp/mtom-36877.gif
Next try SwA as:
ant optimizeclient -Dopt_mode=swa
[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as SwA
[java] Saved response to file : /tmp/swa-47549.gif
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:
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main" onError="errorHandler">
<in>
<send>
<endpoint>
<loadbalance>
<endpoint>
<address uri="http://localhost:9001/soap/LBService1">
<enableAddressing/>
<suspendDurationOnFailure>60</suspendDurationOnFailure>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9002/soap/LBService1">
<enableAddressing/>
<suspendDurationOnFailure>60</suspendDurationOnFailure>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9003/soap/LBService1">
<enableAddressing/>
<suspendDurationOnFailure>60</suspendDurationOnFailure>
</address>
</endpoint>
</loadbalance>
</endpoint>
</send><drop/>
</in>
<out>
<!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
<send/>
</out>
</sequence>
<sequence name="errorHandler">
<makefault>
<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
<reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
</makefault>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>
</sequence>
</definitions>
Objective: Demonstrate the simple load balancing among set of
endpoints
Prerequisites:
Start ESB with sample configuration 52. (i.e. wso2-esb -sample 52)
Deploy the LoadbalanceFailoverService by switching to <ESB installation
directory>/samples/axis2Server/src/LoadbalanceFailoverService directory
and running ant.
Start three instances of sample Axis2 server on HTTP ports 9001, 9002 and
9003 and give some unique names to each server.
Example commands to run sample Axis2 servers from the <ESB installation
directory>/samples/axis2Server directory in Linux are listed below:
Now we are done with setting up the environment for load balance sample.
Start the load balance and failover client using the following command:
ant loadbalancefailover -Di=100
This client sends 100 requests to the LoadbalanceFailoverService through
ESB. ESB 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:
[java] Request: 1 ==> Response from server: MyServer1
[java] Request: 2 ==> Response from server: MyServer2
[java] Request: 3 ==> Response from server: MyServer3
[java] Request: 4 ==> Response from server: MyServer1
[java] Request: 5 ==> Response from server: MyServer2
[java] Request: 6 ==> Response from server: MyServer3
[java] Request: 7 ==> Response from server: MyServer1
...
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):
...
[java] Request: 61 ==> Response from server: MyServer1
[java] Request: 62 ==> Response from server: MyServer2
[java] Request: 63 ==> Response from server: MyServer3
[java] Request: 64 ==> Response from server: MyServer2
[java] Request: 65 ==> Response from server: MyServer3
[java] Request: 66 ==> Response from server: MyServer2
[java] Request: 67 ==> Response from server: MyServer3
...
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 <suspendDurationOnFailure> as 60 seconds in the
configuration. Therefore, load balance endpoint will suspend any failed
child endpoint only for 60 seconds after detecting the failure.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main" onError="errorHandler">
<in>
<send>
<endpoint>
<failover>
<endpoint>
<address uri="http://localhost:9001/soap/LBService1">
<enableAddressing/>
<suspendDurationOnFailure>60</suspendDurationOnFailure>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9002/soap/LBService1">
<enableAddressing/>
<suspendDurationOnFailure>60</suspendDurationOnFailure>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9003/soap/LBService1">
<enableAddressing/>
<suspendDurationOnFailure>60</suspendDurationOnFailure>
</address>
</endpoint>
</failover>
</endpoint>
</send><drop/>
</in>
<out>
<!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
<send/>
</out>
</sequence>
<sequence name="errorHandler">
<makefault>
<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
<reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
</makefault>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>
</sequence>
</definitions>
Objective: Demonstrate the failover sending
Prerequisites:
Start ESB with sample configuration 53 (i.e. wso2-esb -sample 53)
Deploy the LoadbalanceFailoverService and start three instances of sample
Axis2 server as mentioned in sample 52.
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:
ant loadbalancefailover
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.
The console output with MyServer1 shutdown after request 127 is listed
below:
...
[java] Request: 125 ==> Response from server: MyServer1
[java] Request: 126 ==> Response from server: MyServer1
[java] Request: 127 ==> Response from server: MyServer1
[java] Request: 128 ==> Response from server: MyServer2
[java] Request: 129 ==> Response from server: MyServer2
[java] Request: 130 ==> Response from server: MyServer2
...
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.
[java] COULDN'T SEND THE MESSAGE TO THE SERVER.
Once a server is detected as failed, it will be added to the active
servers list again after 60 seconds (specified in <suspendDurationOnFailure>
in the configuration). Therefore, if you have restarted any of the stopped
servers and have shutdown all other servers, messages will be directed to
the newly started server.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main" onError="errorHandler">
<in>
<send>
<endpoint>
<!-- specify the session as the simple client session provided by Synapse for
testing purpose -->
<session type="simpleClientSession"/>
<loadbalance>
<endpoint>
<address uri="http://localhost:9001/soap/LBService1">
<enableAddressing/>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9002/soap/LBService1">
<enableAddressing/>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9003/soap/LBService1">
<enableAddressing/>
</address>
</endpoint>
</loadbalance>
</endpoint>
</send><drop/>
</in>
<out>
<!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
<send/>
</out>
</sequence>
<sequence name="errorHandler">
<makefault>
<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
<reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
</makefault>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>
</sequence>
</definitions>
Objective: Demonstrate the load balancing with session affinity
using client initiated sessions
Prerequisites:
Start ESB with sample configuration 54 (i.e. wso2-esb -sample 54).
Deploy the LoadbalanceFailoverService and start three instances of the
sample Axis2 server as in sample 52.
Above configuration is same as the load balancing configuration in sample
52, 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. ESB 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.
ant loadbalancefailover -Dmode=session
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.
You can see that session number 0 is always directed to the server named
MyServer1. That means session number 0 is bound to MyServer1. Similarly
session 1 and 2 are bound to MyServer3 and MyServer2 respectively.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main" onError="errorHandler">
<in>
<send>
<endpoint>
<!-- specify the session as the simple client session provided by Synapse for
testing purpose -->
<session type="simpleClientSession"/>
<loadbalance>
<endpoint>
<failover>
<endpoint>
<address uri="http://localhost:9001/soap/LBService1">
<enableAddressing/>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9002/soap/LBService1">
<enableAddressing/>
</address>
</endpoint>
</failover>
</endpoint>
<endpoint>
<failover>
<endpoint>
<address uri="http://localhost:9003/soap/LBService1">
<enableAddressing/>
</address>
</endpoint>
<endpoint>
<address uri="http://localhost:9004/soap/LBService1">
<enableAddressing/>
</address>
</endpoint>
</failover>
</endpoint>
</loadbalance>
</endpoint>
</send><drop/>
</in>
<out>
<!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
<send/>
</out>
</sequence>
<sequence name="errorHandler">
<makefault>
<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
<reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
</makefault>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>
</sequence>
</definitions>
Objective: Demonstrate the session affinity based load
balancing with failover capability
Prerequisites:
Start ESB with sample configuration 55 (i.e. wso2-esb -sample 55).
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).
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.
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.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main">
<in>
<send>
<!-- get epr from the given wsdl -->
<endpoint>
<wsdl uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl" service="SimpleStockQuoteService" port="SimpleStockQuoteServiceSOAP11port_http"/>
</endpoint>
</send>
</in>
<out>
<send/>
</out>
</sequence>
</definitions>
Objective: Demonstrate the use of WSDL endpoints
Prerequisites:
Start the Synapse configuration numbered 56 (i.e. wso2-esb -sample 56).
Deploy the SimpleStockQuoteService and start the sample Axis2 server.
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.
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 following command.
ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080
Client will print the quote price for IBM received from the server running
on port 9000. Observe the Axis2 console and the ESB console to verify this
behavior.
Objective: Connecting to endpoints with WS-Security for
outgoing messages
Prerequisites:
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)
Start the Synapse configuration numbered 100: i.e. wso2-esb -sample 100
Start the Axis2 server and deploy the SecureStockQuoteService if not
already done
Use the stock quote client to send a request without WS-Security. ESB 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 ESB shows
the encrypted message flowing to the service and the encrypted response
being received by ESB. 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:
ant stockquote -Dtrpurl=http://localhost:8080/
The message sent by ESB to the secure service can be seen as follows, when
TCPMon is used.
Objective: Demonstrate the message exchange between ESB and the
server using WS-ReliableMessaging (WS-RM)
Prerequisites:
Deploy the ReliableStockQuoteService in the sample Axis2 server by
switching to the samples/axis2Server/src/ReliableStockQuoteService
directory and running ant.
Start the sample Axis2 server on port 9000.
Start ESB with the sample configuration 101 (i.e. wso2-esb -sample 101).
In the above configuration, WS-RM is engaged to the endpoint using the
<enableRM/> 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 ESB
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 ESB
and the server. Now run the sample client using the following command.
ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080
You can observer the client output displaying the quote price for IBM as
follows:
[java] Standard :: Stock price = $189.2521262517493
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. ESB, the initiator of the RM
sequence, first try to create a sequence by sending a message with
CreateSequence element.
ESB 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.
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.
Prerequisites: Start the Synapse
configuration numbered 150: i.e. wso2-esb -sample 150 Start the
Axis2 server and deploy the SimpleStockQuoteService if not already done
Once ESB 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.
Execute the stock quote client by requesting for a stock quote on the
proxy service as follows:
ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy
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 ESB, unless these are
specifically mentioned through the 'transports' attribute.
Objective: Using custom sequences and endpoints for message
mediation with proxy services
Prerequisites: Start the Synapse
configuration numbered 151: i.e. wso2-esb -sample 151 Start the
Axis2 server and deploy the SimpleStockQuoteService if not already done
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.
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.
ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy1 ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy2
Objective: Switching transports and from SOAP to REST/POX
Prerequisites: Start the Synapse
configuration numbered 152: i.e. wso2-esb -sample 152
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
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.
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
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.
Objective: Routing the messages arrived to a proxy service
without processing the MustUnderstand headers (Security header)
Prerequisites: 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)
Start the Synapse configuration numbered 153: i.e. wso2-esb -sample 153
Start the Axis2 server and deploy the SecureStockQuoteService if not
already done
The proxy service will recieve secure messages with security headers which
are MustUnderstand. But hence element 'engageSec' is not present in the
proxy configuration ESB will not engage that Apache Rampart on this proxy
service. It is expected that an MustUnderstand failure exception on the
AxisEngine would occur before the message arrives ESB. But ESB handles
this message and gets it in by setting all the headers which are
MustUnderstand and not processed to processed state. This will enable ESB
to route the messages without reading the Security headers (just routing
the messages from client to service, both of which are secure). 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:
ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy -Dpolicy=./../../repository/conf/sample/resources/policy/client_policy_3.xml
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 URL
http://localhost:8080/soap/StockQuoteProxy?wsdl reveals the security
policy attachments are not there and security is not engaged. When sending
the message to the backend service, you could verify that the security
headers were there as in the original message to ESB from client, and that
the response received does use WS-Security, and forwarded back to the
client without any modification. You should note that this wont be a
security hole because the message inside ESB is signed and encrypted and
can only be forwarded to a secure service to be useful.
Sample setup is same as LoadBalance endpoints (#53 to #54).
Start the Synapse configuration numbered 154: i.e. synapse -sample 154
Start the Axis2 server and deploy the SecureStockQuoteService if not
already done
Runs the client with
ant loadbalancefailover -Dmode=session -Dtrpurl=http://localhost:8080/soap/LBProxy
Objective: Using WS-Security signing and encryption with proxy
services through WS-Policy
Prerequisites: 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)
Start the Synapse configuration numbered 200: i.e. wso2-esb -sample 200
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
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 ESB 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:
ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy -Dpolicy=./../../repository/conf/sample/resources/policy/client_policy_3.xml
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.
Objective: Demonstrate the reliable message exchange between
the client and ESB using WS-ReliableMessaging (WS-RM)
Prerequisites:
Deploy the SimpleStockQuoteService in the sample Axis2 server and start it
on port 9000.
Start ESB with the sample configuration number 201 (i.e. wso2-esb -sample
201).
In the above configuration, a proxy service is created with WS-RM enabled
using the <enableRM/> 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 ESB. Now start the client with WS-RM as follows:
ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dwsrm=true
In this case, client sends WS-RM enabled request to ESB where ESB sends
normal request to the server. This can be observed by examining the wire
level messages between the client and ESB. 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.
Objective: Introduction to switching transports with proxy
services
Prerequisites: Start the Axis2 server
and deploy the SimpleStockQuoteService (Refer steps above)
Download, install and start a JMS server, and configure ESB to listen on
JMS (refer notes below) Start the Synapse configuration numbered
250: i.e. wso2-esb -sample 250 For this example we would use
ActiveMQ as the JMS provider. Once ActiveMQ is installed and started you
should get a message as follows:
INFO BrokerService - ActiveMQ JMS Message Broker (localhost) started
You will now need to configure the Axis2 instance used by ESB (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 and geronimo-j2ee-management_1.0_spec-1.0.jar
into the lib directory to allow ESB to connect to the JMS provider.
For a default ActiveMQ v4.0 installation, you may uncomment the Axis2
transport listener configuration found at repository/conf/axis2.xml as
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.
Now lets send a stock quote request on JMS, using the dumb stock quote
client as follows:
ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/StockQuoteProxy -Djms_payload=MSFT
On the ESB debug log you will notice that the JMS listener received the
request message as:
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver -Proxy Service StockQuoteProxy received a new message...
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:
Accepted order for : 16517 stocks of MSFT at $ 169.14622538721846
In this sample, client sends the request message to the proxy service
exposed in JMS in Synsape. ESB 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.
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.
Prerequisites: Download, install and
start a JMS server
Configure sample Axis2 server for JMS (refer notes above) Start
the Axis2 server and deploy the SimpleStockQuoteService (see below)
Configure the Synase JMS transport (refer notes above - sample 250)
Start the Synapse configuration numbered 251: i.e. wso2-esb -sample 251
To switch from HTTP to JMS, edit the
samples/axis2Server/repository/conf/axis2.xml for the sample Axis2 server
and enable JMS (refer notes above), and restart the server. Now you can
see that the simple stock quote service is available in both JMS and HTTP
in the sample Axis2 server. To see this, point your browser to the WSDL of
the service at http://localhost:9000/soap/SimpleStockQuoteService?wsdl.
JMS URL for the service is mentioned as below:
You may also notice that the simple stock quote proxy service exposed in
ESB is now available only in HTTP as we have specified transport for that
service as HTTP. To observe this, access the WSDL of stock quote proxy
service at http://localhost:8080/soap/StockQuoteProxy?wsdl.
This ESB 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 ESB server. To test this, send a
place order request to ESB using HTTP as follows:
ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dmode=placeorder -Dsymbol=MSFT
The sample Axis2 server console will print a message indicating that it
has accepted the order as follows:
Accepted order for : 18406 stocks of MSFT at $ 83.58806051152119
Objective: Pure POX/Text and Binary JMS Proxy services -
including MTOM
Prerequisites: Configure JMS for ESB
(Refer notes) Start the Synapse configuration numbered 252: i.e.
wso2-esb -sample 252 Start the Axis2 server and deploy the
SimpleStockQuoteService and the MTOMSwASampleService if not already done
This configuration creates three JMS proxy services named
JMSFileUploadProxy, JMSTextProxy and JMSPoxProxy exposed over JMS queues
with the same names as the services. The first part of this example
demonstrates the pure text message support with JMS, where a user sends a
space separated text JMS message of the form "<price> <qty>
<symbol>". ESB converts this message into a SOAP message and sends
this to the SimpleStockQuoteServices' placeOrder operation. ESB uses the
script mediator to transform the text message into a XML payload using the
Javascript support available to tokenize the string. The proxy service
property named "transport.jms.Wrapper" defines a custom wrapper element
QName, to be used when wrapping text/binary content into a SOAP envelope.
Execute JMS client as follows. This will post a pure text JMS message with
the content defined (e.g. "12.33 1000 ACP") to the specified JMS
destination - dynamicQueues/JMSTextProxy
ant jmsclient -Djms_type=text -Djms_payload="12.33 1000 ACP" -Djms_dest=dynamicQueues/JMSTextProxy
Following the debug logs, you could notice that ESB 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.
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.
The sample Axis2 server would now accept the one way message and issue the
following message:
Wed Apr 25 19:50:56 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 1000 stocks of ACP at $ 12.33
The next section of this example demonstrates how a pure binary JMS
message could be received and processed through ESB. The configuration
creates a proxy service named 'JMSFileUploadProxy' that accepts binary
messages and wraps them into a custom element
'{http://services.samples/xsd}element'. The received message is then
forwarded to the MTOMSwASampleService using the SOAP action
'urn:oneWayUploadUsingMTOM' and optimizing binary conent using MTOM. To
execute this sample, use the JMS client to publish a pure binary JMS
message containing the file
'./../../repository/conf/sample/resources/mtom/asf-logo.gif' to the JMS
destination 'dynamicQueues/JMSFileUploadProxy' as follows:
ant jmsclient -Djms_type=binary -Djms_dest=dynamicQueues/JMSFileUploadProxy -Djms_payload=./../../repository/conf/sample/resources/mtom/asf-logo.gif
Examining the ESB debug logs reveals that the binary content was received
over JMS and wrapped with the specified element into a SOAP infoset as
follows:
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Proxy Service JMSFileUploadProxy received a new message...
...
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body><axis2ns1:element xmlns:axis2ns1="http://services.samples/xsd">R0lGODlhgw...AAOw==</axis2ns1:element></soapenv:Body>
</soapenv:Envelope>
Thereafter the message was sent as a MTOM optimized message as specified
by the 'format=mtom' attribute of the endpoint, to the
MTOMSwASampleService using the SOAP action 'urn:oneWayUploadUsingMTOM'.
Once received by the sample service, it is saved into a temporary file and
could be verified for correctness.
Wrote to file : /tmp/mtom-60319.gif
The final section of this example shows how a POX JMS message received by
ESB is sent to the SimpleStockQuoteService as a SOAP message. Use the JMS
client as follows to create a POX (Plain Old XML) message with a stock
quote request payload (without a SOAP envelope), and send it to the JMS
destination 'dynamicQueues/JMSPoxProxy' as follows:
ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/JMSPoxProxy -Djms_payload=MSFT
You can see that ESB received the POX message and displays it as follows
in the debug logs, and then converts it into a SOAP payload and sends to
the SimpleStockQuoteService after setting the SOAP action as
'urn:placeOrder'.
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Proxy Service JMSPoxProxy received a new message...
...
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><m:placeOrder xmlns:m="http://services.samples/xsd">
<m:order>
<m:price>172.39703010684752</m:price>
<m:quantity>19211</m:quantity>
<m:symbol>MSFT</m:symbol>
</m:order>
</m:placeOrder></soapenv:Body></soapenv:Envelope>
[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Using the sequence named pox_proxy for message mediation
...
[JMSWorker-1] DEBUG HeaderMediator - Setting header : Action to : urn:placeOrder
...
[JMSWorker-1] DEBUG AddressEndpoint - Sending message to endpoint :: name = AnonymousEndpoints resolved address = http://localhost:9000/soap/SimpleStockQuoteService
[JMSWorker-1] DEBUG AddressEndpoint - SOAPAction: urn:placeOrder
[JMSWorker-1] DEBUG AddressEndpoint - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><m:placeOrder xmlns:m="http://services.samples/xsd">
<m:order>
<m:price>172.39703010684752</m:price>
<m:quantity>19211</m:quantity>
<m:symbol>MSFT</m:symbol>
</m:order>
</m:placeOrder></soapenv:Body></soapenv:Envelope>
[JMSWorker-1] DEBUG Axis2FlexibleMEPClient - sending [add = false] [sec = false] [rm = false] [ mtom = false] [ swa = false] [ force soap=true; pox=false] [ to null]
The sample Axis2 server displays a successful message on the receipt of
the message as:
Wed Apr 25 20:24:50 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 19211 stocks of MSFT at $ 172.39703010684752
Objective: Demonstrate one way message bridging from JMS to
http and replying with a http 202 Accepted response
Prerequisites: Start the Axis2 server
and deploy the SimpleStockQuoteService if not already done
Start the Synapse configuration numbered 253: i.e. wso2-esb -sample 253
This example invokes the one-way 'placeOrder' operation on the
SimpleStockQuoteService using the Axis2 ServiceClient.fireAndForget() API
at the client. To test this, use 'ant -Dmode=placeorder...' and you will
notice the one way JMS message flowing through ESB into the sample Axis2
server instance over http, and Axis2 acknowledging it with a http 202
Accepted response.
ant stockquote -Dmode=placeorder -Dtrpurl="jms:/JMStoHTTPStockQuoteProxy?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616"
SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733
The second example shows how ESB 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 ESB 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 ESB
ant stockquote -Dmode=placeorder -Dtrpurl=http://localhost:8080/soap/OneWayProxy
Objective: Using the file system as transport medium using VFS
transport listener and sender
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
Create three new directories in a test directory. e.g. in, out, original
in /home/user/test. Open
ESB_HOME/repository/conf/sample/synapse_sample_254.xml and edit the
following values. Change transport.vfs.FileURI,
transport.vfs.MoveAfterProcess, transport.vfs.MoveAfterFailure parameter
values to the above in, original, original directories respectively.
Change outSequence endpoint address uri to out directory with the prefeix
vfs:. Values you have to change are marked with <!--CHANGE-->.
Start the Synapse configuration numbered 254: i.e. wso2-esb -sample 254
Copy ESB_HOME/repository/conf/sample/resources/vfs/test.xml to the
directory given in transport.vfs.FileURI above.
VFS transport listener will pick the file from in
directory and send it to the Axis2 service. The request XML file will be
moved to original directory. The response from the Axis2
server will be saved to out directory.
Create a new test directory in the FTP server. Open
ESB_HOME/repository/conf/sample/synapse_sample_255.xml and edit the
following values. Change transport.vfs.FileURI parameter value point to
the test directory at the FTP server. Change outSequence endpoint address
uri email address to a working email address. Values you have to change
are marked with <!--CHANGE-->.
Start the Synapse configuration numbered 255: i.e. wso2-esb -sample 255
Copy ESB_HOME/repository/conf/sample/resources/vfs/test.xml to the ftp
directory given in transport.vfs.FileURI above.
VFS transport listener will pick the file from the directory in the ftp
server and send it to the Axis2 service. The file in the ftp directory
will be deleted. The response will be sent to the given email address.
Objective: Introduce the concept of tasks and how simple
trigger works
Prerequisites: You will need access to
build the SimpleStockQuoteService as mentioned in the above and start the
sample axis2 server before staring ESB.
When ever ESB gets started and initialized, this task will run
periodically in 5 second intervals. You could limit the number of times
that you want to run this task by adding a count attribute with an integer
as the value, if the count is not present as in this sample this task will
run forever.
One can write his own task class implementing the
org.apache.synapse.startup.Task interface and implementing the execute
method to do the task. For this particular sample we have used the
MessageInjector which just injects a message specified in to the ESB
environment.
The ESB Script Mediator is a ESB extension, and thus all prerequisites are
not bundled by default with the ESB distribution. Before you use some
script mediators you may need to manually add the required jar files to
the ESB lib directory, and optionally perform other installation tasks as
may be required by the individual scripting language. This is explained in
the Samples Setup guide.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<localEntry key="stockquoteScript" src="file:repository/conf/sample/resources/script/stockquoteTransform.js"/>
<in>
<!-- transform the custom quote request into a standard quote request expected by the service -->
<script language="js" key="stockquoteScript" function="transformRequest"/>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</in>
<out>
<!-- transform the standard response back into the custom format the client expects -->
<script language="js" key="stockquoteScript" function="transformResponse"/>
<send/>
</out>
</definitions>
<x><![CDATA[
function transformRequest(mc) {
var symbol = mc.getPayloadXML()..*::Code.toString();
mc.setPayloadXML(
<m:getQuote xmlns:m="http://services.samples/xsd">
<m:request>
<m:symbol>{symbol}</m:symbol>
</m:request>
</m:getQuote>);
}
function transformResponse(mc) {
var symbol = mc.getPayloadXML()..*::symbol.toString();
var price = mc.getPayloadXML()..*::last.toString();
mc.setPayloadXML(
<m:CheckPriceResponse xmlns:m="http://services.samples/xsd">
<m:Code>{symbol}</m:Code>
<m:Price>{price}</m:Price>
</m:CheckPriceResponse>);
}
]]></x>
Objective: Introduction to script mediators
Prerequisites:
Start the Synapse configuration numbered 350: i.e. wso2-esb -sample 350
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This sample is similar to sample 8 but instead of using XSLT the
transformation is done with JavaScript and E4X. Note that the script
source loaded from a resource must be specified within a CDATA tag within
an XML element. The script used in this example has two functions,
'transformRequest' and 'transformResponse', and the Synapse configuration
uses the function attribute to specify which function should be invoked.
Use the stock quote client to issue a custom quote client as follows.:
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote
ESB uses the script mediator and the specified Javascript function to
convert the custom request to a standard quote request. Subsequently the
response received is transformed and sent back to the client.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<in>
<!-- transform the custom quote request into a standard quote requst expected by the service -->
<script language="js"><![CDATA[
var symbol = mc.getPayloadXML()..*::Code.toString();
mc.setPayloadXML(
<m:getQuote xmlns:m="http://services.samples/xsd">
<m:request>
<m:symbol>{symbol}</m:symbol>
</m:request>
</m:getQuote>);
]]></script>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</in>
<out>
<!-- transform the standard response back into the custom format the client expects -->
<script language="js"><![CDATA[
var symbol = mc.getPayloadXML()..*::symbol.toString();
var price = mc.getPayloadXML()..*::last.toString();
mc.setPayloadXML(
<m:CheckPriceResponse xmlns:m="http://services.samples/xsd">
<m:Code>{symbol}</m:Code>
<m:Price>{price}</m:Price>
</m:CheckPriceResponse>);
]]></script>
<send/>
</out>
</definitions>
Objective: Introduction to in-line script mediation
Prerequisites:
Start the Synapse configuration numbered 351: i.e. wso2-esb -sample 351
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This example is functionally equivalent to sample # 350 and sample # 8,
and demonstrates in-line script mediation in ESB. Use the stock quote
client to send a custom quote as in example # 350 to test this example.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<in>
<!-- change the MessageContext into a response and set a response payload -->
<script language="js"><![CDATA[
mc.setTo(mc.getReplyTo());
mc.setProperty("RESPONSE", "true");
mc.setPayloadXML(
<ns:getQuoteResponse xmlns:ns="http://services.samples/xsd">
<ns:return>
<ns:last>99.9</ns:last>
</ns:return>
</ns:getQuoteResponse>);
]]></script>
</in>
<send/>
</definitions>
Objective: Accessing the Synapse APIs from scripting languages
Prerequisites:
Start the Synapse configuration numbered 352: i.e. bin/synapse -sample 352
This example shows how an inline JavaScript mediator script could access
the Synapse message context API to set its 'To' EPR and to set a custom
property to mark it as a response. Execute the stock quote client, and you
will receive the response "99.9" as the last sale price as per the above
script.
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
...
stockquote:
[java] Standard :: Stock price = $99.9
<definitions xmlns="http://ws.apache.org/ns/synapse">
<localEntry key="stockquoteScript" src="file:repository/conf/sample/resources/script/stockquoteTransform.rb"/>
<in>
<!-- transform the custom quote request into a standard quote request expected by the service -->
<script language="rb" key="stockquoteScript" function="transformRequest"/>
<!-- send message to real endpoint referenced by name "stockquote" and stop -->
<send>
<endpoint name="stockquote">
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</in>
<out>
<!-- transform the standard response back into the custom format the client expects -->
<script language="rb" key="stockquoteScript" function="transformResponse"/>
<send/>
</out>
</definitions>
This sample uses Ruby so first setup support for this in ESB as described
at Configuring JRuby.
Start the Synapse configuration numbered 353: i.e. bin/synapse -sample 353
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This sample is functionally equivalent to sample # 350 (#351 and #8) but
instead uses a Ruby script using the JRuby interpreter. The script has two
functions, 'transformRequest' and 'transformResponse', and the Synapse
configuration specifies which function is to be invoked when used. Execute
the stock quote client to send a custom stock quote as per example #350
and check the received stock quote response.
Objective: Script mediators using Ruby(In-lined Ruby Script)
Prerequisites:
This sample uses Ruby so first setup support for this in ESB as described
at Configuring JRuby.
Start the Synapse configuration numbered 354: i.e. bin/synapse -sample 354
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This sample is functionally equivalent to the sample #353.
Runs the client with
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote
Following database mediators use Derby in a client/server configuration by
using the network server. Therefore, to proceed with the following
samples, you need a working Derby database server and you have to follow
the steps in Sample Setup Guide
before going through the samples.
Prerequisites: Setting up Derby database as
explained above.
Start the Synapse configuration numbered 360: i.e. wso2-esb -sample 360
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This sample demonstrates simple database read operations through ESB. When
a message arrives at dblookup mediator, it opens a connection to the
database and executes the SQL query. The SQL query use '?' character for
attributes that will be filled at runtime. The parameters define how to
calculate the value of those attributes at runtime. In this sample a
dblookup mediator has been used to extract 'id' of the company from the
company database using the symbol which is evaluated using an xpath
against the SOAP envelope. Then 'id' base switching will be done by a
switch mediator.
When the IBM stock quote is requested,
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM
ESB console shows
INFO LogMediator text = ** Looking up from the Database **INFO LogMediator text = Company ID ? c1
For the SUN stock quote,
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN
ESB console shows
INFO LogMediator text = ** Looking up from the Database **INFO LogMediator text = Company ID ? c2
and for the MSFT stock quote,
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT
INFO LogMediator text = ** Looking up from the Database ** INFO LogMediator text = Company ID ? c2
For any other symbols, ESB console shows
INFO LogMediator text = ** Unrecognized Company ID **
and the client gets a response which has following message.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main">
<in>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</in>
<out>
<log level="custom">
<property name="text"
value="** Reporting to the Database **"/>
</log>
<dbreport xmlns="http://ws.apache.org/ns/synapse">
<connection>
<pool>
<driver>org.apache.derby.jdbc.ClientDriver</driver>
<url>jdbc:derby://localhost:1527/esbdb;create=false</url>
<user>esb</user>
<password>esb</password>
</pool>
</connection>
<statement>
<sql>update company set price=? where name =?</sql>
<parameter expression="//m0:return/m0:last/child::text()"
xmlns:m0="http://services.samples/xsd" type="DOUBLE"/>
<parameter expression="//m0:return/m0:symbol/child::text()"
xmlns:m0="http://services.samples/xsd" type="VARCHAR"/>
</statement>
</dbreport>
<send/>
</out>
</sequence>
</definitions>
Objective: Introduction to the dbreport mediator
Prerequisites: Setting up Derby database as
above.
Start the Synapse configuration numbered 361: i.e. wso2-esb -sample 361
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
This sample demonstrate simple database write operations. The dbreport
mediator writes (i.e. inserts one row) to a table using the message
details. It works the same as the dblookup mediator. In this sample ,
dbreport mediator is used for updating the stock price of the company
using the last quote value which is calculated by evaluating an XPath
against the response message. After running this sample, user can check
the company table using the Derby client tool. It will show the inserted
value by the dbreport mediator.
Run the client using,
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM
and then execute the following query using database client tool against
synapsedb.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<sequence name="main">
<in>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</in>
<out>
<log level="custom">
<property name="text"
value="** Reporting to the Database **"/>
</log>
<dbreport xmlns="http://ws.apache.org/ns/synapse">
<connection>
<pool>
<driver>org.apache.derby.jdbc.ClientDriver</driver>
<url>jdbc:derby://localhost:1527/esbdb;create=false</url>
<user>esb</user>
<password>esb</password>
</pool>
</connection>
<statement>
<sql>update company set price=? where name =?</sql>
<parameter expression="//m0:return/m0:last/child::text()"
xmlns:m0="http://services.samples/xsd" type="DOUBLE"/>
<parameter expression="//m0:return/m0:symbol/child::text()"
xmlns:m0="http://services.samples/xsd" type="VARCHAR"/>
</statement>
</dbreport>
<log level="custom">
<property name="text"
value="** Looking up from the Database **"/>
</log>
<dblookup xmlns="http://ws.apache.org/ns/synapse">
<connection>
<pool>
<driver>org.apache.derby.jdbc.ClientDriver</driver>
<url>jdbc:derby://localhost:1527/esbdb;create=false</url>
<user>esb</user>
<password>esb</password>
</pool>
</connection>
<statement>
<sql>select * from company where name =?</sql>
<parameter expression="//m0:return/m0:symbol/child::text()"
xmlns:m0="http://services.samples/xsd" type="VARCHAR"/>
<result name="stock_price" column="price"/>
</statement>
</dblookup>
<log level="custom">
<property name="text"
expression="fn:concat('Stock price - ',get-property('stock_price'))"/>
</log>
<send/>
</out>
</sequence>
</definitions>
Objective: Demonstrate the use of dbreport and dblookup
mediators
Prerequisites: Setting up Derby database as
above.
Start the Synapse configuration numbered 362: i.e. wso2-esb -sample 362
Start the Axis2 server and deploy the SimpleStockQuoteService if not
already done
In this sample ,the dbreport mediator works the same as the above sample.
It updates the price for the given company using the response messages
content. Then the dblookup mediator reads the last updated value from the
company database and logs it.
When running client,
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM
ESB console shows,
INFO LogMediator text = ** Reporting to the Database **
...
INFO LogMediator text = ** Looking up from the Database **
...
INFO LogMediator text = Stock price - 153.47886496064808
Objective: Demonstrate the use of throttle mediator for concurrency
throttling
Prerequisites:
Deploy the SimpleStockQuoteService in sample Axis2 server and start it on
port 9000.
Start ESB with the sample configuration 370 (i.e. wso2-esb -sample 370).
Above configuration specifies a throttle mediator inside the in mediator.
Therefore, all request messages directed to the main sequence will be
subjected to throttling. Throttle mediator has policy, onAccept and
onReject tags at top level. Policy tag specifies the throttling policy to
be applied for messages. In this sample policy contains only component
called "MaximumConcurrentAccess" .This indicates the maximum number of
concurrent request that may have passed through the ESB on a single unit
of time. To test concurrency throttling ,it is required to send concurrent
request to ESB. For ESB with above configuration ,if client send 20
request concurrently ,then approximately half of those will success. The
client command is as follows.
ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/
Objective: Demonstrate the use of throttle mediator for
restricting request counts
Prerequisites:
Deploy the SimpleStockQuoteService in sample Axis2 server and start it on
port 9000.
Start ESB with the sample configuration 371 (i.e. wso2-esb -sample 371).
Above configuration specifies a throttle mediator inside the in mediator.
Therefore, all request messages directed to the main sequence will be
subjected to throttling. Throttle mediator has policy, onAccept and
onReject tags at the top level. Policy tag specifies the throttling policy
to be applied for messages. It contains some IP address ranges and the
maximum number of messages to be allowed for those ranges within a time
period given in "UnitTime" tag. "ProhibitTimePeriod" tag specifies the
time period to prohibit further requests after the received request count
exceeds the specified time. Now run the client 5 times repetitively using
the following command to see how throttling works.
ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/
For the first four requests you will get the quote prices for IBM as
follows.
[java] Standard :: Stock price = $177.20143371883802
You will receive the following response for the fifth request.
Maximum number of requests within 800000 milliseconds is specified as 4
for any server (including localhost) other than the explicitly specified
ones. Therefore, our fifth request is denied by the throttle mediator. You
can verify this by looking at the ESB console.
[HttpServerWorker-1] INFO LogMediator - text = **Access Accept**
[HttpServerWorker-2] INFO LogMediator - text = **Access Accept**
[HttpServerWorker-3] INFO LogMediator - text = **Access Accept**
[HttpServerWorker-4] INFO LogMediator - text = **Access Accept**
[HttpServerWorker-5] INFO LogMediator - text = **Access Denied**
<!-- Use of both concurrency throttling and request rate based throttling -->
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.apache.synapse.registry.url.SimpleURLRegistry">
<!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
<parameter name="root">file:repository/</parameter>
<!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
<parameter name="cachableDuration">150000</parameter>
</registry>
<sequence name="onAcceptSequence">
<log level="custom">
<property name="text" value="**Access Accept**"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</sequence>
<sequence name="onRejectSequence" trace="enable">
<log level="custom">
<property name="text" value="**Access Denied**"/>
</log>
<makefault>
<code value="tns:Receiver"
xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
<reason value="**Access Denied**"/>
</makefault>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<send/>
<drop/>
</sequence>
<proxy name="StockQuoteProxy">
<target>
<inSequence>
<throttle onReject="onRejectSequence" onAccept="onAcceptSequence" id="A">
<policy key="conf/sample/resources/policy/throttle_policy.xml"/>
</throttle>
</inSequence>
<outSequence>
<throttle id="A"/>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
Objective: Use of both concurrency throttling and request rate
based throttling
Prerequisites: Deploy the
SimpleStockQuoteService in sample Axis2 server and start it on port 9000.
Start ESB with the sample configuration 372 (i.e. wso2-esb -sample 372).
Throttle policy is loaded from the ?throttle_policy. xml?
.That policy contains merging policy from sample 370 and 371. To check the
functionality , it is need to run load test.The all enabled request from
the concurrency throttling will be controlled by the access rate base
throttling according to the policy.
Run the client as follows
ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy
You will get results same as sample 371.if you run the load test,
results will be different due to affect of concurrency throttling.
Class mediator can be used to write your own custom mediation in Java and
you have access to the SynapseMessageContext and all the Synapse API in
there. This is a useful extension mechanism within ESB to extend its
functionality. This class can contain fields for which you can assign
values at runtime through the configuration.
Objective: Demonstrate the use of Class mediator to extend the
mediation functionality
Prerequisites:
Make sure the synapse-samples-1.0.jar is in your class path (by default
this jar is placed in the lib directory when installing ESB).
Start ESB with the sample configuration 380 (i.e. wso2-esb -sample 380)
Start the sample Axis2 server and deploy the SimpleStockQuoteService.
In this configuration, ESB hands over the request message to the specified
endpoint, which sends it to the Axis2 server running on port 9000.
But the response message is passed through the class mediator before
sending it back to the client. Two parameters named "discountFactor"
and "bonusFor" are passed to the instance mediator implementation class
(i.e. samples.mediators.DiscountQuoteMediator) before each
invocation. Code of the mediator implementation class is shown below.
package samples.mediators;
import org.apache.synapse.MessageContext;
import org.apache.synapse.Mediator;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.namespace.QName;
public class DiscountQuoteMediator implements Mediator {
private static final Log log = LogFactory.getLog(DiscountQuoteMediator.class);
private String discountFactor="10";
private String bonusFor="10";
private int bonusCount=0;
public DiscountQuoteMediator(){}
public boolean mediate(MessageContext mc) {
String price= mc.getEnvelope().getBody().getFirstElement().getFirstElement().
getFirstChildWithName(new QName("http://services.samples/xsd","last")).getText();
//converting String properties into integers
int discount=Integer.parseInt(discountFactor);
int bonusNo=Integer.parseInt(bonusFor);
double currentPrice=Double.parseDouble(price);
//discounting factor is deducted from current price form every response
Double lastPrice = new Double(currentPrice - currentPrice * discount / 100);
//Special discount of 5% offers for the first responses as set in the bonusFor property
if (bonusCount <= bonusNo) {
lastPrice = new Double(lastPrice.doubleValue() - lastPrice.doubleValue() * 0.05);
bonusCount++;
}
String discountedPrice = lastPrice.toString();
mc.getEnvelope().getBody().getFirstElement().getFirstElement().getFirstChildWithName
(new QName("http://services.samples/xsd","last")).setText(discountedPrice);
System.out.println("Quote value discounted.");
System.out.println("Original price: " + price);
System.out.println("Discounted price: " + discountedPrice);
return true;
}
public String getType() {
return null;
}
public void setTraceState(int traceState) {
traceState = 0;
}
public int getTraceState() {
return 0;
}
public void setDiscountFactor(String discount) {
discountFactor=discount;
}
public String getDiscountFactor() {
return discountFactor;
}
public void setBonusFor(String bonus){
bonusFor=bonus;
}
public String getBonusFor(){
return bonusFor;
}
}
All classes developed for class mediation should implement the Mediator
interface, which contains the mediate(...) method. mediate(...) method of
the above class is invoked for each response message mediated through the
main sequence, with the message context of the current message as the
parameter. All the details of the message including the SOAP headers, SOAP
body and properties of the context hierarchy can be accessed from the
message context. In this sample, the body of the message is retrieved and
the discount percentage is subtracted from the quote price. If the quote
request number is less than the number specified in the "bonusFor"
property in the configuration, a special discount is given.
Now run the client using the following command.
ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080
You will see the below output in the client console with the discounted
quote value.
[java] Standard :: Stock price = $138.77458254967408
Now check the console running Synapse. You will see the original value and
the discounted value for the requested quote as follows.
Quote value discounted.
Original price: 162.30945327447262
Discounted price: 138.77458254967408
<!-- Introduction to the XQuery mediator -->
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- the SimpleURLRegistry allows access to a URL based registry (e.g. file:/// or http://) -->
<registry provider="org.wso2.esb.registry.ESBRegistry">
<!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
<parameter name="root">file:repository/conf/sample/resources/</parameter>
<!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
<parameter name="cachableDuration">15000</parameter>
</registry>
<localEntry key="xquery-key-req"
src="file:repository/conf/sample/resources/xquery/xquery_req.xq"/>
<proxy name="StockQuoteProxy">
<target>
<inSequence>
<xquery key="xquery-key-req">
<variable name="payload" type="ELEMENT"/>
</xquery>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<out>
<xquery key="xquery/xquery_res.xq">
<variable name="payload" type="ELEMENT"/>
<variable name="code" type="STRING"
expression="self::node()//m0:return/m0:symbol/child::text()"
xmlns:m0="http://services.samples/xsd"/>
<variable name="price" type="DOUBLE"
expression="self::node()//m0:return/m0:last/child::text()"
xmlns:m0="http://services.samples/xsd"/>
</xquery>
<send/>
</out>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
This example uses the XQuery mediator to perform transformations. This
sample behaves the same as sample number 8 and the only difference is that
this sample uses XQuery instead of XSLT for transformation.
Execute the custom quote client as 'ant stockquote -Dmode=customquote ...'
ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dmode=customquote
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- the SimpleURLRegistry allows access to URL based registry (e.g. file:/// or http://) -->
<registry provider="org.apache.synapse.registry.url.SimpleURLRegistry">
<!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
<parameter name="root">file:repository/conf/sample/resources/</parameter>
<!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
<parameter name="cachableDuration">15000</parameter>
</registry>
<proxy name="StockQuoteProxy">
<target>
<inSequence>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<out>
<xquery key="xquery/xquery_commisson.xq">
<variable name="payload" type="ELEMENT"></variable>
<variable name="commission" type="ELEMENT" key="misc/commission.xml"></variable>
</xquery>
<send/>
</out>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
</definitions>
Objective: Demonstrate the use of XQuery mediator to
import external XML documents to the XQuery engine
Prerequisites:Deploy the SimpleStockQuoteService
in sample Axis2 server and start it on port 9000.
Start ESB with the sample configuration 391 (i.e. wso2-esb -sample 391).
In this sample, data from commission.xml document is used inside XQUERY
document. The stock quote price from the response and commission from the
commission.xml document will be added and given as a new price .
Invoke the client as follows.
ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy
Objective: Demonstrate the use of Iterate mediator to
split the messages in to parts and process them asynchronously and then
aggregate the responses coming in to ESB
Prerequisites:Deploy the SimpleStockQuoteService
in sample Axis2 server and start it on port 9000.
Start ESB with the sample configuration 400 (i.e. wso2-esb -sample 400).
In this sample, the message sent to ESB has embedded with a number of
elements of the same type in one message. When ESB received this message
it will iterate through those elements and then sent to the specified
endpoint. When all the responses appear in to ESB then those messages will
be aggregated to form the resultant response and sent back to the client.
Invoke the client as follows.
ant stockquote -Daddurl=http://localhost:8080/soap/SplitAggregateProxy -Ditr=4
Cached mediator can be used to utilize the network bandwidth, to protect
the backend service from being loaded with the same type of requests like
browser refresh actions and also to speed up the execution of the web
service. This mediator should be used with sence, because it is not
applicable for each and every service (for example services with dynamic
responses for a particular release)
Objective: Demonstrate the use of Cache mediator in order
to cache the response and use that cached response as the response for an
identical xml request
Prerequisites:Deploy the SimpleStockQuoteService
in sample Axis2 server and start it on port 9000.
Start ESB with the sample configuration 420 (i.e. wso2-esb -sample 420).
In this sample, the message sent to ESB is checked for an existing cached
response by calculating the hash value of the request. If there is a cache
hit in ESB then this request will not be forwarded to the actual service,
rather ESB respond to the client with the cached response. In case of a
cache miss that particular message will be forwarded to the actual service
and cached that response in the out path for the use of consecutive
requests of the same type.
To observe this behaviour, invoke the client as follows.
ant stockquote -Dtrpurl=http://localhost:8080/
You could notice that if you send more than one requests within 20 seconds
only the first request is forwarded to the actual service, and the rest of
the requests will be served by the cache inside ESB. You could observe
this by looking at the printed line of the axis2 server, as well as by
observing a constant rate as the response to the client instead of the
random rate, which changes by each and every 20 seconds.
The Callout mediator calls the given service URL with the request message
which is given by the source attribute, waits for the response and
attaches the received response to the destination which is given by the
target attribute. Both the source and the target can be a key or an XPath.
In the case of the source, this key refers to either a message context
property or to a local entry. For the target, this key refers to a message
context property only.
Objective: Demonstrate the use of the Callout
mediator for the synchronized web service invocation
Prerequisites: Deploy the
SimpleStockQuoteService in sample Axis2 server and start it on port
9000.
Start Synapse with the sample configuration 430 (i.e. synapse -sample
430).
In this sample, Callout mediator does the direct service invocation to
the StockQuoteService using the client request, get the response and set
it as the first child of the SOAP message body. Then using the send
mediator, the message is sent back to the client.
Invoke the client as follows.
ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/