| <!-- |
| ~ Licensed to the Apache Software Foundation (ASF) under one |
| ~ or more contributor license agreements. See the NOTICE file |
| ~ distributed with this work for additional information |
| ~ regarding copyright ownership. The ASF licenses this file |
| ~ to you under the Apache License, Version 2.0 (the |
| ~ "License"); you may not use this file except in compliance |
| ~ with the License. You may obtain a copy of the License at |
| ~ |
| ~ http://www.apache.org/licenses/LICENSE-2.0 |
| ~ |
| ~ Unless required by applicable law or agreed to in writing, |
| ~ software distributed under the License is distributed on an |
| ~ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| ~ KIND, either express or implied. See the License for the |
| ~ specific language governing permissions and limitations |
| ~ under the License. |
| --> |
| <html> |
| <head> |
| <meta http-equiv="content-type" content=""/> |
| <title>Synapse Samples</title> |
| <style type="text/css"> |
| .command { |
| border: 1px dashed #3c78b5; |
| text-align: left; |
| background-color: #f0f0f0; |
| padding: 3px; |
| font-size: 11px; |
| font-family: Courier; |
| margin: 10px; |
| line-height: 13px; |
| } |
| .consoleOutput { |
| border: 1px dashed #3c78b5; |
| font-size: 11px; |
| font-family: Courier; |
| margin: 10px; |
| line-height: 13px; |
| background-color: #f0f0f0; |
| border-bottom: 1px dashed #3c78b5; |
| padding: 3px; |
| border-style: solid; |
| } |
| .info { |
| border-style: solid; |
| border-width: 1px; |
| border-color: #090; |
| background-color: #dfd; |
| text-align:left; |
| margin-top: 5px; |
| margin-bottom: 5px; |
| } |
| li { |
| font-family: Verdana, arial, sans-serif; |
| font-size: 11px; |
| line-height: 16px; |
| color: #000000; |
| font-weight: normal; |
| } |
| p { |
| font-family: Verdana, arial, sans-serif; |
| font-size: 11px; |
| line-height: 16px; |
| color: #000000; |
| font-weight: normal; |
| } |
| pre { |
| padding: 0px; |
| margin-top: 5px; |
| margin-left: 15px; |
| margin-bottom: 5px; |
| margin-right: 5px; |
| text-align: left; |
| background-color: #f0f0f0; |
| padding: 3px; |
| border: 1px dashed #3c78b5; |
| font-size: 11px; |
| font-family: Courier; |
| margin: 10px; |
| line-height: 13px; |
| } |
| h1 { |
| font-size: 24px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| color: #003366; |
| border-bottom: 1px solid #3c78b5; |
| padding: 2px; |
| margin: 36px 0px 4px 0px; |
| } |
| h2 { |
| font-size: 18px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| border-bottom: 1px solid #3c78b5; |
| padding: 2px; |
| margin: 27px 0px 4px 0px; |
| } |
| h3 { |
| font-size: 14px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| padding: 2px; |
| margin: 21px 0px 4px 0px; |
| } |
| h4 { |
| font-size: 12px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| padding: 2px; |
| margin: 18px 0px 4px 0px; |
| }</style> |
| </head> |
| |
| <body> |
| <h1>Running the Synapse Samples</h1> |
| |
| <h2><a name="TOC">Contents</a></h2> |
| |
| <div class="section-content"> |
| <ul> |
| <li><a href="samples_setup.html#Overview">Overview</a></li> |
| <li><a href="#MediationSamples">Message mediation samples</a> |
| <ul> |
| <li><a href="#Sample0">Sample 0: Introduction to Synapse</a></li> |
| <li><a href="#Sample1">Sample 1: Simple content based routing (CBR) of |
| messages</a></li> |
| <li><a href="#Sample2">Sample 2: CBR with the Switch-case mediator, |
| using message properties</a></li> |
| <li><a href="#Sample3">Sample 3: Local Registry entry definitions, |
| reusable endpoints and sequences</a></li> |
| <li><a href="#Sample4">Sample 4: Introduction to error handling</a></li> |
| <li><a href="#Sample5">Sample 5: Creating SOAP fault messages and |
| changing the direction of a message</a></li> |
| <li><a href="#Sample6">Sample 6: Manipulating SOAP headers, and |
| filtering incoming and outgoing messages</a></li> |
| <li><a href="#Sample7">Sample 7: Introduction to local Registry entries |
| and using Schema validation</a></li> |
| <li><a href="#Sample8">Sample 8: Introduction to static and dynamic |
| registry resources, and using XSLT transformations</a></li> |
| <li><a href="#Sample9">Sample 9: Introduction to dynamic sequences with |
| the Registry</a></li> |
| <li><a href="#Sample10">Sample 10: Introduction to dynamic endpoints |
| with the Registry</a></li> |
| <li><a href="#Sample11">Sample 11: A full registry based configuration, |
| and sharing a configuration between multiple instances</a></li> |
| <li><a href="#Sample12">Sample 12: One way messaging / fireAndForget |
| through synapse</a></li> |
| </ul> |
| </li> |
| <li><a href="#Endpoints">Advanced mediations with endpoints</a> |
| <ul> |
| <li><a href="#Sample50">Sample 50: POX to SOAP conversion</a></li> |
| <li><a href="#Sample51">Sample 51: MTOM and SwA optimizations and |
| request/response correlation</a></li> |
| <li><a href="#Sample52">Sample 52: Session less load balancing between |
| 3 endpoints</a></li> |
| <li><a href="#Sample53">Sample 53: Failover sending among 3 |
| endpoints</a></li> |
| <li><a href="#Sample54">Sample 54: Session affinity load balancing |
| between 3 endpoints</a></li> |
| <li><a href="#Sample55">Sample 55: Session affinity load balancing |
| between fail over endpoints</a></li> |
| <li><a href="#Sample56">Sample 56: WSDL endpoint</a></li> |
| </ul> |
| </li> |
| <li><a href="#MessageMediationQoS">Quality of Service addition or deduction |
| samples in message mediation</a> |
| <ul> |
| <li><a href="#Sample100">Sample 100: Using WS-Security for outgoing |
| messages</a></li> |
| <li><a href="#Sample101">Sample 101: Reliable message exchange between |
| Synapse and the back-end server using WS-ReliableMessaging</a></li> |
| </ul> |
| </li> |
| <li><a href="#ProxyServices">Synapse Proxy service samples</a> |
| <ul> |
| <li><a href="#Sample150">Sample 150: Introduction to proxy |
| services</a></li> |
| <li><a href="#Sample151">Sample 151: Custom sequences and endpoints |
| with proxy services</a></li> |
| <li><a href="#Sample152">Sample 152: Switching transports and message |
| format from SOAP to REST/POX</a></li> |
| <li><a href="#Sample153">Sample 153: Routing the messages arrived to a |
| proxy service without processing the security headers</a></li> |
| <li><a href="#Sample154">Sample 154: Load Balancing with Proxy Service |
| </a></li> |
| </ul> |
| </li> |
| <li><a href="#ProxyServiceQoS">QoS addition and deduction for service |
| mediation (proxy) samples</a> |
| <ul> |
| <li><a href="#Sample200">Sample 200: Using WS-Security with policy |
| attachments for proxy services</a></li> |
| <li><a href="#Sample201">Sample 201: Reliable message exchange between |
| the client and proxy services using WS-ReliableMessaging</a></li> |
| </ul> |
| </li> |
| <li><a href="#Transport">Transport samples and switching transports</a> |
| <ul> |
| <li><a href="#Sample250">Sample 250: Introduction to switching |
| transports - JMS to http/s</a></li> |
| <li><a href="#Sample251">Sample 251: Switching from http/s to |
| JMS</a></li> |
| <li><a href="#Sample252">Sample 252: Pure text/binary and POX message |
| support with JMS</a></li> |
| <li><a href="#Sample253">Sample 253: One way bridging from JMS to http |
| and replying with a 202 Accepted response</a></li> |
| <li><a href="#Sample254">Sample 254: Using the file system as transport |
| medium using VFS transport listener and sender</a></li> |
| <li><a href="#Sample255">Sample 255: Switching from ftp transport |
| listener to mail transport sender</a></li> |
| <li><a href="#Sample256">Sample 256: Proxy services with the mail |
| transport</a></li> |
| </ul> |
| </li> |
| <li><a href="#Task">Introduction to synapse tasks</a> |
| <ul> |
| <li><a href="#Sample300">Sample 300: Introduction to tasks with simple |
| trigger</a></li> |
| </ul> |
| </li> |
| <li><a href="#AdvancedMediation">Advanced mediations with advanced |
| mediators</a> |
| <ul> |
| <li><a href="#ScriptMediator">Using scripts in mediation (Script |
| Mediator)</a> |
| <ul> |
| <li><a href="#Sample350">Sample 350: Introduction to the script |
| mediator using js scripts</a></li> |
| <li><a href="#Sample351">Sample 351: In-line script mediation with |
| JavaScript</a></li> |
| <li><a href="#Sample352">Sample 352: Accessing Synapse message |
| context API methods using scripting language</a></li> |
| <li><a href="#Sample353">Sample 353: Using Ruby scripts for |
| mediation</a></li> |
| <li><a href="#Sample354">Sample 354: Using In-lined Ruby scripts |
| for mediation</a></li> |
| </ul> |
| </li> |
| <li><a href="#DBMediators">Database interactions in mediation (DBLookup |
| / DBReport)</a> |
| <ul> |
| <li><a href="#Sample360">Sample 360: Introduction to dblookp |
| mediator</a></li> |
| <li><a href="#Sample361">Sample 361: Introduction to dbreport |
| mediator</a></li> |
| <li><a href="#Sample362">Sample 362: Action of dbreport and |
| dblookup mediators together</a></li> |
| </ul> |
| </li> |
| <li><a href="#Throttle">Throtteling messages (Throttle Mediator)</a> |
| <ul> |
| <li><a href="#Sample370">Sample 370: Introduction to throttle |
| mediator and concurrency throttling</a></li> |
| <li><a href="#Sample371">Sample 371: Restricting requests based on |
| policies</a></li> |
| <li><a href="#Sample372">Sample 372: Use of both concurrency |
| throttling and request rate based throttling </a></li> |
| </ul> |
| </li> |
| <li><a href="#Class">Extending the mediation in java (Class |
| Mediator)</a> |
| <ul> |
| <li><a href="#Sample380">Sample 380: Writing your own custom |
| mediation in Java</a></li> |
| </ul> |
| </li> |
| <li><a href="#XQuery">Evaluating XQuery for mediation (XQuery |
| Mediator)</a> |
| <ul> |
| <li><a href="#Sample390">Sample 390: Introduction to the XQuery |
| mediator</a></li> |
| <li><a href="#Sample391">Sample 391: How to use the data from an |
| external XML document with in XQuery </a></li> |
| </ul> |
| </li> |
| <li><a href="#Splitter">Splitting messages in to parts and process in |
| parallel (Iterate / Clone)</a> |
| <ul> |
| <li><a href="#Sample400">Sample 400: Message splitting and |
| aggregating the responses</a></li> |
| </ul> |
| </li> |
| <!--<li><a href="#Aggregator">Aggregating messages and process in batch</a> --> |
| <!--<ul>--> |
| <!--<li><a href="#Sample410">Sample 410: Message splitting and--> |
| <!--aggregating the responses</a></li>--> |
| <!--</ul>--> |
| <!--</li>--> |
| <li><a href="#Cache">Caching the responses over the requests</a> |
| <ul> |
| <li><a href="#Sample420">Sample 420: Simple cache implemented on |
| synapse for the actual service</a></li> |
| </ul> |
| </li> |
| <li><a href="#Callout">Synchronize web service invocation with Callout |
| mediator </a> |
| <ul> |
| <li><a href="#Sample430">Sample 430: Simple Callout Mediator for |
| Synchronize web service invocation</a></li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| |
| <h1><a name="MediationSamples">Message Mediation Samples</a></h1> |
| |
| <h2><a name="Sample0">Sample 0: Introduction to Synapse</a></h2> |
| <pre><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></pre> |
| |
| <p><strong>Objective: Introduction to Synapse. Shows how a message could be |
| made to pass through Synapse </strong><strong>and logged before it is |
| delivered to its ultimate receiver.</strong></p> |
| |
| <p>The Stock quote client can operate in the following modes for this |
| example.</p> |
| <ol> |
| <li>Smart Client mode</li> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ </pre> |
| <li>Using Synapse as a HTTP Proxy</li> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dprxurl=http://localhost:8080/</pre> |
| <li>Gateway Mode / Dumb Client</li> |
| |
| <p>See sample # 1</p> |
| </ol> |
| |
| <p><strong>Prerequisites:<br/> |
| </strong>Start the Synapse configuration numbered 0: e.g. synapse -sample |
| 0<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| deployed</p> |
| |
| <p><strong>Execute the Smart Client </strong></p> |
| |
| <p>By tracing the execution of Synapse with the log output level set to |
| DEBUG, you will see the client request arriving at Synapse with a |
| WS-Addressing 'To' set to EPR |
| http://localhost:9000/soap/SimpleStockQuoteService. The Synapse 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.</p> |
| <pre>Sat Nov 18 21:01:23 IST 2006 SimpleStockQuoteService :: Generating quote for : IBM</pre> |
| |
| <p>The response message generated by the service is again received by |
| Synapse, and flows through the same mediation rules, which logs the response |
| message and then sends it back. This time to the client. On the client |
| console you should see an output similar to the following based on the |
| message received by the client.</p> |
| <pre>Standard :: Stock price = $95.26454380258552</pre> |
| |
| <p><strong>Execute the Proxy Client </strong></p> |
| |
| <p>You will see the exact same behaviour as per the previous example when you |
| run this scenario. However this time the difference is at the client, as it |
| sends the message to the WS-Addressing 'To' address |
| http://localhost:9000/soap/SimpleStockQuoteService, but the transport |
| specifies Synapse as the http proxy. </p> |
| |
| <h2><a name="Sample1">Sample 1: Simple content based routing (CBR) of |
| messages</a></h2> |
| <pre><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> </pre> |
| |
| <p><strong>Objective: Introduction to simple content based routing. Shows how |
| a message could be made to pass through Synapse using the Dumb Client mode, |
| where Synapse acts as a gateway to accept all messages and then perform |
| mediation and routing based on message properties or content.</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 1: i.e. synapse -sample 1<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| deployed<br/> |
| </p> |
| |
| <p>Execute the Dumb Client as: </p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuote<br/></pre> |
| |
| <p>This time you will see Synapse receiving a message for which Synapse was |
| set as the ultimate receiver of the message. Based on the 'To' EPR of |
| http://localhost:8080/soap/StockQuote, Synapse 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.</p> |
| |
| <h2><a name="Sample2">Sample 2: CBR with the Switch-case mediator, using |
| message properties</a></h2> |
| <pre><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></pre> |
| |
| <p><strong>Objective: Introduce switch-case mediator and writing and reading |
| of local properties set on a message instance</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 2: i.e. synapse -sample 2<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done.</p> |
| |
| <p>Execute the 'ant stockquote ..' request again in the smart client mode, |
| specifying 'IBM', 'MSFT' and 'SUN' as the stock symbols. When the symbol IBM |
| is 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.</p> |
| |
| <p>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService |
| -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM</p> |
| <pre>INFO LogMediator - symbol = Great stock - IBM, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService </pre> |
| |
| <p>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService |
| -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT</p> |
| <pre>INFO LogMediator - symbol = Are you sure? - MSFT, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService</pre> |
| |
| <h2><a name="Sample3">Sample 3: Local Registry entry definitions, reusable |
| endpoints and sequences</a></h2> |
| <pre><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></pre> |
| |
| <p><strong>Objective: Illustrates local registry entry definitions, reusable |
| endpoints and sequences</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 3: i.e. synapse -sample 3<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>This example uses a sequence named as "main" that specifies the main |
| mediation rules to be executed. This is equivalent to directly specifying the |
| mediators of the main sequence within the <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".</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre> |
| <pre>DEBUG SequenceMediator - Sequence mediator <main> :: mediate()<br/>DEBUG InMediator - In mediator mediate()<br/>DEBUG SequenceMediator - Sequence mediator <stockquote> :: mediate()</pre> |
| |
| <p>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 Synapse.</p> |
| <pre>[HttpServerWorker-1] INFO LogMediator - Text = Sending quote request, version = 0.1, direction = incoming |
| [HttpServerWorker-1] DEBUG SendMediator - Send mediator :: mediate() |
| [HttpServerWorker-1] DEBUG AddressEndpoint - Sending To: http://localhost:9000/soap/SimpleStockQuoteService </pre> |
| |
| <h2><a name="Sample4">Sample 4: Introduction to error handling</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <!-- the default fault handling sequence used by Synapse - named 'fault' --> |
| <sequence name="fault"> |
| <log level="custom"> |
| <property name="text" value="An unexpected error occured"/> |
| <property name="message" expression="get-property('ERROR_MESSAGE')"/> |
| </log> |
| <drop/> |
| </sequence> |
| |
| <sequence name="sunErrorHandler"> |
| <log level="custom"> |
| <property name="text" value="An unexpected error occured for stock SUN"/> |
| <property name="message" expression="get-property('ERROR_MESSAGE')"/> |
| </log> |
| <drop/> |
| </sequence> |
| |
| <!-- default message handling sequence used by Synapse - named 'main' --> |
| <sequence name="main"> |
| <in> |
| <switch source="//m0:getQuote/m0:request/m0:symbol" xmlns:m0="http://services.samples/xsd"> |
| <case regex="IBM"> |
| <send> |
| <endpoint><address uri="http://localhost:9000/soap/SimpleStockQuoteService"/></endpoint> |
| </send> |
| </case> |
| <case regex="MSFT"> |
| <send> |
| <endpoint key="bogus"/> |
| </send> |
| </case> |
| <case regex="SUN"> |
| <sequence key="sunSequence"/> |
| </case> |
| </switch> |
| <drop/> |
| </in> |
| |
| <out> |
| <send/> |
| </out> |
| </sequence> |
| |
| <sequence name="sunSequence" onError="sunErrorHandler"> |
| <send> |
| <endpoint key="sunPort"/> |
| </send> |
| </sequence> |
| |
| </definitions> </pre> |
| |
| <p><strong>Objective: Introduction to error handling with the 'fault' |
| sequence</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 4: i.e. synapse -sample 4<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>When the IBM stock quote is requested, the configuration routes it to the |
| 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.</p> |
| |
| <p>If you lookup a stock quote for 'MSFT', Synapse is instructed to route the |
| message to the endpoint defined as the 'bogus' endpoint, which does not |
| exist. Synapse executes the specified error handler sequence closest to the |
| point where the error was encountered. In this case, the currently executing |
| sequence is 'main' and it does not specify an 'onError' attribute. Whenever |
| Synapse cannot find an error handler, it looks for a sequence named 'fault'. |
| Thus the 'fault' sequence can be seen executing, and writing the generic |
| error message to the logs. </p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT</pre> |
| <pre>[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</pre> |
| |
| <p>When the 'SUN' quote is requested, a custom sequence 'sunSequence' is |
| invoked, and it specifies 'sunErrorHandler' as its error handler. Hence when |
| the send fails, you could see the proper error handler invocation and the |
| custom error message printed as follows.</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN</pre> |
| <pre>[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</pre> |
| |
| <h2><a name="Sample5">Sample 5: Creating SOAP fault messages and changing the |
| direction of a message</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <sequence name="myFaultHandler"> |
| <makefault> |
| <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/> |
| <reason expression="get-property('ERROR_MESSAGE')"/> |
| </makefault> |
| |
| <property name="RESPONSE" value="true"/> |
| <header name="To" expression="get-property('ReplyTo')"/> |
| <send/> |
| </sequence> |
| |
| <sequence name="main" onError="myFaultHandler"> |
| <in> |
| <switch source="//m0:getQuote/m0:request/m0:symbol" |
| xmlns:m0="http://services.samples/xsd"> |
| <case regex="MSFT"> |
| <send> |
| <endpoint><address uri="http://bogus:9000/soap/NonExistentStockQuoteService"/></endpoint> |
| </send> |
| </case> |
| <case regex="SUN"> |
| <send> |
| <endpoint><address uri="http://localhost:9009/soap/NonExistentStockQuoteService"/></endpoint> |
| </send> |
| </case> |
| </switch> |
| <drop/> |
| </in> |
| |
| <out> |
| <send/> |
| </out> |
| </sequence> |
| |
| </definitions></pre> |
| |
| <p><strong>Objective: Makefault mediator and sending back error responses |
| </strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 5: i.e. synapse -sample 5<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>When the MSFT stock quote is requested, an unknown host exception would be |
| 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.</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT</pre> |
| |
| <p>returns,</p> |
| <pre><soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><faultcode>soapenv:Client</faultcode> |
| <faultstring>java.net.UnknownHostException: bogus</faultstring><detail /></soapenv:Fault></pre> |
| |
| <p>And</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN</pre> |
| |
| <p>returns,</p> |
| <pre><soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><faultcode>soapenv:Client</faultcode> |
| <faultstring>java.net.ConnectException: Connection refused</faultstring><detail /></soapenv:Fault></pre> |
| |
| <h2><a name="Sample6">Sample 6: Manipulating SOAP headers, and filtering |
| incoming and outgoing messages</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <in> |
| <header name="To" value="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </in> |
| <send/> |
| </definitions></pre> |
| |
| <p><strong>Objective: Introduction to header, in (out) mediators</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 6: i.e. synapse -sample 6<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>In this example we use the stockquote client in the dumb client mode, |
| setting the 'To' EPR of the message to Synapse. Then the 'in' mediator |
| processes the incoming messages, and manipulates the 'To' header to refer to |
| the stock quote service on the sample Axis2 server. Thus it is now possible |
| to request for a stock quote as follows.</p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/</pre> |
| |
| <h2><a name="Sample7">Sample 7: Introduction to local Registry entries and |
| using Schema validation</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <localEntry key="validate_schema"> |
| <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" |
| xmlns="http://www.apache-synapse.org/test" elementFormDefault="qualified" |
| attributeFormDefault="unqualified" |
| targetNamespace="http://services.samples/xsd"> |
| <xs:element name="getQuote"> |
| <xs:complexType> |
| <xs:sequence> |
| <xs:element name="request"> |
| <xs:complexType> |
| <xs:sequence> |
| <xs:element name="stocksymbol" type="xs:string"/> |
| </xs:sequence> |
| </xs:complexType> |
| </xs:element> |
| </xs:sequence> |
| </xs:complexType> |
| </xs:element> |
| </xs:schema> |
| </localEntry> |
| |
| <in> |
| <validate> |
| <schema key="validate_schema"/> |
| <on-fail> |
| <!-- if the request does not validate againt schema throw a fault --> |
| <makefault> |
| <code value="tns:Receiver" |
| xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/> |
| <reason value="Invalid custom quote request"/> |
| </makefault> |
| <property name="RESPONSE" value="true"/> |
| <header name="To" expression="get-property('ReplyTo')"/> |
| </on-fail> |
| </validate> |
| </in> |
| <send/> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Introduction to local (static) registry entries and the |
| validate mediator</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 7: i.e. synapse -sample 7<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>This example shows how a static XML fragment could be made available to |
| the Synapse local registry. Resources defined 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'.</p> |
| |
| <p>The validate mediator by default operates on the first child element of |
| the SOAP body. You may specify an XPath expression using the 'source' |
| attribute to override this behaviour. The validate mediator now uses the |
| 'validate_schema' resource to validate the incoming message, and if the |
| message validatation fails it invokes the 'on-fail' sequence of mediators.</p> |
| |
| <p>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)</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre> |
| |
| <h2><a name="Sample8">Sample 8: Introduction to static and dynamic registry |
| resources, and using XSLT transformations</a></h2> |
| <pre><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></pre> |
| |
| <p><strong>Objective: Introduction to static and dynamic registry resources |
| and the XSLT mediator</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 8: i.e. synapse -sample 8<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>This example uses the XSLT mediator to perform transformations, and the |
| xslt tranformations are specified as registry resources. The first resource |
| 'xslt-key-req' is specified as a 'local' registry entry. Local entries do not |
| place the resource on the registry, but simply 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.</p> |
| |
| <p>In this example you will notice the new 'registry' definition. Synapse |
| comes with a simple URL based registry implementation SimpleURLRegistry. |
| During initialization of the registry, the SimpleURLRegistry expects to find |
| a property named 'root', which specifies a prefix for the registry keys used |
| later. When the SimpleURLRegistry is used, this root is prefixed to the entry |
| keys to form the complete URL for the resource being looked up. The registry |
| caches a resource once requested, and caches it internally for a specified |
| duration. Once this period expires, it will reload the meta information about |
| the resource and reload its cached copy if necessary, the next time the |
| resource is requested.</p> |
| |
| <p>Hence the second XSLT resource key 'transform/transform_back.xslt' |
| concatenated with the 'root' of the SimpleURLRegistry |
| 'file:repository/conf/sample/resources/' forms the complete URL of the |
| resource as |
| 'file:repository/conf/sample/resources/transform/transform_back.xslt' and |
| caches its value for a period of 15000 ms.</p> |
| |
| <p>Execute the custom quote client as 'ant stockquote -Dmode=customquote ...' |
| and analyze the the Synapse debug log output</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote</pre> |
| |
| <p>The incoming message is now transformed into a standard stock quote |
| request as expected by the SimpleStockQuoteService deployed on the local |
| Axis2 instance, by the XSLT mediator. The XSLT mediator uses Xalan-J to |
| perform the transformations. It is possible to configure the underlying |
| transformation engine using properties where necessary. The response from the |
| SimpleStockQuoteService is converted back into the custom format as expected |
| by the client during the out message processing.</p> |
| |
| <p>During the response processing you could see the SimpleURLRegistry |
| fetching the resource as shown by the log message below</p> |
| <pre>[HttpClientWorker-1] INFO SimpleURLRegistry - ==> Repository fetch of resource with key : transform/transform_back.xslt</pre> |
| |
| <p>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.</p> |
| |
| <p>However if you leave the system idle for 15 seconds or more and then retry |
| the same request, you will now notice that the registry noticed the 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.</p> |
| <pre>[HttpClientWorker-1] DEBUG AbstractRegistry - Cached object has expired for key : transform/transform_back.xslt |
| [HttpClientWorker-1] DEBUG SimpleURLRegistry - Perform RegistryEntry lookup for key : transform/transform_back.xslt |
| [HttpClientWorker-1] DEBUG AbstractRegistry - Expired version number is same as current version in registry |
| [HttpClientWorker-1] DEBUG AbstractRegistry - Renew cache lease for another 15s </pre> |
| |
| <p>Now edit the |
| repository/conf/sample/resources/transform/transform_back.xslt file and add a |
| blank line at the end. Now when you run the client again, and if the cache is |
| expired, the resource would be re-fetched from its URL by the registry and |
| this can be seen by the following debug log messages</p> |
| <pre>[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 </pre> |
| |
| <p>Thus the SimpleURLRegistry allows resource to be cached, and updates |
| detected so that the changes could be reloaded without restarting the Synapse |
| instance.</p> |
| |
| <h2><a name="Sample9">Sample 9: Introduction to dynamic sequences with the |
| Registry</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"> |
| <parameter name="root">file:./repository/conf/sample/resources/</parameter> |
| <parameter name="cachableDuration">15000</parameter> |
| </registry> |
| |
| <sequence key="sequence/dynamic_seq_1.xml"/> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Introduction to dynamic sequences with a |
| Registry</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 9: i.e. synapse -sample 9<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>This example introduces the dynamic behaviour of Synapse through the use |
| of a Registry. Synapse supports dynamic definitions for sequences 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 Synapse at runtime, and cached |
| appropriately as per its definition in the registry. Once the cache expires, |
| Synapse would recheck the meta information for the definition and re-load the |
| sequence definition if necessary and re-cache it again.</p> |
| |
| <p>Once Synapse is started, execute the stock quote client as 'ant |
| stockquote..'. You will notice that that Synapse fetches the definition of |
| the sequence from the registry and executes its rules as follows:</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre> |
| <pre>[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 ***</pre> |
| |
| <p>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 Synapse from |
| the following log messages.</p> |
| <pre>[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 ***</pre> |
| |
| <p>The cache timeout could be tuned appropriately by configuring the URL |
| registry to suite the environment and the needs.</p> |
| |
| <h2><a name="Sample10">Sample 10: Introduction to dynamic endpoints with the |
| Registry</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"> |
| <parameter name="root">file:repository/conf/sample/resources/</parameter> |
| <parameter name="cachableDuration">15000</parameter> |
| </registry> |
| |
| <in> |
| <send> |
| <endpoint key="endpoint/dynamic_endpt_1.xml"/> |
| </send> |
| </in> |
| <out> |
| <send/> |
| </out> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Introduction to dynamic endpoints with the |
| Registry</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 10: i.e. synapse -sample 10<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done<br/> |
| Start a second Axis2 server on http port 9001 and https port 9003 as |
| follows:</p> |
| <pre>./axis2server.sh -http 9001 -https 9003</pre> |
| |
| <p>This example introduces dynamic endpoints, where the definition of an |
| endpoint is stored in the Registry. To follow this example execute the stock |
| quote client as 'ant stockquote..' and see that the message is routed to the |
| SimpleStockQuoteService on the default Axis2 instance on http port 9000. |
| Repeat the above example immediately again, and notice that the endpoint is |
| cached and reused by Synapse - similarly to example # 8.</p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/</pre> |
| |
| <p>Now edit the repository/conf/sample/resources/endpoint/dynamic_endpt_1.xml |
| definition and update the address to |
| "http://localhost:9001/soap/SimpleStockQuoteService". After the cached |
| expires, the Registry loads the new definition of the endpoint, and then the |
| messages can be seen being routed to the second sample Axis2 server on http |
| port 9001.</p> |
| |
| <h2><a name="Sample11">Sample 11: A full registry based configuration, and |
| sharing a configuration between multiple instances</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"> |
| <parameter name="root">file:./repository/conf/sample/resources/</parameter> |
| <parameter name="cachableDuration">15000</parameter> |
| </registry> |
| </definitions> </pre> |
| |
| <p><strong>Objective: A full registry based configuration</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 11: i.e. synapse -sample 11<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>This example shows a full registry based Synapse configuration. Thus it is |
| possible to start a remote configuration from multiple instances of Synapse |
| in a clustered environment easily. The Synapse configuration held on a node |
| hosting Synapse simply points to the registry and looks up the actual |
| configuration by requesting the key 'synapse.xml'. </p> |
| |
| <p>(Note: Full registry based configuration is not dynamic atleast for the |
| moment. i.e. it is not reloading itself) </p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre> |
| <pre>[HttpServerWorker-1] INFO LogMediator - message = This is a dynamic Synapse configuration</pre> |
| |
| <p>The actual synapse.xml loaded is:</p> |
| <pre><!-- 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></pre> |
| |
| <h2><a name="Sample12">Sample 12: One way messaging / fireAndForget through |
| synapse</a></h2> |
| |
| <p><strong>Objective: Demonstrate one way messaging / fireAndForget through |
| synapse</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService (Refer steps |
| above)<br/> |
| Start the Synapse configuration numbered 1: i.e. synapse -sample 1</p> |
| |
| <p>This example invokes the one-way 'placeOrder' operation on the |
| SimpleStockQuoteService using the custom client which uses the Axis2 |
| ServiceClient.fireAndForget() API. To test this, use 'ant |
| -Dmode=placeorder...' and you will notice the one way message flowing through |
| Synapse into the sample Axis2 server instance, which reports the acceptance |
| of the order as follows:</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=placeorder</pre> |
| <pre>SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733</pre> |
| |
| <p>If you send your client request through TCPmon, you will notice that the |
| SimpleStockQuoteService replies to Synapse with a HTTP 202 reply, and that |
| Synapse in-turn replies to the client with a HTTP 202 acknowledgement</p> |
| |
| <h1><a name="Endpoints">Advanced mediations with endpoints</a></h1> |
| |
| <h2><a name="Sample50">Sample 50: POX to SOAP conversion</a></h2> |
| <pre><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> </pre> |
| |
| <p><strong>Objective: POX to SOAP conversion</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 50: i.e. synapse -sample 50</p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| |
| <p>Execute the 'ant stockquote' specifying that the request should be a REST |
| request as follows:</p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuote -Drest=true</pre> |
| |
| <p>This example shows a http REST request (as shown below) being transformed |
| into a SOAP request and forwarded to the stock quote service. </p> |
| <pre>POST /soap/StockQuote HTTP/1.1 |
| Content-Type: application/xml; charset=UTF-8;action="urn:getQuote"; |
| SOAPAction: urn:getQuote |
| User-Agent: Axis2 |
| Host: 127.0.0.1 |
| Transfer-Encoding: chunked |
| |
| 75 |
| <m0:getQuote xmlns:m0="http://services.samples/xsd"> |
| <m0:request> |
| <m0:symbol>IBM</m0:symbol> |
| </m0:request> |
| </m0:getQuote>0</pre> |
| |
| <h2><a name="Sample51">Sample 51: MTOM and SwA optimizations and |
| request/response correlation</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <in> |
| <filter source="get-property('Action')" regex="urn:uploadFileUsingMTOM"> |
| <property name="example" value="mtom"/> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/MTOMSwASampleService" optimize="mtom"/> |
| </endpoint> |
| </send> |
| </filter> |
| <filter source="get-property('Action')" regex="urn:uploadFileUsingSwA"> |
| <property name="example" value="swa"/> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/MTOMSwASampleService" optimize="swa"/> |
| </endpoint> |
| </send> |
| </filter> |
| </in> |
| <out> |
| <filter source="get-property('example')" regex="mtom"> |
| <property name="enableMTOM" value="true" scope="axis2"/> |
| </filter> |
| <filter source="get-property('example')" regex="swa"> |
| <property name="enableSwA" value="true" scope="axis2"/> |
| </filter> |
| <send/> |
| </out> |
| </definitions></pre> |
| |
| <p><strong>Objective: MTOM and SwA optimizations and request/response |
| correlation</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 51: i.e. synapse -sample 51<br/> |
| Start the Axis2 server and deploy the MTOMSwASampleService if not already |
| done</p> |
| |
| <p>Execute the 'ant optimizeclient' specifying MTOM optimization as |
| follows:</p> |
| <pre>ant optimizeclient -Dopt_mode=mtom</pre> |
| |
| <p>The configuration now sets a local message context property, and forwards |
| the message to 'http://localhost:9000/soap/MTOMSwASampleService' optimizing |
| 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 Synapse |
| could identify the past information about the current message context, and |
| uses this knowledge to transform the response back to the client in the same |
| format as the original request.</p> |
| |
| <p>When the client executes successfully, it will upload a file containing |
| the ASF logo and receive its response back again and save it into a temporary |
| file.</p> |
| <pre>[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as MTOM</pre> |
| <pre>[java] Saved response to file : /tmp/mtom-36877.gif</pre> |
| |
| <p>Next try SwA as:</p> |
| <pre>ant optimizeclient -Dopt_mode=swa</pre> |
| <pre>[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as SwA |
| [java] Saved response to file : /tmp/swa-47549.gif</pre> |
| |
| <p>By using TCPMon and sending the message through it, one can inspect that |
| the requests and responses sent are indeed MTOM optimized or sent as http |
| attachments as follows:</p> |
| <pre>POST http://localhost:9000/soap/MTOMSwASampleService HTTP/1.1 |
| Host: 127.0.0.1 |
| SOAPAction: urn:uploadFileUsingMTOM |
| Content-Type: multipart/related; boundary=MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177413845353; type="application/xop+xml"; |
| start="<0.urn:uuid:B94996494E1DD5F9B51177413845354@apache.org>"; start-info="text/xml"; charset=UTF-8 |
| Transfer-Encoding: chunked |
| Connection: Keep-Alive |
| User-Agent: Synapse-HttpComponents-NIO |
| |
| --MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177413845353241 |
| Content-Type: application/xop+xml; charset=UTF-8; type="text/xml" |
| Content-Transfer-Encoding: binary |
| Content-ID: |
| <0.urn:uuid:B94996494E1DD5F9B51177413845354@apache.org>221b1 |
| <?xml version='1.0' encoding='UTF-8'?> |
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soapenv:Body> |
| <m0:uploadFileUsingMTOM xmlns:m0="http://www.apache-synapse.org/test"> |
| <m0:request> |
| <m0:image> |
| <xop:Include href="cid:1.urn:uuid:78F94BC50B68D76FB41177413845003@apache.org" xmlns:xop="http://www.w3.org/2004/08/xop/include" /> |
| </m0:image> |
| </m0:request> |
| </m0:uploadFileUsingMTOM> |
| </soapenv:Body> |
| </soapenv:Envelope> |
| --MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177413845353217 |
| Content-Type: image/gif |
| Content-Transfer-Encoding: binary |
| Content-ID: |
| <1.urn:uuid:78F94BC50B68D76FB41177413845003@apache.org>22800GIF89a... << binary content >></pre> |
| <pre>POST http://localhost:9000/soap/MTOMSwASampleService HTTP/1.1 |
| Host: 127.0.0.1 |
| SOAPAction: urn:uploadFileUsingSwA |
| Content-Type: multipart/related; boundary=MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177414170491; type="text/xml"; |
| start="<0.urn:uuid:B94996494E1DD5F9B51177414170492@apache.org>"; charset=UTF-8 |
| Transfer-Encoding: chunked |
| Connection: Keep-Alive |
| User-Agent: Synapse-HttpComponents-NIO |
| |
| --MIMEBoundaryurn_uuid_B94996494E1DD5F9B51177414170491225 |
| Content-Type: text/xml; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| Content-ID: |
| <0.urn:uuid:B94996494E1DD5F9B51177414170492@apache.org>22159 |
| <?xml version='1.0' encoding='UTF-8'?> |
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soapenv:Body> |
| <m0:uploadFileUsingSwA xmlns:m0="http://www.apache-synapse.org/test"> |
| <m0:request> |
| <m0:imageId>urn:uuid:15FD2DA2584A32BF7C1177414169826</m0:imageId> |
| </m0:request> |
| </m0:uploadFileUsingSwA> |
| </soapenv:Body> |
| </soapenv:Envelope>22--34MIMEBoundaryurn_uuid_B94996494E1DD5F9B511774141704912 |
| 17 |
| Content-Type: image/gif |
| Content-Transfer-Encoding: binary |
| Content-ID: |
| <urn:uuid:15FD2DA2584A32BF7C1177414169826>22800GIF89a... << binary content >></pre> |
| |
| <h2><a name="Sample52">Sample 52: Session less load balancing between 3 |
| endpoints</a></h2> |
| <pre><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></pre> |
| |
| <p><strong>Objective: Demonstrate the simple load balancing among set of |
| endpoints</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start Synapse with sample configuration 52. (i.e. synapse -sample 52)</p> |
| |
| <p>Deploy the LoadbalanceFailoverService by switching to <synapse |
| installation directory>/samples/axis2Server/src/LoadbalanceFailoverService |
| directory and running ant.</p> |
| |
| <p>Start three instances of sample Axis2 server on HTTP ports 9001, 9002 and |
| 9003 and give some unique names to each server.</p> |
| |
| <p>Example commands to run sample Axis2 servers from the <synapse |
| installation directory>/samples/axis2Server directory in Linux are listed |
| below:</p> |
| <pre>./axis2server.sh -http 9001 -https 9005 -name MyServer1 |
| ./axis2server.sh -http 9002 -https 9006 -name MyServer2 |
| ./axis2server.sh -http 9003 -https 9007 -name MyServer3</pre> |
| |
| <p>Now we are done with setting up the environment for load balance sample. |
| Start the load balance and failover client using the following command:</p> |
| <pre>ant loadbalancefailover -Di=100</pre> |
| |
| <p>This client sends 100 requests to the LoadbalanceFailoverService through |
| Synapse. Synapse will distribute the load among the three endpoints mentioned |
| in the configuration in round-robin manner. LoadbalanceFailoverService |
| appends the name of the server to the response, so that client can determine |
| which server has processed the message. If you examine the console output of |
| the client, you can see that requests are processed by three servers as |
| follows:</p> |
| <pre>[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 |
| ...</pre> |
| |
| <p>Now run the client without the -Di=100 parameter to send infinite |
| requests. While running the client shutdown the server named MyServer1. You |
| can observe that requests are only distributed among MyServer2 and MyServer3 |
| after shutting down MyServer1. Console output before and after shutting down |
| MyServer1 is listed below (MyServer1 was shutdown after request 63):</p> |
| <pre>... |
| [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 |
| ...</pre> |
| |
| <p>Now restart MyServer1. You can observe that requets will be again sent to |
| all three servers roughly after 60 seconds. This is because we have specified |
| <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. </p> |
| |
| <h2><a name="Sample53">Sample 53: Failover sending among 3 endpoints</a></h2> |
| <pre><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></pre> |
| |
| <p><strong>Objective: Demonstrate the failover sending</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start Synapse with sample configuration 53 (i.e. synapse -sample 53)</p> |
| |
| <p>Deploy the LoadbalanceFailoverService and start three instances of sample |
| Axis2 server as mentioned in sample 52.</p> |
| |
| <p></p> |
| |
| <p>Above configuration sends messages with the failover behavior. Initially |
| the server at port 9001 is treated as primary and other two are treated as |
| back ups. Messages are always directed only to the primary server. If the |
| primary server has failed, next listed server is selected as the primary. |
| Thus, messages are sent successfully as long as there is at least one active |
| server. To test this, run the loadbalancefailover client to send infinite |
| requests as follows:</p> |
| <pre>ant loadbalancefailover</pre> |
| |
| <p>You can see that all requests are processed by MyServer1. Now shutdown |
| MyServer1 and inspect the console output of the client. You will observe that |
| all subsequent requests are processed by MyServer2.</p> |
| |
| <p>The console output with MyServer1 shutdown after request 127 is listed |
| below:</p> |
| <pre>... |
| [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 |
| ...</pre> |
| |
| <p>You can keep on shutting down servers like this. Client will get a |
| response till you shutdown all listed servers. Once all servers are shutdown, |
| the error sequence is activated and a fault message is sent to the client as |
| follows.</p> |
| <pre>[java] COULDN'T SEND THE MESSAGE TO THE SERVER.</pre> |
| |
| <p>Once a server is detected as failed, it will be added to the active |
| servers list again after 60 seconds (specified in |
| <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.</p> |
| |
| <h2><a name="Sample54">Sample 54: Session affinity load balancing between 3 |
| endpoints</a></h2> |
| <pre><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 --> |
| <strong><session type="simpleClientSession"/></strong> |
| |
| <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></pre> |
| |
| <p><strong>Objective: Demonstrate the load balancing with session affinity |
| using client initiated sessions</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start Synapse with sample configuration 54 (i.e. synapse -sample 54).</p> |
| |
| <p>Deploy the LoadbalanceFailoverService and start three instances of the |
| sample Axis2 server as in sample 52. </p> |
| |
| <p></p> |
| |
| <p>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. Synapse binds this ID with a server on the first request and |
| sends all seccessive requests containing that ID to the same server. Now |
| switch to samples/axis2Client directory and run the client using the |
| following command to check this in action.</p> |
| <pre>ant loadbalancefailover -Dmode=session</pre> |
| |
| <p>In the session mode, client continuesly sends requests with three diferent |
| client (session) IDs. One ID is selected among these three IDs for each |
| request randomly. Then client prints the session ID with the responded server |
| for each request. Client output for the first 10 requests are shown below.</p> |
| <pre>[java] Request: 1 Session number: 1 Response from server: MyServer3 |
| [java] Request: 2 Session number: 2 Response from server: MyServer2 |
| [java] Request: 3 Session number: 0 Response from server: MyServer1 |
| [java] Request: 4 Session number: 2 Response from server: MyServer2 |
| [java] Request: 5 Session number: 1 Response from server: MyServer3 |
| [java] Request: 6 Session number: 2 Response from server: MyServer2 |
| [java] Request: 7 Session number: 2 Response from server: MyServer2 |
| [java] Request: 8 Session number: 1 Response from server: MyServer3 |
| [java] Request: 9 Session number: 0 Response from server: MyServer1 |
| [java] Request: 10 Session number: 0 Response from server: MyServer1 |
| ... </pre> |
| |
| <p>You can see that session number 0 is always directed to the server named |
| MyServer1. That means session number 0 is bound to MyServer1. Similarly |
| session 1 and 2 are bound to MyServer3 and MyServer2 respectively. </p> |
| |
| <h2><a name="Sample55">Sample 55: Session affinity load balancing between |
| fail over endpoints</a></h2> |
| <pre><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 --> |
| <strong><session type="simpleClientSession"/></strong> |
| |
| <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></pre> |
| |
| <p><strong>Objective: Demonstrate the session affinity based load balancing |
| with failover capability</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start Synapse with sample configuration 55 (i.e. synapse -sample 55).</p> |
| |
| <p>Deploy the LoadbalanceFailoverService and start four sample Axis2 servers |
| on http ports 9001, 9002, 9003 and 9004 respectively (make sure to specify |
| unconflicting https ports).</p> |
| |
| <p></p> |
| |
| <p>This configuration also uses "simpleClientSession" to bind sessions as in |
| the previous sample. But failover endpoints are specified as the child |
| endpoints of the load balance endpoint. Therefore sessions are bound to the |
| failover endpoints. Session information has to be replicated among the |
| servers listed under each failover endpoint using some clustering mechanism. |
| Therefore, if one endpoint bound to a session failed, successive requets for |
| that session will be directed to the next endpoint in that failover group. |
| Run the client using the following command to observe this behavoir.</p> |
| <pre>ant loadbalancefailover -Dmode=session</pre> |
| |
| <p>You can see a client output as shown below.</p> |
| <pre>... |
| [java] Request: 222 Session number: 0 Response from server: MyServer1 |
| [java] Request: 223 Session number: 0 Response from server: MyServer1 |
| [java] Request: 224 Session number: 1 Response from server: MyServer1 |
| [java] Request: 225 Session number: 2 Response from server: MyServer3 |
| [java] Request: 226 Session number: 0 Response from server: MyServer1 |
| [java] Request: 227 Session number: 1 Response from server: MyServer1 |
| [java] Request: 228 Session number: 2 Response from server: MyServer3 |
| [java] Request: 229 Session number: 1 Response from server: MyServer1 |
| [java] Request: 230 Session number: 1 Response from server: MyServer1 |
| [java] Request: 231 Session number: 2 Response from server: MyServer3 |
| ...</pre> |
| |
| <p>Note that session 0 is always directed to MyServer1 and session 1 is |
| directed to MyServer3. No requests are directed to MyServer2 and MyServer4 as |
| they are kept as backups by failover endpoints. Now shutdown the server named |
| MyServer1 while running the sample. You will observer that all successive |
| requests for session 0 is now directed to MyServer2, which is the backup |
| server for MyServer1's group. This is shown below, where MyServer1 was |
| shutdown after the request 534.</p> |
| <pre>... |
| [java] Request: 529 Session number: 2 Response from server: MyServer3 |
| [java] Request: 530 Session number: 1 Response from server: MyServer1 |
| [java] Request: 531 Session number: 0 Response from server: MyServer1 |
| [java] Request: 532 Session number: 1 Response from server: MyServer1 |
| [java] Request: 533 Session number: 1 Response from server: MyServer1 |
| [java] Request: 534 Session number: 1 Response from server: MyServer1 |
| [java] Request: 535 Session number: 0 Response from server: MyServer2 |
| [java] Request: 536 Session number: 0 Response from server: MyServer2 |
| [java] Request: 537 Session number: 0 Response from server: MyServer2 |
| [java] Request: 538 Session number: 2 Response from server: MyServer3 |
| [java] Request: 539 Session number: 0 Response from server: MyServer2 |
| ...</pre> |
| |
| <h2><a name="Sample56">Sample 56: WSDL endpoint</a></h2> |
| <pre><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></pre> |
| |
| <p><strong>Objective: Demonstrate the use of WSDL endpoints</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start the Synapse configuration numbered 56 (i.e. synapse -sample 56).</p> |
| |
| <p>Deploy the SimpleStockQuoteService and start the sample Axis2 server.</p> |
| |
| <p>This sample uses a WSDL endpoint inside the send mediator. WSDL endpoints |
| can extract endpoint's address from the given WSDL. As WSDL documents can |
| have many services and many ports inside each service, the service and port |
| of the required endpoint has to be specified. As with address endpoints, QoS |
| parameters for the endpoint can be specified inline in the configuration. An |
| excerpt taken from the sample_proxy_1.wsdl containing the specified service |
| and port is listed below.</p> |
| <pre><wsdl:service name="SimpleStockQuoteService"> |
| <wsdl:port name="SimpleStockQuoteServiceSOAP11port_http" |
| binding="axis2:SimpleStockQuoteServiceSOAP11Binding"> |
| <soap:address location="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </wsdl:port> |
| <wsdl:port name="SimpleStockQuoteServiceSOAP12port_http" |
| binding="axis2:SimpleStockQuoteServiceSOAP12Binding"> |
| <soap12:address location="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </wsdl:port> |
| </wsdl:service></pre> |
| |
| <p>Specified service and port refers to the endpoint address |
| "http://localhost:9000/soap/SimpleStockQuoteService" according to the above |
| WSDL. Now run the client using the following command.</p> |
| <pre>ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080</pre> |
| |
| <p>Client will print the quote price for IBM received from the server running |
| on port 9000. Observe the Axis2 console and the Synapse console to verify |
| this behavior.</p> |
| |
| <h1><a name="MessageMediationQoS">Quality of Service addition or deduction |
| samples in message mediation</a></h1> |
| |
| <h2><a name="Sample100">Sample 100: Using WS-Security for outgoing |
| messages</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <localEntry key="sec_policy" src="file:repository/conf/sample/resources/policy/policy_3.xml"/> |
| |
| <in> |
| <send> |
| <endpoint name="secure"> |
| <address uri="http://localhost:9000/soap/SecureStockQuoteService"> |
| <enableSec policy="sec_policy"/> |
| <enableAddressing/> |
| </address> |
| </endpoint> |
| </send> |
| </in> |
| <out> |
| <header name="wsse:Security" action="remove" |
| xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/> |
| <send/> |
| </out> |
| </definitions></pre> |
| |
| <p><strong>Objective: Connecting to endpoints with WS-Security for outgoing |
| messages</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| </p> |
| |
| <p>You may also need to download and install the unlimited strength policy |
| files for your JDK before using Apache Rampart (e.g. see |
| http://java.sun.com/javase/downloads/index_jdk5.jsp)</p> |
| |
| <p>Start the Synapse configuration numbered 100: i.e. synapse -sample 100<br/> |
| Start the Axis2 server and deploy the SecureStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>Use the stock quote client to send a request without WS-Security. Synapse |
| is configured to enable WS-Security as per the policy specified by |
| 'policy_3.xml' for the outgoing messages to the SecureStockQuoteService |
| endpoint hosted on the Axis2 instance. The debug log messages on Synapse |
| shows the encrypted message flowing to the service and the encrypted response |
| being received by Synapse. The wsse:Security header is then removed from the |
| decrypted message and the response is delivered back to the client, as |
| expected. You may execute the client as follows:</p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/</pre> |
| |
| <p>The message sent by Synapse to the secure service can be seen as follows, |
| when TCPMon is used.</p> |
| <pre>POST http://localhost:9001/soap/SecureStockQuoteService HTTP/1.1 |
| Host: 127.0.0.1 |
| SOAPAction: urn:getQuote |
| Content-Type: text/xml; charset=UTF-8 |
| Transfer-Encoding: chunked |
| Connection: Keep-Alive |
| User-Agent: Synapse-HttpComponents-NIO |
| |
| 800 |
| <?xml version='1.0' encoding='UTF-8'?> |
| <soapenv:Envelope xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsa="http://www.w3.org/2005/08/addressing" ..> |
| <soapenv:Header> |
| <wsse:Security ..> |
| <wsu:Timestamp ..> |
| ... |
| </wsu:Timestamp> |
| <xenc:EncryptedKey..> |
| ... |
| </xenc:EncryptedKey> |
| <wsse:BinarySecurityToken ...> |
| <ds:SignedInfo> |
| ... |
| </ds:SignedInfo> |
| <ds:SignatureValue> |
| ... |
| </ds:SignatureValue> |
| <ds:KeyInfo Id="KeyId-29551621"> |
| ... |
| </ds:KeyInfo> |
| </ds:Signature> |
| </wsse:Security> |
| <wsa:To>http://localhost:9001/soap/SecureStockQuoteService</wsa:To> |
| <wsa:MessageID>urn:uuid:1C4CE88B8A1A9C09D91177500753443</wsa:MessageID> |
| <wsa:Action>urn:getQuote</wsa:Action> |
| </soapenv:Header> |
| <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-3789605"> |
| <xenc:EncryptedData Id="EncDataId-3789605" Type="http://www.w3.org/2001/04/xmlenc#Content"> |
| <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" /> |
| <xenc:CipherData> |
| <xenc:CipherValue>Layg0xQcnH....6UKm5nKU6Qqr</xenc:CipherValue> |
| </xenc:CipherData> |
| </xenc:EncryptedData> |
| </soapenv:Body> |
| </soapenv:Envelope>0</pre> |
| |
| <h2><a name="Sample101">Sample 101: Reliable message exchange between Synapse |
| and the back-end server using WS-ReliableMessaging</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <in> |
| <RMSequence single="true" version="1.0"/> |
| <send> |
| <endpoint name="reliable"> |
| <address uri="http://localhost:9000/soap/ReliableStockQuoteService"> |
| <enableRM/> |
| <enableAddressing/> |
| </address> |
| </endpoint> |
| </send> |
| </in> |
| <out> |
| <header name="wsrm:SequenceAcknowledgement" action="remove" |
| xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/> |
| <header name="wsrm:Sequence" action="remove" |
| xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/> |
| <send/> |
| </out> |
| |
| </definitions></pre> |
| <strong>Objective: Demonstrate the message exchange between Synapse and the |
| server using WS-ReliableMessaging (WS-RM)</strong> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Deploy the ReliableStockQuoteService in the sample Axis2 server by |
| switching to the samples/axis2Server/src/ReliableStockQuoteService directory |
| and running ant.</p> |
| |
| <p>Start the sample Axis2 server on port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 101 (i.e. synapse -sample |
| 101).</p> |
| |
| <p></p> |
| |
| <p>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 Synapse configuration |
| language documentation for more information about the RMSequence mediator. RM |
| related SOAP headers are removed form the message in the out mediator as |
| WS-RM message exchange happens only between the Synapse and the server. Now |
| run the sample client using the following command.</p> |
| <pre>ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080</pre> |
| |
| <p>You can observer the client output displaying the quote price for IBM as |
| follows:</p> |
| <pre>[java] Standard :: Stock price = $189.2521262517493</pre> |
| |
| <p>There is no difference to be observed between the normal message exchange |
| and WS-RM enabled message exchange as far as client and server outputs are |
| considered. But if you look at the wire level messages, you would observe |
| additional WS-RM messages and WS-RM elements. Synapse, the initiator of the |
| RM sequence, first try to create a sequence by sending a message with |
| CreateSequence element.</p> |
| <pre>... |
| <soapenv:Body> |
| <wsrm:CreateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"> |
| <wsrm:AcksTo> |
| <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address> |
| </wsrm:AcksTo> |
| <wsrm:Offer> |
| <wsrm:Identifier>urn:uuid:546F6F33FB7D8BBE351179807372769</wsrm:Identifier> |
| </wsrm:Offer> |
| </wsrm:CreateSequence> |
| </soapenv:Body> |
| ...</pre> |
| |
| <p>Sample Axis2 server responds to CreateSequence request with the following |
| message:</p> |
| <pre>... |
| <soapenv:Body> |
| <wsrm:CreateSequenceResponse xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"> |
| <wsrm:Identifier>urn:uuid:879853A6871A66641C1179807373270</wsrm:Identifier> |
| <wsrm:Accept> |
| <wsrm:AcksTo> |
| <wsa:Address>http://localhost:9000/soap/ReliableStockQuoteService</wsa:Address> |
| </wsrm:AcksTo> |
| </wsrm:Accept> |
| </wsrm:CreateSequenceResponse> |
| </soapenv:Body> |
| ...</pre> |
| |
| <p>Once the sequence is established, Synapse sends the request to the server |
| with the pre-negotiated sequence ID.</p> |
| <pre><soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" |
| xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soapenv:Header> |
| <wsa:To>http://localhost:9000/soap/ReliableStockQuoteService</wsa:To> |
| <wsa:MessageID>urn:uuid:DB9A5257B637DDA38B1179807372560712002-1515891720</wsa:MessageID> |
| <wsa:Action>urn:getQuote</wsa:Action> |
| <wsrm:Sequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" |
| soapenv:mustUnderstand="1"> |
| <wsrm:Identifier>urn:uuid:879853A6871A66641C1179807373270</wsrm:Identifier> |
| <wsrm:MessageNumber>1</wsrm:MessageNumber> |
| <wsrm:LastMessage/> |
| </wsrm:Sequence> |
| </soapenv:Header> |
| <soapenv:Body> |
| <m0:getQuote xmlns:m0="http://services.samples/xsd"> |
| <m0:request> |
| <m0:symbol>IBM</m0:symbol> |
| </m0:request> |
| </m0:getQuote> |
| </soapenv:Body> |
| </soapenv:Envelope></pre> |
| |
| <p>Synapse keeps on sending above message till the server responds with a |
| valid response message with 200 OK HTTP header. If the server is not ready |
| with a response, it will respond with 202 Accepted HTTP header for all |
| requests. Once the server is ready with a response it will send the response |
| message with sequence ID as follows.</p> |
| <pre><soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" |
| xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soapenv:Header> |
| <wsa:MessageID>urn:uuid:879853A6871A66641C1179807373804</wsa:MessageID> |
| <wsa:Action>http://services.samples/ReliableStockQuoteServicePortType/getQuoteResponse |
| </wsa:Action> |
| <wsa:RelatesTo>urn:uuid:DB9A5257B637DDA38B1179807372560712002-1515891720</wsa:RelatesTo> |
| <wsrm:Sequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" |
| soapenv:mustUnderstand="1"> |
| <wsrm:Identifier>urn:uuid:546F6F33FB7D8BBE351179807372769</wsrm:Identifier> |
| <wsrm:MessageNumber>1</wsrm:MessageNumber> |
| <wsrm:LastMessage/> |
| </wsrm:Sequence> |
| <wsrm:SequenceAcknowledgement xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" |
| soapenv:mustUnderstand="1"> |
| <wsrm:Identifier>urn:uuid:879853A6871A66641C1179807373270</wsrm:Identifier> |
| <wsrm:AcknowledgementRange Lower="1" Upper="1"/> |
| </wsrm:SequenceAcknowledgement> |
| </soapenv:Header> |
| <soapenv:Body> |
| <ns:getQuoteResponse xmlns:ns="http://services.samples/xsd"> |
| ...</pre> |
| |
| <p>Now both Synapse and the server are done with the actual message exchange. |
| Then Synapse sends a request to terminate the sequence as follows:</p> |
| <pre><soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" |
| xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soapenv:Header> |
| <wsa:To>http://localhost:9000/soap/ReliableStockQuoteService</wsa:To> |
| <wsa:MessageID>urn:uuid:546F6F33FB7D8BBE351179807379591</wsa:MessageID> |
| <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</wsa:Action> |
| <wsrm:SequenceAcknowledgement xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" |
| soapenv:mustUnderstand="1"> |
| <wsrm:Identifier>urn:uuid:546F6F33FB7D8BBE351179807372769</wsrm:Identifier> |
| <wsrm:AcknowledgementRange Lower="1" Upper="1"/> |
| </wsrm:SequenceAcknowledgement> |
| </soapenv:Header> |
| <soapenv:Body> |
| <wsrm:TerminateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"> |
| <wsrm:Identifier>urn:uuid:879853A6871A66641C1179807373270</wsrm:Identifier> |
| </wsrm:TerminateSequence> |
| </soapenv:Body> |
| </soapenv:Envelope></pre> |
| |
| <p>Server responds to the sequence termination message, accepting to |
| terminate the sequence as follows.</p> |
| <pre><soapenv:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" |
| xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soapenv:Header> |
| <wsa:ReplyTo> |
| <wsa:Address>http://localhost:9000/soap/ReliableStockQuoteService</wsa:Address> |
| </wsa:ReplyTo> |
| <wsa:MessageID>urn:uuid:879853A6871A66641C1179807380190</wsa:MessageID> |
| <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</wsa:Action> |
| </soapenv:Header> |
| <soapenv:Body> |
| <wsrm:TerminateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"> |
| <wsrm:Identifier>urn:uuid:546F6F33FB7D8BBE351179807372769</wsrm:Identifier> |
| </wsrm:TerminateSequence> |
| </soapenv:Body> |
| </soapenv:Envelope></pre> |
| |
| <p>Note that although each of above messages are separate SOAP messages, in |
| most cases they will be exchanged in a single socket connection as HTTP |
| Keep-Alive header is used.</p> |
| |
| <h1><a name="ProxyServices">Synapse Proxy service samples</a></h1> |
| |
| <h2><a name="Sample150">Sample 150: Introduction to proxy services</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="StockQuoteProxy"> |
| <target> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| </definitions></pre> |
| |
| <p><strong>Objective: Introduction to Synapse proxy services</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 150: i.e. synapse -sample 150<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>Once Synapse starts, you could go to |
| http://localhost:8080/soap/StockQuoteProxy?wsdl and view the WSDL generated |
| for the proxy service defined in the configuration. This WSDL is based on the |
| source WSDL supplied in the proxy service definition, and is updated to |
| reflect the proxy service EPR.</p> |
| |
| <p>Execute the stock quote client by requesting for a stock quote on the |
| proxy service as follows:</p> |
| <pre>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy</pre> |
| |
| <p>An 'inSequence' or 'endpoint' or both of these would decide how the |
| message would be handled after the proxy service receives the message. In the |
| above example, the request received is forwarded to the sample service hosted |
| on Axis2. The 'outSequence' defines how the response is handled before it is |
| sent back to the client. By default, a proxy service is exposed over all |
| transports configured for Synapse, unless these are specifically mentioned |
| through the 'transports' attribute.</p> |
| |
| <h2><a name="Sample151">Sample 151: Custom sequences and endpoints with proxy |
| services</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <sequence name="proxy_1"> |
| <send> |
| <endpoint><address uri="http://localhost:9000/soap/SimpleStockQuoteService"/></endpoint> |
| </send> |
| </sequence> |
| <sequence name="out"> |
| <send/> |
| </sequence> |
| <endpoint name="proxy_2_endpoint"> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| <localEntry key="proxy_wsdl" src="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| |
| <proxy name="StockQuoteProxy1"> |
| <publishWSDL key="proxy_wsdl"/> |
| <target inSequence="proxy_1" outSequence="out"/> |
| </proxy> |
| |
| <proxy name="StockQuoteProxy2"> |
| <publishWSDL key="proxy_wsdl"/> |
| <target endpoint="proxy_2_endpoint" outSequence="out"/> |
| </proxy> |
| </definitions></pre> |
| |
| <p><strong>Objective: Using custom sequences and endpoints for message |
| mediation with proxy services</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 151: i.e. synapse -sample 151<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>This configuration creates two proxy services.. The first proxy service |
| 'StockQuoteProxy1' uses the sequence named 'proxy_1' to process incoming |
| messages and the sequence named "out" to process outgoing responses. The |
| second proxy service 'StockQuoteProxy2' is set to directly forward messages |
| that are received to the endpoint named 'proxy_2_endpoint' without any |
| mediation.</p> |
| |
| <p>You could send a stock quote request to each of these proxy services and |
| receive the reply generated by the actual service hosted on the Axis2 |
| instance. </p> |
| <pre>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy1<br/>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy2</pre> |
| |
| <h2><a name="Sample152">Sample 152: Switching transports and message format |
| from SOAP to REST/POX</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="StockQuoteProxy" transports="https"> |
| <target> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="pox"/> |
| </endpoint> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| </definitions></pre> |
| |
| <p><strong>Objective: Switching transports and from SOAP to |
| REST/POX</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Synapse configuration numbered 152: i.e. synapse -sample 152</p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| |
| <p></p> |
| |
| <p>This configuration demonstrates how a proxy service could be exposed on a |
| subset of available transports, and how it could switch from one transport to |
| another. This example exposes the created proxy service only on https, and |
| thus if the user tries to access it over http, would result in a fault.</p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy |
| ... |
| [java] org.apache.axis2.AxisFault: The service cannot be found for the endpoint reference (EPR) /soap/StockQuoteProxy</pre> |
| |
| <p></p> |
| |
| <p>Accessing this over https (ant stockquote |
| -Dtrpurl=https://localhost:8443/soap/StockQuoteProxy) causes the proxy |
| service to access the SimpleStockQuoteService on the sample Axis2 server |
| using REST/POX. This could be seen if the message exchange was captured using |
| TCPMon as follows. The REST/POX response is now transformed back into a SOAP |
| message and returned to the client.</p> |
| <pre>POST http://localhost:9000/soap/SimpleStockQuoteService HTTP/1.1 |
| Host: 127.0.0.1 |
| SOAPAction: urn:getQuote |
| Content-Type: application/xml; charset=UTF-8;action="urn:getQuote"; |
| Transfer-Encoding: chunked |
| Connection: Keep-Alive |
| User-Agent: Synapse-HttpComponents-NIO |
| |
| 75 |
| <m0:getQuote xmlns:m0="http://services.samples/xsd"> |
| <m0:request> |
| <m0:symbol>IBM</m0:symbol> |
| </m0:request> |
| </m0:getQuote></pre> |
| <pre>HTTP/1.1 200 OK |
| Content-Type: application/xml; charset=UTF-8;action="http://services.samples/SimpleStockQuoteServicePortType/getQuoteResponse"; |
| Date: Tue, 24 Apr 2007 14:42:11 GMT |
| Server: Synapse-HttpComponents-NIO |
| Transfer-Encoding: chunked |
| Connection: Keep-Alive |
| |
| 2b3 |
| <ns:getQuoteResponse xmlns:ns="http://services.samples/xsd"> |
| <ns:return> |
| <ns:change>3.7730036841862384</ns:change> |
| <ns:earnings>-9.950236235550818</ns:earnings> |
| <ns:high>-80.23868444613285</ns:high> |
| <ns:last>80.50750970812187</ns:last> |
| <ns:lastTradeTimestamp>Tue Apr 24 20:42:11 LKT 2007</ns:lastTradeTimestamp> |
| <ns:low>-79.67368355714606</ns:low> |
| <ns:marketCap>4.502043663670823E7</ns:marketCap> |
| <ns:name>IBM Company</ns:name> |
| <ns:open>-80.02229531286982</ns:open> |
| <ns:peRatio>25.089295161182022</ns:peRatio> |
| <ns:percentageChange>4.28842665653824</ns:percentageChange> |
| <ns:prevClose>87.98107059692451</ns:prevClose> |
| <ns:symbol>IBM</ns:symbol> |
| <ns:volume>19941</ns:volume> |
| </ns:return></ns:getQuoteResponse></pre> |
| |
| <p></p> |
| |
| <h2><a name="Sample153">Sample 153: Routing the messages arrived to a proxy |
| service without processing the security headers</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="StockQuoteProxy"> |
| <target> |
| <inSequence> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SecureStockQuoteService"/> |
| </endpoint> |
| </send> |
| </inSequence> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| </definitions></pre> |
| |
| <p><strong>Objective: Routing the messages arrived to a proxy service without |
| processing the MustUnderstand headers (Security header)</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| You may also need to download and install the unlimited strength policy files |
| for your JDK before using Apache Rampart (e.g. see |
| http://java.sun.com/javase/downloads/index_jdk5.jsp)</p> |
| |
| <p>Start the Synapse configuration numbered 153: i.e. synapse -sample 153<br/> |
| Start the Axis2 server and deploy the SecureStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>The proxy service will recieve secure messages with security headers which |
| are MustUnderstand. But hence element 'engageSec' is not present in the proxy |
| configuration synapse 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 Synapse. But Synapse |
| handles this message and gets it in by setting all the headers which are |
| MustUnderstand and not processed to processed state. This will enable synapse |
| 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:</p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy -Dpolicy=./../../repository/conf/sample/resources/policy/client_policy_3.xml</pre> |
| |
| <p>By following through the debug logs or TCPMon output, you could see that |
| the request received by the proxy service was signed and encrypted. Also, |
| looking up the WSDL of the proxy service by requesting the 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 synapse 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 synapse is signed and encrypted and can only be |
| forwarded to a secure service to be useful.</p> |
| |
| <h2><a name="Sample154">Sample 154: Load Balancing with Proxy Service |
| </a></h2> |
| |
| <div> |
| <pre> <!-- A proxy service with a loadbalace endpoint --> |
| <definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="LBProxy" transports="https http" startOnLoad="true"> |
| <target faultSequence="errorHandler"> |
| <inSequence> |
| <send> |
| <endpoint> |
| <session type="simpleClientSession"/> |
| <loadbalance algorithm="roundRobin"> |
| <endpoint> |
| <address uri="http://localhost:9001/soap/LBService1"> |
| <enableAddressing/> |
| <suspendDurationOnFailure>20</suspendDurationOnFailure> |
| </address> |
| </endpoint> |
| <endpoint> |
| <address uri="http://localhost:9002/soap/LBService1"> |
| <enableAddressing/> |
| <suspendDurationOnFailure>20</suspendDurationOnFailure> |
| </address> |
| </endpoint> |
| <endpoint> |
| <address uri="http://localhost:9003/soap/LBService1"> |
| <enableAddressing/> |
| <suspendDurationOnFailure>20</suspendDurationOnFailure> |
| </address> |
| </endpoint> |
| </loadbalance> |
| </endpoint> |
| </send> |
| <drop/> |
| </inSequence> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_2.wsdl"/> |
| </proxy> |
| <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> </pre> |
| |
| <p><strong>Objective: Load Balancing with Proxy Service </strong></p> |
| |
| <p><strong>Prerequisites:</strong> Sample setup is same as LoadBalance |
| endpoints (#53 to #54).</p> |
| |
| <p>Start the Synapse configuration numbered 154: i.e. synapse -sample 154<br/> |
| Start the Axis2 server and deploy the SecureStockQuoteService if not already |
| done</p> |
| |
| <p>Runs the client with </p> |
| <pre> ant loadbalancefailover -Dmode=session -Dtrpurl=http://localhost:8080/soap/LBProxy </pre> |
| |
| <p>Functionality is similar to the sample #54. </p> |
| </div> |
| |
| <h1><a name="ProxyServiceQoS">QoS addition and deduction for service |
| mediation (proxy) samples</a></h1> |
| |
| <h2><a name="Sample200">Sample 200: Using WS-Security with policy attachments |
| for proxy services</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <localEntry key="sec_policy" src="file:repository/conf/sample/resources/policy/policy_3.xml"/> |
| <proxy name="StockQuoteProxy"> |
| <target> |
| <inSequence> |
| <header name="wsse:Security" action="remove" |
| xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </inSequence> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| <policy key="sec_policy"/> |
| <enableSec/> |
| </proxy> |
| </definitions></pre> |
| |
| <p><strong>Objective: Using WS-Security signing and encryption with proxy |
| services through WS-Policy</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| You may also need to download and install the unlimited strength policy files |
| for your JDK before using Apache Rampart (e.g. see |
| http://java.sun.com/javase/downloads/index_jdk5.jsp)</p> |
| |
| <p>Start the Synapse configuration numbered 200: i.e. synapse -sample 200<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>The proxy service expects to receive a signed and encrypted message as |
| specified by the security policy. Please see Apache Rampart and Axis2 |
| documentation on the format of the policy file. The element 'engageSec' |
| specifies that Apache Rampart should be engaged on this proxy service. Hence |
| if Rampart rejects any request messages that does not conform to the |
| specified policy, those messages will never reach the 'inSequence' to be |
| processed. Since the proxy service is forwarding the received request to the |
| simple stock quote service that does not use WS-Security, we are instructing |
| Synapse to remove the wsse:Security header from the outgoing message. To |
| execute the client, send a stock quote request to the proxy service, and sign |
| and encrypt the request by specifying the client side security policy as |
| follows:</p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy -Dpolicy=./../../repository/conf/sample/resources/policy/client_policy_3.xml</pre> |
| |
| <p>By following through the debug logs or TCPMon output, you could see that |
| the request received by the proxy service was signed and encrypted. Also, |
| looking up the WSDL of the proxy service by requesting the |
| URLhttp://localhost:8080/soap/StockQuoteProxy?wsdl reveals the security |
| policy attachment to the supplied base WSDL. When sending the message to the |
| backend service, you could verify that the security headers were removed, and |
| that the response received does not use WS-Security, but that the response |
| being forwarded back to the client is signed and encrypted as expected by the |
| client.</p> |
| |
| <h2><a name="Sample201">Sample 201: Reliable message exchange between the |
| client and proxy services using WS-ReliableMessaging</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="StockQuoteProxy"> |
| <target> |
| <inSequence> |
| <header name="wsrm:SequenceAcknowledgement" action="remove" |
| xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/> |
| <header name="wsrm:Sequence" action="remove" |
| xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </inSequence> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| <enableRM/> |
| </proxy> |
| </definitions></pre> |
| <strong>Objective: Demonstrate the reliable message exchange between the |
| client and Synapse using WS-ReliableMessaging (WS-RM)</strong> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Deploy the SimpleStockQuoteService in the sample Axis2 server and start it |
| on port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration number 201 (i.e. synapse |
| -sample 201).</p> |
| |
| <p></p> |
| |
| <p>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 |
| Synapse. Now start the client with WS-RM as follows:</p> |
| <pre>ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dwsrm=true</pre> |
| |
| <p>In this case, client sends WS-RM enabled request to Synapse where Synapse |
| sends normal request to the server. This can be observed by examining the |
| wire level messages between the client and Synapse. These messages would be |
| similar to the wire level messages shown in sample 53. Each message would |
| perform a similar function to the messages discussed in sample 53.</p> |
| |
| <p></p> |
| |
| <h1><a name="Transport">Transport samples and switching transports</a></h1> |
| |
| <h2><a name="Sample250">Sample 250: Introduction to switching transports - |
| JMS to http/s</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <proxy name="StockQuoteProxy" transports="jms"> |
| <target> |
| <inSequence> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| </inSequence> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| |
| </definitions></pre> |
| |
| <p><strong>Objective: Introduction to switching transports with proxy |
| services</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService (Refer steps |
| above)<br/> |
| Download, install and start a JMS server, and configure Synapse to listen on |
| JMS (refer notes below)<br/> |
| Start the Synapse configuration numbered 250: i.e. synapse -sample 250<br/> |
| For this example we would use ActiveMQ as the JMS provider. Once ActiveMQ is |
| installed and started you should get a message as follows:</p> |
| <pre>INFO BrokerService - ActiveMQ JMS Message Broker (localhost) started</pre> |
| |
| <p>You will now need to configure the Axis2 instance used by Synapse (not the |
| sample Axis2 server) to enable JMS support using the above provider. Refer to |
| the Axis2 documentation on setting up JMS for more details |
| (http://ws.apache.org/axis2/1_1/jms-transport.html). You will also need to |
| copy the ActiveMQ client jar files activeio-core-3.0-beta1.jar, |
| activemq-core-4.0-RC2.jar and geronimo-j2ee-management_1.0_spec-1.0.jar into |
| the lib directory to allow Synapse to connect to the JMS provider.</p> |
| |
| <p>For a default ActiveMQ v4.0 installation, you may uncomment the Axis2 |
| transport listener configuration found at repository/conf/axis2.xml as</p> |
| <pre><transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener"> ...</pre> |
| |
| <p>Once you start the Synapse configuration and request for the WSDL of the |
| proxy service (http://localhost:8080/soap/StockQuoteProxy?wsdl) you will |
| notice that its exposed only on the JMS transport. This is because the |
| configuration specified this requirement in the proxy service definition.</p> |
| |
| <p>Now lets send a stock quote request on JMS, using the dumb stock quote |
| client as follows:</p> |
| <pre>ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/StockQuoteProxy -Djms_payload=MSFT</pre> |
| |
| <p>On the Synapse debug log you will notice that the JMS listener received |
| the request message as:</p> |
| <pre>[JMSWorker-1] DEBUG ProxyServiceMessageReceiver -Proxy Service StockQuoteProxy received a new message...</pre> |
| |
| <p>Now if you examine the console running the sample Axis2 server, you will |
| see a message indicating that the server has accepted an order as follows:</p> |
| <pre>Accepted order for : 16517 stocks of MSFT at $ 169.14622538721846</pre> |
| |
| <p>In this sample, client sends the request message to the proxy service |
| exposed in JMS in Synsape. Synapse forwards this message to the HTTP EPR of |
| the simple stock quote service hosted on the sample Axis2 server, and returns |
| the reply back to the client through a JMS temporary queue.</p> |
| |
| <p>Note: It is possible to instruct a JMS proxy service to listen to an |
| already existing destination without creating a new one. To do this, use the |
| property elements on the proxy service definition to specify the destination |
| and connection factory etc.</p> |
| |
| <p>e.g.</p> |
| <pre><property name="transport.jms.Destination" value="dynamicTopics/something.TestTopic"/></pre> |
| |
| <h2><a name="Sample251">Sample 251: Switching from http/s to JMS</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <proxy name="StockQuoteProxy" transports="http"> |
| <target> |
| <endpoint> |
| <address uri="jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp; |
| java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue"/> |
| </endpoint> |
| <inSequence> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| </inSequence> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| |
| </definitions></pre> |
| |
| <p><strong>Objective: Demonstrate switching from HTTP to JMS</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Download, install and start a JMS server</p> |
| |
| <p>Configure sample Axis2 server for JMS (refer notes above)<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService (see below)<br/> |
| Configure the Synase JMS transport (refer notes above - sample 250)<br/> |
| Start the Synapse configuration numbered 251: i.e. synapse -sample 251</p> |
| |
| <p>To switch from HTTP to JMS, edit the |
| samples/axis2Server/repository/conf/axis2.xml for the sample Axis2 server and |
| enable JMS (refer notes above), and restart the server. Now you can see that |
| the simple stock quote service is available in both JMS and HTTP in the |
| sample Axis2 server. To see this, point your browser to the WSDL of the |
| service at http://localhost:9000/soap/SimpleStockQuoteService?wsdl. JMS URL |
| for the service is mentioned as below:</p> |
| <pre>jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName= |
| QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory& |
| java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue</pre> |
| |
| <p>You may also notice that the simple stock quote proxy service exposed in |
| Synapse is now available only in HTTP as we have specified transport for that |
| service as HTTP. To observe this, access the WSDL of stock quote proxy |
| service at http://localhost:8080/soap/StockQuoteProxy?wsdl.</p> |
| |
| <p>This Synapse configuration creates a proxy service over HTTP and forwards |
| received messages to the above EPR using JMS, and sends back the response to |
| the client over HTTP once the simple stock quote service responds with the |
| stock quote reply over JMS to the Synapse server. To test this, send a place |
| order request to Synapse using HTTP as follows:</p> |
| <pre>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dmode=placeorder -Dsymbol=MSFT</pre> |
| |
| <p>The sample Axis2 server console will print a message indicating that it |
| has accepted the order as follows:</p> |
| <pre>Accepted order for : 18406 stocks of MSFT at $ 83.58806051152119</pre> |
| |
| <h2><a name="Sample252">Sample 252: Pure text/binary and POX message support |
| with JMS</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <sequence name="text_proxy"> |
| <header name="Action" value="urn:placeOrder"/> |
| <script language="js"><![CDATA[ |
| var args = mc.getPayloadXML().toString().split(" "); |
| mc.setPayloadXML( |
| <m:placeOrder xmlns:m="http://services.samples/xsd"> |
| <m:order> |
| <m:price>{args[0]}</m:price> |
| <m:quantity>{args[1]}</m:quantity> |
| <m:symbol>{args[2]}</m:symbol> |
| </m:order> |
| </m:placeOrder>); |
| ]]></script> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </sequence> |
| |
| <sequence name="mtom_proxy"> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| <header name="Action" value="urn:oneWayUploadUsingMTOM"/> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/MTOMSwASampleService" optimize="mtom"/> |
| </endpoint> |
| </send> |
| </sequence> |
| |
| <sequence name="pox_proxy"> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| <header name="Action" value="urn:placeOrder"/> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="soap11"/> |
| </endpoint> |
| </send> |
| </sequence> |
| |
| <sequence name="out"> |
| <send/> |
| </sequence> |
| |
| <proxy name="JMSFileUploadProxy" transports="jms"> |
| <target inSequence="mtom_proxy" outSequence="out"/> |
| <parameter name="transport.jms.Wrapper">{http://services.samples/xsd}element</parameter> |
| </proxy> |
| <proxy name="JMSTextProxy" transports="jms"> |
| <target inSequence="text_proxy" outSequence="out"/> |
| <parameter name="transport.jms.Wrapper">{http://services.samples/xsd}text</parameter> |
| </proxy> |
| <proxy name="JMSPoxProxy" transports="jms"> |
| <target inSequence="pox_proxy" outSequence="out"/> |
| </proxy> |
| </definitions></pre> |
| |
| <p><strong>Objective: Pure POX/Text and Binary JMS Proxy services - including |
| MTOM</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Configure JMS for Synapse (Refer notes)<br/> |
| Start the Synapse configuration numbered 252: i.e. synapse -sample 252<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService and the |
| MTOMSwASampleService if not already done</p> |
| |
| <p></p> |
| |
| <p>This configuration creates three JMS proxy services named |
| JMSFileUploadProxy, JMSTextProxy and JMSPoxProxy exposed over JMS queues with |
| the same names as the services. The first part of this example demonstrates |
| the pure text message support with JMS, where a user sends a space separated |
| text JMS message of the form "<price> <qty> <symbol>". |
| Synapse converts this message into a SOAP message and sends this to the |
| SimpleStockQuoteServices' placeOrder operation. Synapse uses the script |
| mediator to transform the text message into a XML payload using the |
| JavaScript support available to tokenize the string. The proxy service |
| property named "transport.jms.Wrapper" defines a custom wrapper element |
| QName, to be used when wrapping text/binary content into a SOAP envelope.</p> |
| |
| <p></p> |
| |
| <p>Execute JMS client as follows. This will post a pure text JMS message with |
| the content defined (e.g. "12.33 1000 ACP") to the specified JMS destination |
| - dynamicQueues/JMSTextProxy</p> |
| <pre>ant jmsclient -Djms_type=text -Djms_payload="12.33 1000 ACP" -Djms_dest=dynamicQueues/JMSTextProxy</pre> |
| |
| <p>Following the debug logs, you could notice that Synapse received the JMS |
| text message and transformed it into a SOAP payload as follows. Notice that |
| the wrapper element "{http://services.samples/xsd}text" has been used to hold |
| the text message content.</p> |
| <pre>[JMSWorker-1] DEBUG ProxyServiceMessageReceiver - Body : |
| <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soapenv:Body><axis2ns1:text xmlns:axis2ns1="http://services.samples/xsd">12.33 1000 ACP</axis2ns1:text></soapenv:Body> |
| </soapenv:Envelope></pre> |
| |
| <p>Now, you could see how the script mediator created a stock quote request |
| by tokenizing the text as follows, and sent the message to the placeOrder |
| operation of the SimpleStockQuoteService.</p> |
| <pre>[JMSWorker-1] DEBUG AddressEndpoint - Sending message to endpoint :: name = AnonymousEndpoints resolved address = http://localhost:9000/soap/SimpleStockQuoteService |
| [JMSWorker-1] DEBUG AddressEndpoint - SOAPAction: urn:placeOrder |
| [JMSWorker-1] DEBUG AddressEndpoint - WSA-Action: urn:placeOrder |
| [JMSWorker-1] DEBUG AddressEndpoint - Body : |
| <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body> |
| <m:placeOrder xmlns:m="http://services.samples/xsd"><m:order><m:price>12.33</m:price><m:quantity>1000</m:quantity><m:symbol>ACP</m:symbol></m:order> |
| </m:placeOrder></soapenv:Body></soapenv:Envelope></pre> |
| |
| <p>The sample Axis2 server would now accept the one way message and issue the |
| following message:</p> |
| <pre>Wed Apr 25 19:50:56 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 1000 stocks of ACP at $ 12.33</pre> |
| |
| <p></p> |
| |
| <p>The next section of this example demonstrates how a pure binary JMS |
| message could be received and processed through Synapse. The configuration |
| creates a proxy service named 'JMSFileUploadProxy' that accepts binary |
| messages and wraps them into a custom element |
| '{http://services.samples/xsd}element'. The received message is then |
| forwarded to the MTOMSwASampleService using the SOAP action |
| 'urn:oneWayUploadUsingMTOM' and optimizing binary conent using MTOM. To |
| execute this sample, use the JMS client to publish a pure binary JMS message |
| containing the file |
| './../../repository/conf/sample/resources/mtom/asf-logo.gif' to the JMS |
| destination 'dynamicQueues/JMSFileUploadProxy' as follows:</p> |
| <pre>ant jmsclient -Djms_type=binary -Djms_dest=dynamicQueues/JMSFileUploadProxy -Djms_payload=./../../repository/conf/sample/resources/mtom/asf-logo.gif</pre> |
| |
| <p>Examining the Synapse debug logs reveals that the binary content was |
| received over JMS and wrapped with the specified element into a SOAP infoset |
| as follows:</p> |
| <pre>[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></pre> |
| |
| <p>Thereafter the message was sent as a MTOM optimized message as specified |
| by the 'format=mtom' attribute of the endpoint, to the MTOMSwASampleService |
| using the SOAP action 'urn:oneWayUploadUsingMTOM'. Once received by the |
| sample service, it is saved into a temporary file and could be verified for |
| correctness.</p> |
| <pre>Wrote to file : /tmp/mtom-60319.gif</pre> |
| |
| <p></p> |
| |
| <p>The final section of this example shows how a POX JMS message received by |
| Synapse is sent to the SimpleStockQuoteService as a SOAP message. Use the JMS |
| client as follows to create a POX (Plain Old XML) message with a stock quote |
| request payload (without a SOAP envelope), and send it to the JMS destination |
| 'dynamicQueues/JMSPoxProxy' as follows:</p> |
| <pre>ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/JMSPoxProxy -Djms_payload=MSFT</pre> |
| |
| <p>You can see that Synapse received the POX message and displays it as |
| follows in the debug logs, and then converts it into a SOAP payload and sends |
| to the SimpleStockQuoteService after setting the SOAP action as |
| 'urn:placeOrder'.</p> |
| |
| <p></p> |
| <pre>[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] </pre> |
| |
| <p>The sample Axis2 server displays a successful message on the receipt of |
| the message as:</p> |
| <pre>Wed Apr 25 20:24:50 LKT 2007 samples.services.SimpleStockQuoteService :: Accepted order for : 19211 stocks of MSFT at $ 172.39703010684752</pre> |
| |
| <h2><a name="Sample253">Sample 253: One way bridging from JMS to http and |
| replying with a 202 Accepted response</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <proxy name="JMStoHTTPStockQuoteProxy" transports="jms"> |
| <target> |
| <inSequence> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| </inSequence> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| |
| <proxy name="OneWayProxy" transports="http"> |
| <target> |
| <inSequence> |
| <log level="full"/> |
| <property name="RESPONSE" value="true"/> |
| <header name="To" value="http://www.w3.org/2005/08/addressing/anonymous"/> |
| <property name="SC_ACCEPTED" value="true" scope="axis2"/> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| <send/> |
| </inSequence> |
| <outSequence> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| |
| </definitions></pre> |
| |
| <p><strong>Objective: Demonstrate one way message bridging from JMS to http |
| and replying with a http 202 Accepted response</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p>Start the Synapse configuration numbered 253: i.e. synapse -sample 253</p> |
| |
| <p></p> |
| |
| <p>This example invokes the one-way 'placeOrder' operation on the |
| SimpleStockQuoteService using the Axis2 ServiceClient.fireAndForget() API at |
| the client. To test this, use 'ant -Dmode=placeorder...' and you will notice |
| the one way JMS message flowing through Synapse into the sample Axis2 server |
| instance over http, and Axis2 acknowledging it with a http 202 Accepted |
| response.</p> |
| <pre>ant stockquote -Dmode=placeorder -Dtrpurl="jms:/JMStoHTTPStockQuoteProxy?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue"</pre> |
| <pre>SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733</pre> |
| |
| <p>The second example shows how Synapse could be made to respond with a http |
| 202 Accepted response to a request received. The proxy service simply logs |
| the message received and acknowledges it. On the Synapse console you could |
| see the logged message, and if TCPMon was used at the client, you would see |
| the 202 Accepted response sent back to the client from Synapse</p> |
| <pre>ant stockquote -Dmode=placeorder -Dtrpurl=http://localhost:8080/soap/OneWayProxy</pre> |
| <pre>HTTP/1.1 202 Accepted |
| Content-Type: text/xml; charset=UTF-8 |
| Host: 127.0.0.1 |
| SOAPAction: "urn:placeOrder" |
| Date: Sun, 06 May 2007 17:20:19 GMT |
| Server: Synapse-HttpComponents-NIO |
| Transfer-Encoding: chunked |
| |
| 0</pre> |
| |
| <h2><a name="Sample254">Sample 254: Using the file system as transport medium |
| using VFS transport listener and sender</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="StockQuoteProxy" transports="vfs"> |
| <parameter name="transport.vfs.FileURI">file:///home/user/test/in</parameter> <!--CHANGE--> |
| <parameter name="transport.vfs.ContentType">text/xml</parameter> |
| <parameter name="transport.vfs.FileNamePattern">.*\.xml</parameter> |
| <parameter name="transport.PollInterval">15</parameter> |
| <parameter name="transport.vfs.MoveAfterProcess">file:///home/user/test/original</parameter> <!--CHANGE--> |
| <parameter name="transport.vfs.MoveAfterFailure">file:///home/user/test/original</parameter> <!--CHANGE--> |
| <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter> |
| <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter> |
| |
| <target> |
| <endpoint> |
| <address format="soap12" uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| <outSequence> |
| <property name="transport.vfs.ReplyFileName" |
| expression="fn:concat(fn:substring-after(get-property('MessageID'), 'urn:uuid:'), '.xml')" scope="transport"/> |
| <send> |
| <endpoint> |
| <address uri="vfs:file:///home/user/test/out"/> <!--CHANGE--> |
| </endpoint> |
| </send> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Using the file system as transport medium using VFS |
| transport listener and sender</strong></p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| |
| <p>Create three new directories in a test directory. e.g. in, out, original |
| in /home/user/test. Open |
| SYNAPSE_HOME/repository/conf/sample/synapse_sample_115.xml and edit the |
| following values. Change transport.vfs.FileURI, |
| transport.vfs.MoveAfterProcess, transport.vfs.MoveAfterFailure parameter |
| values to the above in, original, original directories respectively. Change |
| outSequence endpoint address uri to out directory with the prefeix |
| <em>vfs:</em>. Values you have to change are marked with <!--CHANGE-->. |
| </p> |
| |
| <p>Start the Synapse configuration numbered 254: i.e. synapse -sample 254</p> |
| |
| <p>Copy SYNAPSE_HOME/repository/conf/sample/resources/vfs/test.xml to the |
| directory given in transport.vfs.FileURI above.</p> |
| |
| <p>test.xml file content is as follows</p> |
| <pre><?xml version='1.0' encoding='UTF-8'?> |
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing"> |
| <soapenv:Body> |
| <m0:getQuote xmlns:m0="http://services.samples/xsd"> |
| <m0:request> |
| <m0:symbol>IBM</m0:symbol> |
| </m0:request> |
| </m0:getQuote> |
| </soapenv:Body> |
| </soapenv:Envelope></pre> |
| |
| <p>VFS transport listener will pick the file from <em>in</em> directory and |
| send it to the Axis2 service. The request XML file will be moved to |
| <em>original</em> directory. The response from the Axis2 server will be saved |
| to <em>out</em> directory.</p> |
| |
| <h2><a name="Sample255">Sample 255: Switching from ftp transport listener to |
| mail transport sender</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="StockQuoteProxy" transports="vfs"> |
| <parameter name="transport.vfs.FileURI">vfs:ftp://guest:guest@localhost/test?vfs.passive=true</parameter> <!--CHANGE--> |
| <parameter name="transport.vfs.ContentType">text/xml</parameter> |
| <parameter name="transport.vfs.FileNamePattern">.*\.xml</parameter> |
| <parameter name="transport.PollInterval">15</parameter> |
| |
| <target> |
| <inSequence> |
| <header name="Action" value="urn:getQuote"/> |
| </inSequence> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| <outSequence> |
| <property action="set" name="OUT_ONLY" value="true"/> |
| <send> |
| <endpoint> |
| <address uri="mailto:user@host"/> <!--CHANGE--> |
| </endpoint> |
| </send> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Switching from ftp transport listener to mail transport |
| sender</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| You will need access to an FTP server and an SMTP server to try this |
| sample.</p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| |
| <p>Enable mail transport sender in the Synapse axis2.xml. See <a |
| href="samples_setup.html#mailsender">Setting up mail transport |
| sender</a> </p> |
| |
| <p>Create a new test directory in the FTP server. Open |
| SYNAPSE_HOME/repository/conf/sample/synapse_sample_116.xml and edit the |
| following values. Change transport.vfs.FileURI parameter value point to the |
| test directory at the FTP server. Change outSequence endpoint address uri |
| email address to a working email address. Values you have to change are |
| marked with <!--CHANGE-->.</p> |
| |
| <p>Start the Synapse configuration numbered 255: i.e. synapse -sample 255</p> |
| |
| <p>Copy SYNAPSE_HOME/repository/conf/sample/resources/vfs/test.xml to the ftp |
| directory given in transport.vfs.FileURI above.</p> |
| |
| <p>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.</p> |
| |
| <h2><a name="Sample256">Sample 256: Proxy services with the mail transport |
| </a></h2> |
| <pre><!-- Using the mail transport --> |
| <definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <proxy name="StockQuoteProxy" transports="mailto"> |
| |
| <parameter name="transport.mail.Address">synapse.demo.1@gmail.com</parameter> |
| <parameter name="transport.mail.Protocol">pop3</parameter> |
| <parameter name="transport.PollInterval">5</parameter> |
| <parameter name="mail.pop3.host">pop.gmail.com</parameter> |
| <parameter name="mail.pop3.port">995</parameter> |
| <parameter name="mail.pop3.user">synapse.demo.1</parameter> |
| <parameter name="mail.pop3.password">mailpassword</parameter> |
| <parameter name="mail.pop3.socketFactory.class">javax.net.ssl.SSLSocketFactory</parameter> |
| <parameter name="mail.pop3.socketFactory.fallback">false</parameter> |
| <parameter name="mail.pop3.socketFactory.port">995</parameter> |
| |
| <target> |
| <inSequence> |
| <property name="senderAddress" expression="get-property('transport', 'From')"/> |
| <log level="full"> |
| <property name="Sender Address" expression="get-property('senderAddress')"/> |
| </log> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </inSequence> |
| <outSequence> |
| <property name="Subject" value="Custom Subject for Response" scope="transport"/> |
| <header name="To" expression="fn:concat('mailto:', get-property('senderAddress'))"/> |
| <log level="full"> |
| <property name="message" value="Response message"/> |
| <property name="Sender Address" expression="get-property('senderAddress')"/> |
| </log> |
| <send/> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Using the mail transport with Proxy |
| services</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| You will need access to an email account</p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| |
| <p>Enable mail transport sender in the Synapse axis2.xml. See <a |
| href="samples_setup.html#mailsender">Setting up mail transport |
| sender</a> </p> |
| |
| <p>Start the Synapse configuration numbered 256: i.e. synapse -sample 256</p> |
| |
| <p>Send a plain/text email with the following body and any custom Subject |
| from your mail account.</p> |
| <pre><m0:getQuote xmlns:m0="http://services.samples/xsd"><m0:request><m0:symbol>IBM</m0:symbol></m0:request></m0:getQuote> </pre> |
| |
| <p>After a few seconds (e.g. 30s), you should receive a POX response in your email |
| account with the stock quote reply.</p> |
| |
| <h1><a name="Task">Introduction to synapse tasks</a></h1> |
| |
| <h2><a name="Sample300">Sample 300: Introduction to tasks with simple |
| trigger</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <task class="org.apache.synapse.startup.tasks.MessageInjector" name="CheckPrice"> |
| <property name="to" value="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| <property name="soapAction" value="urn:getQuote"/> |
| <property name="message"> |
| <m0:getQuote xmlns:m0="http://services.samples/xsd"> |
| <m0:request> |
| <m0:symbol>IBM</m0:symbol> |
| </m0:request> |
| </m0:getQuote> |
| </property> |
| <trigger interval="5000"/> |
| </task> |
| |
| <in> |
| <send/> |
| </in> |
| <out> |
| <log level="custom"> |
| <property name="Stock_Quote_on" expression="//ns:return/ns:lastTradeTimestamp/child::text()" xmlns:ns="http://services.samples/xsd"/> |
| <property name="For_the_organization" expression="//ns:return/ns:name/child::text()" xmlns:ns="http://services.samples/xsd"/> |
| <property name="Last_Value" expression="//ns:return/ns:last/child::text()" xmlns:ns="http://services.samples/xsd"/> |
| </log> |
| </out> |
| |
| </definitions></pre> |
| |
| <p><strong>Objective: Introduce the concept of tasks and how simple trigger |
| works</strong></p> |
| |
| <p><strong>Prerequisites:</strong><br/> |
| You will need access to build the SimpleStockQuoteService as mentioned in the |
| above and start the sample axis2 server before staring synapse.</p> |
| |
| <p>When ever synapse gets started and initialized, this task will run |
| periodically in 5 second intervals. You could limit the number of times that |
| you want to run this task by adding a count attribute with an integer as the |
| value, if the count is not present as in this sample this task will run |
| forever.</p> |
| |
| <p>One can write his own task class implementing the |
| org.apache.synapse.startup.Task interface and implementing the execute method |
| to do the task. For this particular sample we have used the MessageInjector |
| which just injects a message specified in to the synapse environment.</p> |
| |
| <h1><a name="AdvancedMediation">Advanced mediations with advanced |
| mediators</a></h1> |
| |
| <h2><a name="ScriptMediator">Using scripts in mediation (Script |
| Mediator)</a></h2> |
| |
| <p>The Synapse Script Mediator is a Synapse extension, and thus all |
| prerequisites are not bundled by default with the Synapse distribution. |
| Before you use some script mediators you may need to manually add the |
| required jar files to the Synapse lib directory, and optionally perform other |
| installation tasks as may be required by the individual scripting language. |
| This is explained in the <a href="samples_setup.html#script">Samples |
| Setup guide</a>.</p> |
| |
| <h2><a name="Sample350">Sample 350: Introduction to the script mediator using |
| js scripts</a></h2> |
| <pre><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> </pre> |
| |
| <p></p> |
| <pre><x><![CDATA[ |
| function transformRequest(mc) { |
| var symbol = mc.getPayloadXML()..*::Code.toString(); |
| mc.setPayloadXML( |
| <m:getQuote xmlns:m="http://services.samples/xsd"> |
| <m:request> |
| <m:symbol>{symbol}</m:symbol> |
| </m:request> |
| </m:getQuote>); |
| } |
| |
| function transformResponse(mc) { |
| var symbol = mc.getPayloadXML()..*::symbol.toString(); |
| var price = mc.getPayloadXML()..*::last.toString(); |
| mc.setPayloadXML( |
| <m:CheckPriceResponse xmlns:m="http://www.apache-synapse.org/test"> |
| <m:Code>{symbol}</m:Code> |
| <m:Price>{price}</m:Price> |
| </m:CheckPriceResponse>); |
| } |
| ]]></x></pre> |
| |
| <p><strong>Objective: Introduction to script mediators</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start the Synapse configuration numbered 350: i.e. synapse -sample 350<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>This sample is similar to sample 8 but instead of using XSLT the |
| transformation is done with JavaScript and E4X. Note that the script source |
| loaded from a resource must be specified within a CDATA tag within an XML |
| element. The script used in this example has two functions, |
| 'transformRequest' and 'transformResponse', and the Synapse configuration |
| uses the function attribute to specify which function should be invoked. Use |
| the stock quote client to issue a custom quote client as follows.:</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote</pre> |
| |
| <p>Synapse uses the script mediator and the specified JavaScript function to |
| convert the custom request to a standard quote request. Subsequently the |
| response received is transformed and sent back to the client.</p> |
| |
| <h2><a name="Sample351">Sample 351: In-line script mediation with |
| JavaScript</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <in> |
| <!-- transform the custom quote request into a standard quote requst expected by the service --> |
| <script language="js"><![CDATA[ |
| var symbol = mc.getPayloadXML()..*::Code.toString(); |
| mc.setPayloadXML( |
| <m:getQuote xmlns:m="http://services.samples/xsd"> |
| <m:request> |
| <m:symbol>{symbol}</m:symbol> |
| </m:request> |
| </m:getQuote>); |
| ]]></script> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </in> |
| <out> |
| <!-- transform the standard response back into the custom format the client expects --> |
| <script language="js"><![CDATA[ |
| var symbol = mc.getPayloadXML()..*::symbol.toString(); |
| var price = mc.getPayloadXML()..*::last.toString(); |
| mc.setPayloadXML( |
| <m:CheckPriceResponse xmlns:m="http://www.apache-synapse.org/test"> |
| <m:Code>{symbol}</m:Code> |
| <m:Price>{price}</m:Price> |
| </m:CheckPriceResponse>); |
| ]]></script> |
| <send/> |
| </out> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Introduction to in-line script mediation</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start the Synapse configuration numbered 351: i.e. synapse -sample 351<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>This example is functionally equivalent to sample # 350 and sample # 8, |
| and demonstrates in-line script mediation in Synapse. Use the stock quote |
| client to send a custom quote as in example # 500 to test this example.</p> |
| |
| <p></p> |
| |
| <h2><a name="Sample352">Sample 352: Accessing Synapse message context API |
| methods using scripting language</a></h2> |
| <pre><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> </pre> |
| |
| <p><strong>Objective: Accessing the Synapse APIs from scripting |
| languages</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Start the Synapse configuration numbered 352: i.e. bin/synapse -sample |
| 352<br/> |
| </p> |
| |
| <p></p> |
| |
| <p>This example shows how an inline JavaScript mediator script could access |
| the Synapse message context API to set its 'To' EPR and to set a custom |
| property to mark it as a response. Execute the stock quote client, and you |
| will receive the response "99.9" as the last sale price as per the above |
| script.</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ |
| ... |
| stockquote: |
| [java] Standard :: Stock price = $99.9</pre> |
| |
| <h2><a name="Sample353">Sample 353: Using Ruby scripts for mediation</a></h2> |
| <pre><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> </pre> |
| <pre><x><![CDATA[ |
| require 'rexml/document' |
| include REXML |
| |
| def transformRequest(mc) |
| newRequest= Document.new '<m:getQuote xmlns:m="http://services.samples/xsd">'<< |
| '<m:request><m:symbol></m:symbol></m:request></m:getQuote>' |
| newRequest.root.elements[1].elements[1].text = mc.getPayloadXML().root.elements[1].get_text |
| mc.setPayloadXML(newRequest) |
| end |
| |
| def transformResponse(mc) |
| newResponse = Document.new '<m:CheckPriceResponse xmlns:m="http://www.apache-synapse.org/test"><m:Code>' << |
| '</m:Code><m:Price></m:Price></m:CheckPriceResponse>' |
| newResponse.root.elements[1].text = mc.getPayloadXML().root.elements[1].elements[1].get_text |
| newResponse.root.elements[2].text = mc.getPayloadXML().root.elements[1].elements[2].get_text |
| mc.setPayloadXML(newResponse) |
| end |
| ]]></x></pre> |
| |
| <p><strong>Objective: Script mediators using Ruby</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>This sample uses Ruby so first setup support for this in Synapse as |
| described at <a href="samples_setup.html#script">Configuring |
| JRuby</a>. </p> |
| |
| <p>Start the Synapse configuration numbered 353: i.e. bin/synapse -sample |
| 353<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>This sample is functionally equivalent to sample # 500 (#501 and #8) but |
| instead uses a Ruby script using the JRuby interpreter. The script has two |
| functions, 'transformRequest' and 'transformResponse', and the Synapse |
| configuration specifies which function is to be invoked when used. Execute |
| the stock quote client to send a custom stock quote as per example #500 and |
| check the received stock quote response.</p> |
| |
| <h2><a name="Sample354">Sample 354: Using In-lined Ruby scripts for |
| mediation</a></h2> |
| |
| <div> |
| <pre> <!-- Using In-lined Ruby scripts for mediation --> |
| <definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <in> |
| <script language="rb"> |
| <![CDATA[ |
| require 'rexml/document' |
| include REXML |
| newRequest= Document.new '<m:getQuote xmlns:m="http://services.samples/xsd"><m:request><m:symbol>...test...</m:symbol></m:request></m:getQuote>' |
| newRequest.root.elements[1].elements[1].text = $mc.getPayloadXML().root.elements[1].get_text |
| $mc.setPayloadXML(newRequest) |
| ]]> |
| </script> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </in> |
| <out> |
| <script language="rb"> |
| <![CDATA[ |
| require 'rexml/document' |
| include REXML |
| newResponse = Document.new '<m:CheckPriceResponse xmlns:m="http://services.samples/xsd"><m:Code></m:Code><m:Price></m:Price></m:CheckPriceResponse>' |
| newResponse.root.elements[1].text = $mc.getPayloadXML().root.elements[1].elements[1].get_text |
| newResponse.root.elements[2].text = $mc.getPayloadXML().root.elements[1].elements[2].get_text |
| $mc.setPayloadXML(newResponse) |
| ]]> |
| </script> |
| <send/> |
| </out> |
| </definitions> </pre> |
| |
| <p><strong>Objective: Script mediators using Ruby(In-line Ruby |
| Script)</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>This sample uses Ruby so first setup support for this in Synapse as |
| described at <a href="samples_setup.html#script">Configuring |
| JRuby</a>. </p> |
| |
| <p>Start the Synapse configuration numbered 354: i.e. bin/synapse -sample |
| 354<br/> |
| Start the Axis2 server and deploy the SimpleStockQuoteService if not already |
| done</p> |
| |
| <p></p> |
| |
| <p>This sample is functionally equivalent to the sample 353. </p> |
| |
| <p>Run the client with </p> |
| <pre> ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote</pre> |
| </div> |
| |
| <h2><a name="DBMediators">Database interactions in mediation (DBLookup / |
| DBReport)</a></h2> |
| |
| <p>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 |
| <a href="samples_setup.html#derby">Sample Setup Guide</a> before |
| going through the samples.</p> |
| |
| <p></p> |
| |
| <h2><a name="Sample360">Sample 360: Introduction to dblookp mediator</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <sequence name="myFaultHandler"> |
| <makefault> |
| <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/> |
| <reason expression="get-property('ERROR_MESSAGE')"/> |
| </makefault> |
| |
| <property name="RESPONSE" value="true"/> |
| <header name="To" expression="get-property('ReplyTo')"/> |
| <send/> |
| <drop/> |
| </sequence> |
| |
| <sequence name="main" onError="myFaultHandler"> |
| <in> |
| <log level="custom"> |
| <property name="text" |
| value="** Looking up from the Database **"/> |
| </log> |
| <dblookup xmlns="http://ws.apache.org/ns/synapse"> |
| <connection> |
| <pool> |
| <driver>org.apache.derby.jdbc.ClientDriver</driver> |
| <url>jdbc:derby://localhost:1527/synapsedb;create=false</url> |
| <user>synapse</user> |
| <password>synapse</password> |
| </pool> |
| </connection> |
| <statement> |
| <sql>select * from company where name =?</sql> |
| <parameter expression="//m0:getQuote/m0:request/m0:symbol" |
| xmlns:m0="http://services.samples/xsd" type="VARCHAR"/> |
| <result name="company_id" column="id"/> |
| </statement> |
| </dblookup> |
| |
| <switch source="get-property('company_id')"> |
| <case regex="c1"> |
| <log level="custom"> |
| <property name="text" |
| expression="fn:concat('Company ID - ',get-property('company_id'))"/> |
| </log> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </case> |
| <case regex="c2"> |
| <log level="custom"> |
| <property name="text" |
| expression="fn:concat('Company ID - ',get-property('company_id'))"/> |
| </log> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </case> |
| <case regex="c3"> |
| <log level="custom"> |
| <property name="text" |
| expression="fn:concat('Company ID - ',get-property('company_id'))"/> |
| </log> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </case> |
| <default> |
| <log level="custom"> |
| <property name="text" value="** Unrecognized Company ID **"/> |
| </log> |
| <makefault> |
| <code value="tns:Receiver" |
| xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/> |
| <reason value="** Unrecognized Company ID **"/> |
| </makefault> |
| <property name="RESPONSE" value="true"/> |
| <header name="To" action="remove"/> |
| <send/> |
| <drop/> |
| </default> |
| </switch> |
| <drop/> |
| </in> |
| |
| <out> |
| <send/> |
| </out> |
| |
| </sequence> |
| |
| </definitions></pre> |
| |
| <p></p> |
| |
| <p></p> |
| |
| <p><strong>Objective:</strong> I<strong>ntroduction to the dblookup |
| mediator</strong></p> |
| |
| <p><strong>Prerequisites:</strong> Setting up Derby database as explained |
| above.</p> |
| |
| <p>Start the Synapse configuration numbered 360: i.e. synapse -sample 360</p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| |
| <p></p> |
| |
| <p>This sample demonstrates simple database read operations through Synapse. |
| When a message arrives at dblookup mediator, it opens a connection to the |
| database and executes the SQL query. The SQL query use '?' character for |
| attributes that will be filled at runtime. The parameters define how to |
| calculate the value of those attributes at runtime. In this sample a dblookup |
| mediator has been used to extract 'id' of the company from the company |
| database using the symbol which is evaluated using an xpath against the SOAP |
| envelope. Then 'id' base switching will be done by a switch mediator.</p> |
| |
| <p></p> |
| |
| <p>When the IBM stock quote is requested,</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM</pre> |
| |
| <p>Synapse console shows</p> |
| <pre>INFO LogMediator text = ** Looking up from the Database **INFO LogMediator text = Company ID – c1<br/></pre> |
| |
| <p></p> |
| |
| <p>For the SUN stock quote,</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN</pre> |
| |
| <p></p> |
| |
| <p>Synapse console shows</p> |
| <pre>INFO LogMediator text = ** Looking up from the Database **INFO LogMediator text = Company ID – c2<br/></pre> |
| |
| <p>and for the MSFT stock quote,</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT</pre> |
| <pre>INFO LogMediator text = ** Looking up from the Database **<br/>INFO LogMediator text = Company ID – c2</pre> |
| |
| <p>For any other symbols, Synapse console shows</p> |
| <pre>INFO LogMediator text = ** Unrecognized Company ID **</pre> |
| |
| <p></p> |
| |
| <p>and the client gets a response which has following message.</p> |
| <pre>** Unrecognized Company ID **</pre> |
| |
| <div> |
| </div> |
| |
| <h2><a name="Sample361">Sample 361: Introduction to dbreport mediator</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <sequence name="main"> |
| <in> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </in> |
| |
| <out> |
| <log level="custom"> |
| <property name="text" |
| value="** Reporting to the Database **"/> |
| </log> |
| <dbreport xmlns="http://ws.apache.org/ns/synapse"> |
| <connection> |
| <pool> |
| <driver>org.apache.derby.jdbc.ClientDriver</driver> |
| <url>jdbc:derby://localhost:1527/synapsedb;create=false</url> |
| <user>synapse</user> |
| <password>synapse</password> |
| </pool> |
| </connection> |
| <statement> |
| <sql>update company set price=? where name =?</sql> |
| <parameter expression="//m0:return/m0:last/child::text()" |
| xmlns:m0="http://services.samples/xsd" type="DOUBLE"/> |
| <parameter expression="//m0:return/m0:symbol/child::text()" |
| xmlns:m0="http://services.samples/xsd" type="VARCHAR"/> |
| </statement> |
| </dbreport> |
| <send/> |
| </out> |
| </sequence> |
| |
| </definitions></pre> |
| |
| <div> |
| <p><strong>Objective: I<strong>ntroduction to the dbreport |
| mediator</strong></strong></p> |
| |
| <p><strong>Prerequisites:</strong> Setting up Derby database as above.</p> |
| |
| <p>Start the Synapse configuration numbered 361: i.e. synapse -sample 361</p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| </div> |
| |
| <p>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.</p> |
| |
| <p></p> |
| |
| <p>Run the client using,</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM</pre> |
| |
| <p>and then execute the following query using database client tool against |
| synapsedb.</p> |
| <pre>select price from company where name='IBM';</pre> |
| |
| <p>It will show some value as follows.</p> |
| <pre>96.39535981018865</pre> |
| |
| <div> |
| </div> |
| |
| <h2><a name="Sample362">Sample 362: Action of dbreport and dblookup mediators |
| together</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <sequence name="main"> |
| <in> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </in> |
| |
| <out> |
| <log level="custom"> |
| <property name="text" |
| value="** Reporting to the Database **"/> |
| </log> |
| |
| <dbreport xmlns="http://ws.apache.org/ns/synapse"> |
| <connection> |
| <pool> |
| <driver>org.apache.derby.jdbc.ClientDriver</driver> |
| <url>jdbc:derby://localhost:1527/synapsedb;create=false</url> |
| <user>synapse</user> |
| <password>synapse</password> |
| </pool> |
| </connection> |
| <statement> |
| <sql>update company set price=? where name =?</sql> |
| <parameter expression="//m0:return/m0:last/child::text()" |
| xmlns:m0="http://services.samples/xsd" type="DOUBLE"/> |
| <parameter expression="//m0:return/m0:symbol/child::text()" |
| xmlns:m0="http://services.samples/xsd" type="VARCHAR"/> |
| </statement> |
| </dbreport> |
| <log level="custom"> |
| <property name="text" |
| value="** Looking up from the Database **"/> |
| </log> |
| <dblookup xmlns="http://ws.apache.org/ns/synapse"> |
| <connection> |
| <pool> |
| <driver>org.apache.derby.jdbc.ClientDriver</driver> |
| <url>jdbc:derby://localhost:1527/synapsedb;create=false</url> |
| <user>synapse</user> |
| <password>synapse</password> |
| </pool> |
| </connection> |
| <statement> |
| <sql>select * from company where name =?</sql> |
| <parameter expression="//m0:return/m0:symbol/child::text()" |
| xmlns:m0="http://services.samples/xsd" type="VARCHAR"/> |
| <result name="stock_price" column="price"/> |
| </statement> |
| </dblookup> |
| <log level="custom"> |
| <property name="text" |
| expression="fn:concat('Stock price - ',get-property('stock_price'))"/> |
| </log> |
| <send/> |
| </out> |
| </sequence> |
| |
| </definitions></pre> |
| |
| <p><strong>Objective: Demonstrate the use of dbreport and dblookup |
| mediators</strong></p> |
| |
| <p><strong>Prerequisites:</strong> Setting up Derby database as above.</p> |
| |
| <p>Start the Synapse configuration numbered 362: i.e. synapse -sample 362</p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done</p> |
| |
| <p></p> |
| |
| <p>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.</p> |
| |
| <p>When running client,</p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM</pre> |
| |
| <p>Synapse console shows,</p> |
| <pre>INFO LogMediator text = ** Reporting to the Database **<br/><br/>...<br/><br/>INFO LogMediator text = ** Looking up from the Database **<br/><br/>...<br/><br/>INFO LogMediator text = Stock price - 153.47886496064808</pre> |
| |
| <p></p> |
| |
| <h2><a name="Throttle">Throttling messages (Throttle Mediator)</a></h2> |
| |
| <h2><a name="Sample370">Sample 370: Introduction to throttle mediator and |
| concurrency throttling</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <sequence name="main"> |
| <in> |
| <throttle id="A"> |
| <policy> |
| <!-- define throttle policy --> |
| <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" |
| xmlns:throttle="http://www.wso2.org/products/wso2commons/throttle"> |
| <throttle:ThrottleAssertion> |
| <throttle:MaximumConcurrentAccess>10</throttle:MaximumConcurrentAccess> |
| </throttle:ThrottleAssertion> |
| </wsp:Policy> |
| </policy> |
| <onAccept> |
| <log level="custom"> |
| <property name="text" value="**Access Accept**"/> |
| </log> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </onAccept> |
| <onReject> |
| <log level="custom"> |
| <property name="text" value="**Access Denied**"/> |
| </log> |
| <makefault> |
| <code value="tns:Receiver" |
| xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/> |
| <reason value="**Access Denied**"/> |
| </makefault> |
| <property name="RESPONSE" value="true"/> |
| <header name="To" action="remove"/> |
| <send/> |
| <drop/> |
| </onReject> |
| </throttle> |
| </in> |
| <out> |
| <throttle id="A"/> |
| <send/> |
| </out> |
| </sequence> |
| </definitions></pre> |
| |
| <p><b>Objective: Demonstrate the use of throttle mediator for concurrency |
| throttling </b></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Deploy the SimpleStockQuoteService in sample Axis2 server and start it on |
| port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 370 (i.e. synapse -sample |
| 370).</p> |
| |
| <p></p> |
| |
| <p>Above configuration specifies a throttle mediator inside the in mediator. |
| Therefore, all request messages directed to the main sequence will be |
| subjected to throttling. Throttle mediator has policy, onAccept and onReject |
| tags at top level. Policy tag specifies the throttling policy to be applied |
| for messages. In this sample policy contains only component called |
| "MaximumConcurrentAccess" .This indicates the maximum number of concurrent |
| request that may have passed through the synapse on a single unit of time. To |
| test concurrency throttling ,it is required to send concurrent request to |
| synapse. For synapse with above configuration ,if client send 20 request |
| concurrently ,then approximately half of those will success. The client |
| command is as follows.</p> |
| <pre>ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/</pre> |
| |
| <p></p> |
| |
| <h2><a name="Sample371">Sample 371: Restricting requests based on policies |
| </a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <sequence name="main"> |
| <in> |
| <throttle id="A"> |
| <policy> |
| <!-- define throttle policy --> |
| <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" |
| xmlns:throttle="http://www.wso2.org/products/wso2commons/throttle"> |
| <throttle:ThrottleAssertion> <br/> <wsp:All> |
| <throttle:ID throttle:type="IP">Other</throttle:ID> |
| <wsp:ExactlyOne> |
| <wsp:All> |
| <throttle:MaximumCount>4</throttle:MaximumCount> |
| <throttle:UnitTime>800000</throttle:UnitTime> |
| <throttle:ProhibitTimePeriod wsp:Optional="true">10000</throttle:ProhibitTimePeriod> |
| </wsp:All> |
| <throttle:IsAllow>true</throttle:IsAllow> |
| </wsp:ExactlyOne> |
| </wsp:All> |
| <wsp:All> |
| <throttle:ID throttle:type="IP">192.168.8.200-192.168.8.222</throttle:ID> |
| <wsp:ExactlyOne> |
| <wsp:All> |
| <throttle:MaximumCount>8</throttle:MaximumCount> |
| <throttle:UnitTime>800000</throttle:UnitTime> |
| <throttle:ProhibitTimePeriod wsp:Optional="true">10</throttle:ProhibitTimePeriod> |
| </wsp:All> |
| <throttle:IsAllow>true</throttle:IsAllow> |
| </wsp:ExactlyOne> |
| </wsp:All> |
| <wsp:All> |
| <throttle:ID throttle:type="IP">192.168.8.201</throttle:ID> |
| <wsp:ExactlyOne> |
| <wsp:All> |
| <throttle:MaximumCount>200</throttle:MaximumCount> |
| <throttle:UnitTime>600000</throttle:UnitTime> |
| <throttle:ProhibitTimePeriod wsp:Optional="true"></throttle:ProhibitTimePeriod> |
| </wsp:All> |
| <throttle:IsAllow>true</throttle:IsAllow> |
| </wsp:ExactlyOne> |
| </wsp:All> |
| <wsp:All> |
| <throttle:ID throttle:type="IP">192.168.8.198</throttle:ID> |
| <wsp:ExactlyOne> |
| <wsp:All> |
| <throttle:MaximumCount>50</throttle:MaximumCount> |
| <throttle:UnitTime>500000</throttle:UnitTime> |
| <throttle:ProhibitTimePeriod wsp:Optional="true"></throttle:ProhibitTimePeriod> |
| </wsp:All> |
| <throttle:IsAllow>true</throttle:IsAllow> |
| </wsp:ExactlyOne> |
| </wsp:All> |
| </throttle:ThrottleAssertion> |
| </wsp:Policy> |
| </policy> |
| <onAccept> |
| <log level="custom"> |
| <property name="text" value="**Access Accept**"/> |
| </log> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </onAccept> |
| <onReject> |
| <log level="custom"> |
| <property name="text" value="**Access Denied**"/> |
| </log> |
| <makefault> |
| <code value="tns:Receiver" |
| xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/> |
| <reason value="**Access Denied**"/> |
| </makefault> |
| <property name="RESPONSE" value="true"/> |
| <header name="To" action="remove"/> |
| <send/> |
| <drop/> |
| </onReject> |
| </throttle> |
| </in> |
| <out> |
| <throttle id="A"/> |
| <send/> |
| </out> |
| </sequence> |
| </definitions></pre> |
| |
| <p><strong>Objective: Demonstrate the use of throttle mediator for |
| restricting request counts</strong> </p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Deploy the SimpleStockQuoteService in sample Axis2 server and start it on |
| port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 371 (i.e. synapse -sample |
| 371).</p> |
| |
| <p></p> |
| |
| <p>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.</p> |
| <pre>ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/</pre> |
| |
| <p>For the first four requests you will get the quote prices for IBM as |
| follows.</p> |
| <pre>[java] Standard :: Stock price = $177.20143371883802</pre> |
| |
| <p>You will receive the following response for the fifth request.</p> |
| <pre>[java] org.apache.axis2.AxisFault: **Access Denied**</pre> |
| |
| <p>Maximum number of requests within 800000 milliseconds is specified as 4 |
| for any server (including localhost) other than the explicitly specified |
| ones. Therefore, our fifth request is denied by the throttle mediator. You |
| can verify this by looking at the Synapse console.</p> |
| <pre>[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** </pre> |
| |
| <h2><a name="Sample372">Sample 372: Use of both concurrency throttling and |
| request rate based throttling </a></h2> |
| <pre><!-- 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></pre> |
| |
| <div> |
| </div> |
| |
| <p><strong>Objective: Use of both concurrency throttling and request rate |
| based throttling </strong></p> |
| |
| <p><strong>Prerequisites:</strong> Deploy the SimpleStockQuoteService in |
| sample Axis2 server and start it on port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 372 (i.e. synapse -sample |
| 372).</p> |
| |
| <p></p> |
| |
| <p>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.</p> |
| |
| <p>Run the client as follows </p> |
| <pre>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy</pre> |
| |
| <div> |
| <p>You will get results same as sample 371.if you run the load test, results |
| will be different due to affect of concurrency throttling.</p> |
| </div> |
| |
| <h2><a name="Class">Extending the mediation in java (Class Mediator)</a></h2> |
| |
| <p>Class mediator can be used to write your own custom mediation in Java and |
| you have access to the SynapseMessageContext and all the Synapse API in |
| there. This is a useful extension mechanism within Synapse to extend its |
| functionality. This class can contain fields for which you can assign values |
| at runtime through the configuration.</p> |
| |
| <h2><a name="Sample380">Sample 380: Writing your own custom mediation in |
| Java</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <sequence name="fault"> |
| <makefault> |
| <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/> |
| <reason value="Mediation failed."/> |
| </makefault> |
| <send/> |
| </sequence> |
| |
| <sequence name="main" onError="fault"> |
| <in> |
| <send> |
| <endpoint name="stockquote"> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </in> |
| <out> |
| <class name="samples.mediators.DiscountQuoteMediator"> |
| <property name="discountFactor" value="10"/> |
| <property name="bonusFor" value="5"/> |
| </class> |
| <send/> |
| </out> |
| </sequence> |
| |
| </definitions></pre> |
| |
| <p></p> |
| |
| <p><strong>Objective: Demonstrate the use of Class mediator to extend the |
| mediation functionality</strong></p> |
| |
| <p><strong>Prerequisites:</strong></p> |
| |
| <p>Make sure the synapse-samples-1.0.jar is in your class path (by default |
| this jar is placed in the lib directory when installing Synapse).</p> |
| |
| <p>Start Synapse with the sample configuration 380 (i.e. synapse -sample |
| 380)</p> |
| |
| <p>Start the sample Axis2 server and deploy the SimpleStockQuoteService.</p> |
| |
| <p></p> |
| |
| <p>In this configuration, Synapse hands over the request message to the |
| specified endpoint, which sends it to the Axis2 server running on port |
| 9000.</p> |
| |
| <p>But the response message is passed through the class mediator before |
| sending it back to the client. Two parameters named "discountFactor"</p> |
| |
| <p>and "bonusFor" are passed to the instance mediator implementation class |
| (i.e. samples.mediators.DiscountQuoteMediator) before each</p> |
| |
| <p>invocation. Code of the mediator implementation class is shown below.</p> |
| <pre>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; |
| } |
| }</pre> |
| |
| <p>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.</p> |
| |
| <p></p> |
| |
| <p>Now run the client using the following command.</p> |
| <pre>ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080</pre> |
| |
| <p>You will see the below output in the client console with the discounted |
| quote value.</p> |
| <pre>[java] Standard :: Stock price = $138.77458254967408</pre> |
| |
| <p>Now check the console running Synapse. You will see the original value and |
| the discounted value for the requested quote as follows.</p> |
| <pre>Quote value discounted. |
| Original price: 162.30945327447262 |
| Discounted price: 138.77458254967408</pre> |
| |
| <p></p> |
| |
| <h2><a name="XQuery">Evaluating XQuery for mediation (XQuery |
| Mediator)</a></h2> |
| |
| <h2><a name="Sample390">Sample 390: Introduction to the XQuery |
| mediator</a></h2> |
| <pre> <!-- Introduction to the XQuery mediator --> |
| <definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <!-- the SimpleURLRegistry allows access to a URL based registry (e.g. file:/// or http://) --> |
| <registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"> |
| <!-- the root property of the simple URL registry helps resolve a resource URL as root + key --> |
| <parameter name="root">file:repository/conf/sample/resources/</parameter> |
| <!-- all resources loaded from the URL registry would be cached for this number of milli seconds --> |
| <parameter name="cachableDuration">15000</parameter> |
| </registry> |
| |
| <localEntry key="xquery-key-req" |
| src="file:repository/conf/sample/resources/xquery/xquery_req.xq"/> |
| <proxy name="StockQuoteProxy"> |
| <target> |
| <inSequence> |
| <xquery key="xquery-key-req"> |
| <variable name="payload" type="ELEMENT"/> |
| </xquery> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </inSequence> |
| <outSequence> |
| <out> |
| <xquery key="xquery/xquery_res.xq"> |
| <variable name="payload" type="ELEMENT"/> |
| <variable name="code" type="STRING" |
| expression="self::node()//m0:return/m0:symbol/child::text()" |
| xmlns:m0="http://services.samples/xsd"/> |
| <variable name="price" type="DOUBLE" |
| expression="self::node()//m0:return/m0:last/child::text()" |
| xmlns:m0="http://services.samples/xsd"/> |
| </xquery> |
| <send/> |
| </out> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/> |
| </proxy> |
| |
| </definitions> </pre> |
| |
| <p><b>Objective: Introduction transformation using XQuery mediator</b></p> |
| |
| <p><b>Prerequisites</b>:Start the Synapse configuration numbered 390: i.e. |
| synapse -sample 390 </p> |
| |
| <p>Start the Axis2 server and deploy the SimpleStockQuoteService if not |
| already done.</p> |
| |
| <p></p> |
| |
| <p>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.</p> |
| |
| <p></p> |
| |
| <p>Execute the custom quote client as 'ant stockquote -Dmode=customquote ...' |
| </p> |
| <pre>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dmode=customquote </pre> |
| |
| <p></p> |
| |
| <h2><a name="Sample391">Sample 391: How to use data from an external XML |
| document with in XQuery </a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <!-- the SimpleURLRegistry allows access to URL based registry (e.g. file:/// or http://) --> |
| <registry provider="org.apache.synapse.registry.url.SimpleURLRegistry"> |
| <!-- the root property of the simple URL registry helps resolve a resource URL as root + key --> |
| <parameter name="root">file:repository/conf/sample/resources/</parameter> |
| <!-- all resources loaded from the URL registry would be cached for this number of milli seconds --> |
| <parameter name="cachableDuration">15000</parameter> |
| </registry> |
| |
| <proxy name="StockQuoteProxy"> |
| <target> |
| <inSequence> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </inSequence> |
| <outSequence> |
| <out> |
| <xquery key="xquery/xquery_commisson.xq"> |
| <variable name="payload" type="ELEMENT"></variable> |
| <variable name="commission" type="ELEMENT" key="misc/commission.xml"></variable> |
| </xquery> |
| <send/> |
| </out> |
| </outSequence> |
| </target> |
| <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/></proxy></definitions> ns></pre> |
| |
| <p><b></b></p> |
| |
| <p><b><strong>Objective: Demonstrate the use of XQuery mediator to import |
| external XML documents to the XQuery engine</strong></b></p> |
| |
| <p><strong>Prerequisites:</strong>Deploy the SimpleStockQuoteService in |
| sample Axis2 server and start it on port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 391 (i.e. synapse -sample |
| 391).</p> |
| |
| <p>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 .</p> |
| |
| <p>Invoke the client as follows. </p> |
| <pre>ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy</pre> |
| |
| <h2><a name="Splitter">Splitting messages in to parts and process in parallel |
| (Iterate / Clone)</a></h2> |
| |
| <h2><a name="Sample400">Sample 400: Message splitting and aggregating the |
| responses</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| |
| <proxy name="SplitAggregateProxy"> |
| <target> |
| <inSequence> |
| <iterate expression="//m0:getQuote/m0:request" preservePayload="true" |
| attachPath="//m0:getQuote" |
| xmlns:m0="http://services.samples/xsd"> |
| <target> |
| <sequence> |
| <send> |
| <endpoint> |
| <address |
| uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </sequence> |
| </target> |
| </iterate> |
| </inSequence> |
| <outSequence> |
| <aggregate> |
| <onComplete expression="//m0:getQuoteResponse" |
| xmlns:m0="http://services.samples/xsd"> |
| <send/> |
| </onComplete> |
| <invalidate> |
| <log level="full"/> |
| <drop/> |
| </invalidate> |
| </aggregate> |
| </outSequence> |
| </target> |
| </proxy> |
| </definitions></pre> |
| |
| <p><b><strong>Objective: Demonstrate the use of Iterate mediator to split the |
| messages in to parts and process them asynchronously and then aggregate the |
| responses coming in to synapse</strong></b></p> |
| |
| <p><strong>Prerequisites:</strong>Deploy the SimpleStockQuoteService in |
| sample Axis2 server and start it on port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 400 (i.e. synapse -sample |
| 400).</p> |
| |
| <p>In this sample, the message sent to synapse has embedded with a number of |
| elements of the same type in one message. When synapse received this message |
| it will iterate through those elements and then sent to the specified |
| endpoint. When all the responses appear in to synapse then those messages |
| will be aggregated to form the resultant response and sent back to the |
| client.</p> |
| |
| <p>Invoke the client as follows. </p> |
| <pre>ant stockquote -Daddurl=http://localhost:8080/soap/SplitAggregateProxy -Ditr=4</pre> |
| <!--<h2><a name="Aggregator">Aggregating messages and process in batch (Aggregate--> |
| <!--Mediator)</a></h2>--> |
| <!----> |
| <!--<h2><a name="Sample410">Sample 410: Message aggregation for batch--> |
| <!--processing</a></h2>--> |
| <!----> |
| |
| <h2><a name="Cache">Caching the responses over the requests (Cache |
| Mediator)</a></h2> |
| |
| <p>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)</p> |
| |
| <h2><a name="Sample420">Sample 420: Simple cache implemented on synapse for |
| the actual service</a></h2> |
| <pre><definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <in> |
| <cache timeout="20000" scope="per-host" collector="false" |
| hashGenerator="org.wso2.caching.digest.DOMHASHGenerator"> |
| <implementation type="memory" maxSize="100"/> |
| </cache> |
| <send> |
| <endpoint> |
| <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> |
| </endpoint> |
| </send> |
| </in> |
| <out> |
| <cache collector="true"/> |
| <send/> |
| </out> |
| </definitions></pre> |
| |
| <p><b><strong>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</strong></b></p> |
| |
| <p><strong>Prerequisites:</strong>Deploy the SimpleStockQuoteService in |
| sample Axis2 server and start it on port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 420 (i.e. synapse -sample |
| 420).</p> |
| |
| <p>In this sample, the message sent to synapse is checked for an existing |
| cached response by calculating the hash value of the request. If there is a |
| cache hit in synapse then this request will not be forwarded to the actual |
| service, rather synapse respond to the client with the cached response. In |
| case of a cache miss that particular message will be forwarded to the actual |
| service and cached that response in the out path for the use of consecutive |
| requests of the same type.</p> |
| |
| <p>To observe this behaviour, invoke the client as follows. </p> |
| <pre>ant stockquote -Dtrpurl=http://localhost:8080/</pre> |
| |
| <p>You could notice that if you send more than one requests within 20 seconds |
| only the first request is forwarded to the actual service, and the rest of |
| the requests will be served by the cache inside Synapse. You could observe |
| this by looking at the printed line of the axis2 server, as well as by |
| observing a constant rate as the response to the client instead of the random |
| rate, which changes by each and every 20 seconds.<br/> |
| </p> |
| |
| <h2><a name="Callout">Synchronize web service invocation with Callout |
| mediator </a></h2> |
| |
| <p>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. </p> |
| |
| <h2><a name="Sample430">Sample 430: Simple Callout Mediator |
| for synchronizing web service invocation</a></h2> |
| |
| <p> </p> |
| <pre> |
| <!-- Simple callout mediator --> |
| <definitions xmlns="http://ws.apache.org/ns/synapse"> |
| <callout serviceURL="http://localhost:9000/soap/SimpleStockQuoteService" |
| action="urn:getQuote"> |
| <source xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" |
| xmlns:s12="http://www.w3.org/2003/05/soap-envelope" |
| xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/> |
| <target xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" |
| xmlns:s12="http://www.w3.org/2003/05/soap-envelope" |
| xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/> |
| </callout> |
| <property name="RESPONSE" value="true"/> |
| <header name="To" action="remove"/> |
| <send/> |
| <drop/> |
| </definitions> </pre> |
| |
| <div> |
| <p><strong>Objective:</strong> Demonstrate the use of the Callout mediator |
| for the synchronized web service invocation</p> |
| |
| <p><strong>Prerequisites:</strong> Deploy the SimpleStockQuoteService in |
| sample Axis2 server and start it on port 9000.</p> |
| |
| <p>Start Synapse with the sample configuration 430 (i.e. synapse -sample |
| 430).</p> |
| |
| <p>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. </p> |
| |
| <p>Invoke the client as follows. </p> |
| <pre>ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/</pre> |
| </div> |
| </body> |
| </html> |