Running the Synapse Samples

Synapse logo

Contents

Message Mediation Samples

Sample 0: Introduction to Synapse

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <!-- log all attributes of messages passing through -->
    <log level="full"/>

    <!-- Send the messageto implicit destination -->
    <send/>
</definitions>

Objective: Introduction to Synapse. Shows how a message could be made to pass through Synapse and logged before it is delivered to its ultimate receiver.

The Stock quote client can operate in the following modes for this example.

  1. Smart Client mode
  2. ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ 
  3. Using Synapse as a HTTP Proxy
  4. ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dprxurl=http://localhost:8080/
  5. Gateway Mode / Dumb Client
  6. See sample # 1

Prerequisites:
Start the Synapse configuration numbered 0: e.g. synapse -sample 0
Start the Axis2 server and deploy the SimpleStockQuoteService if not already deployed

Execute the Smart Client

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.

Sat Nov 18 21:01:23 IST 2006 SimpleStockQuoteService :: Generating quote for : IBM

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.

Standard :: Stock price = $95.26454380258552

Execute the Proxy Client

You will see the exact same behaviour as per the previous example when you run this scenario. However this time the difference is at the client, as it sends the message to the WS-Addressing 'To' address http://localhost:9000/soap/SimpleStockQuoteService, but the transport specifies Synapse as the http proxy.

Sample 1: Simple content based routing (CBR) of messages

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <!-- filtering of messages with XPath and regex matches -->
    <filter source="get-property('To')" regex=".*/StockQuote.*">
        <send>
            <endpoint>
                <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
            </endpoint>
        </send>
        <drop/>
    </filter>
    <send/>
</definitions> 

Objective: Introduction to simple content based routing. Shows how a message could be made to pass through 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.

Prerequisites:
Start the Synapse configuration numbered 1: i.e. synapse -sample 1
Start the Axis2 server and deploy the SimpleStockQuoteService if not already deployed

Execute the Dumb Client as:

ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuote

This time you will see 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.

Sample 2: CBR with the Switch-case mediator, using message properties

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <switch source="//m0:getQuote/m0:request/m0:symbol" xmlns:m0="http://services.samples/xsd">
        <case regex="IBM">
            <!-- the property mediator sets a local property on the *current* message -->
            <property name="symbol" value="Great stock - IBM"/>
        </case>
        <case regex="MSFT">
            <property name="symbol" value="Are you sure? - MSFT"/>
        </case>
        <default>
            <!-- it is possible to assign the result of an XPath expression as well -->
            <property name="symbol"
                  expression="fn:concat('Normal Stock - ', //m0:getQuote/m0:request/m0:symbol)"
                  xmlns:m0="http://services.samples/xsd"/>
        </default>
    </switch>

    <log level="custom">
        <!-- the get-property() XPath extension function allows the lookup of local message properties
            as well as properties from the Axis2 or Transport contexts (i.e. transport headers) -->
        <property name="symbol" expression="get-property('symbol')"/>
        <!-- the get-property() function supports the implicit message headers To/From/Action/FaultTo/ReplyTo -->
        <property name="epr" expression="get-property('To')"/>
    </log>

    <!-- Send the messages where they are destined to (i.e. the 'To' EPR of the message) -->
    <send/>
</definitions>

Objective: Introduce switch-case mediator and writing and reading of local properties set on a message instance

Prerequisites:
Start the Synapse configuration numbered 2: i.e. synapse -sample 2
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done.

Execute the 'ant stockquote ..' request again in the smart client mode, specifying 'IBM', 'MSFT' and 'SUN' as the stock symbols. When the symbol IBM is requested, viewing the mediation logs you will see that the case statements' first case for 'IBM' is executed and a local property named 'symbol' was set to 'Great stock - IBM'. Subsequently this local property value is looked up by the log mediator and logged using the 'get-property()' XPath extension function.

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=IBM

INFO LogMediator - symbol = Great stock - IBM, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService 

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT

INFO LogMediator - symbol = Are you sure? - MSFT, epr = http://localhost:9000/axis2/services/SimpleStockQuoteService

Sample 3: Local Registry entry definitions, reusable endpoints and sequences

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <!-- define a string resource entry to the local registry -->
    <localEntry key="version">0.1</localEntry>
    <!-- define a reuseable endpoint definition -->
    <endpoint name="simple">
        <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
    </endpoint>

    <!-- define a reusable sequence -->
    <sequence name="stockquote">
        <!-- log the message using the custom log level. illustrates custom properties for log -->
        <log level="custom">
            <property name="Text" value="Sending quote request"/>
            <property name="version" expression="get-property('version')"/>
            <property name="direction" expression="get-property('direction')"/>
        </log>
        <!-- send message to real endpoint referenced by key "simple" endpoint definition -->
        <send>
            <endpoint key="simple"/>
        </send>
    </sequence>

    <sequence name="main">
        <in>
            <property name="direction" value="incoming"/>
            <sequence key="stockquote"/>
        </in>
        <out>
            <send/>
        </out>
    </sequence>
</definitions>

Objective: Illustrates local registry entry definitions, reusable endpoints and sequences

Prerequisites:
Start the Synapse configuration numbered 3: i.e. synapse -sample 3
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This example uses a sequence named as "main" that specifies the main mediation rules to be executed. This is equivalent to directly specifying the mediators of the main sequence within the <definitions> tags. This is the recommended and also a better approach for non-trivial configurations. Execute the 'ant stockquote ..' request again, and following through the mediation logs you will now notice that the sequence named "main" is executed. Then for the incoming message flow the <in> mediator executes, and it calls into the sequence named "stockquote".

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
DEBUG SequenceMediator - Sequence mediator <main> :: mediate()
DEBUG InMediator - In mediator mediate()
DEBUG SequenceMediator - Sequence mediator <stockquote> :: mediate()

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.

[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 

Sample 4: Introduction to error handling

<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> 

Objective: Introduction to error handling with the 'fault' sequence

Prerequisites:
Start the Synapse configuration numbered 4: i.e. synapse -sample 4
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

When the IBM stock quote is requested, the configuration routes it to the defined inline endpoint, which routes the message to the SimpleStockQuoteService on the local Axis2 instance. Hence a valid response message is shown at the client.

If you lookup a stock quote for 'MSFT', 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.

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT
[HttpServerWorker-1] DEBUG SendMediator - Send mediator :: mediate()
[HttpServerWorker-1] ERROR IndirectEndpoint - Reference to non-existent endpoint for key : bogus
[HttpServerWorker-1] DEBUG MediatorFaultHandler - MediatorFaultHandler :: handleFault
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <fault> :: mediate()
[HttpServerWorker-1] DEBUG LogMediator - Log mediator :: mediate()
[HttpServerWorker-1] INFO  LogMediator - text = An unexpected error occured, message = Reference to non-existent endpoint for key : bogus

When the 'SUN' quote is requested, a custom sequence 'sunSequence' is invoked, and it specifies 'sunErrorHandler' as its error handler. Hence when the send fails, you could see the proper error handler invocation and the custom error message printed as follows.

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <sunSequence> :: mediate()
[HttpServerWorker-1] DEBUG SequenceMediator - Setting the onError handler for the sequence
[HttpServerWorker-1] DEBUG AbstractListMediator - Implicit Sequence <SequenceMediator> :: mediate()
[HttpServerWorker-1] DEBUG SendMediator - Send mediator :: mediate()
[HttpServerWorker-1] ERROR IndirectEndpoint - Reference to non-existent endpoint for key : sunPort
[HttpServerWorker-1] DEBUG MediatorFaultHandler - MediatorFaultHandler :: handleFault
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <sunErrorHandler> :: mediate()
[HttpServerWorker-1] DEBUG AbstractListMediator - Implicit Sequence <SequenceMediator> :: mediate()
[HttpServerWorker-1] DEBUG LogMediator - Log mediator :: mediate()
[HttpServerWorker-1] INFO  LogMediator - text = An unexpected error occured for stock SUN, message = Reference to non-existent endpoint for key : sunPort

Sample 5: Creating SOAP fault messages and changing the direction of a message

<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>

Objective: Makefault mediator and sending back error responses

Prerequisites:
Start the Synapse configuration numbered 5: i.e. synapse -sample 5
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

When the MSFT stock quote is requested, an unknown host exception would be generated. A connection refused exception would be generated for the SUN stock request. This error message is captured and returned to the original client as a SOAP fault in this example.

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=MSFT

returns,

<soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><faultcode>soapenv:Client</faultcode>
    <faultstring>java.net.UnknownHostException: bogus</faultstring><detail /></soapenv:Fault>

And

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dsymbol=SUN

returns,

<soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><faultcode>soapenv:Client</faultcode>
    <faultstring>java.net.ConnectException: Connection refused</faultstring><detail /></soapenv:Fault>

Sample 6: Manipulating SOAP headers, and filtering incoming and outgoing messages

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <in>
        <header name="To" value="http://localhost:9000/soap/SimpleStockQuoteService"/>
    </in>
    <send/>
</definitions>

Objective: Introduction to header, in (out) mediators

Prerequisites:
Start the Synapse configuration numbered 6: i.e. synapse -sample 6
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

In this example we use the stockquote client in the dumb client mode, setting the 'To' EPR of the message to 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.

ant stockquote -Dtrpurl=http://localhost:8080/

Sample 7: Introduction to local Registry entries and using Schema validation

<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> 

Objective: Introduction to local (static) registry entries and the validate mediator

Prerequisites:
Start the Synapse configuration numbered 7: i.e. synapse -sample 7
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This example shows how a static XML fragment could be made available to the 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'.

The validate mediator by default operates on the first child element of the SOAP body. You may specify an XPath expression using the 'source' attribute to override this behaviour. The validate mediator now uses the 'validate_schema' resource to validate the incoming message, and if the message validatation fails it invokes the 'on-fail' sequence of mediators.

If you send a stockquote request using 'ant stockquote ...' you will get a fault back with the message 'Invalid custom quote request' as the schema validation failed. This is because the schema used in the example expects a slightly different message than what is created by the stock quote client. (i.e. expects a 'stocksymbol' element instead of 'symbol' to specify thestock symbol)

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/

Sample 8: Introduction to static and dynamic registry resources, and using XSLT transformations

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <!-- the SimpleURLRegistry allows access to a URL based registry (e.g. file:/// or http://) -->
    <registry provider="org.apache.synapse.registry.url.SimpleURLRegistry">
        <!-- the root property of the simple URL registry helps resolve a resource URL as root + key -->
        <parameter name="root">file:./repository/conf/sample/resources/</parameter>
        <!-- all resources loaded from the URL registry would be cached for this number of milli seconds -->
        <parameter name="cachableDuration">15000</parameter>
    </registry>

    <!-- define the request processing XSLT resource as a static URL source -->
    <localEntry key="xslt-key-req" src="file:repository/conf/sample/resources/transform/transform.xslt"/>

    <in>
        <!-- transform the custom quote request into a standard quote requst expected by the service -->
        <xslt key="xslt-key-req"/>
    </in>
    <out>
        <!-- transform the standard response back into the custom format the client expects -->
        <!-- the key is looked up in the remote registry and loaded as a 'dynamic' registry resource -->
        <xslt key="transform/transform_back.xslt"/>
    </out>
    <send/>
</definitions>

Objective: Introduction to static and dynamic registry resources and the XSLT mediator

Prerequisites:
Start the Synapse configuration numbered 8: i.e. synapse -sample 8
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This example uses the XSLT mediator to perform transformations, and the xslt tranformations are specified as registry resources. The first resource 'xslt-key-req' is specified as a 'local' registry entry. Local entries do not place the resource on the registry, but simply make it available to the local configuration. If a local entry is defined with a key that already exists in the remote registry, the local entry will have higher preference and override the remote resource.

In this example you will notice the new 'registry' definition. 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.

Hence the second XSLT resource key 'transform/transform_back.xslt' concatenated with the 'root' of the SimpleURLRegistry 'file:repository/conf/sample/resources/' forms the complete URL of the resource as 'file:repository/conf/sample/resources/transform/transform_back.xslt' and caches its value for a period of 15000 ms.

Execute the custom quote client as 'ant stockquote -Dmode=customquote ...' and analyze the the Synapse debug log output

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=customquote

The incoming message is now transformed into a standard stock quote request as expected by the SimpleStockQuoteService deployed on the local Axis2 instance, by the XSLT mediator. The XSLT mediator uses Xalan-J to perform the transformations. It is possible to configure the underlying transformation engine using properties where necessary. The response from the SimpleStockQuoteService is converted back into the custom format as expected by the client during the out message processing.

During the response processing you could see the SimpleURLRegistry fetching the resource as shown by the log message below

[HttpClientWorker-1] INFO  SimpleURLRegistry - ==> Repository fetch of resource with key : transform/transform_back.xslt

If you run the client again immediately (i.e within 15 seconds of the first request) you will not see the resource being reloaded by the registry as the cached value would be still valid.

However if you leave the system idle for 15 seconds or more and then retry the same request, you will now notice that the registry noticed the cached resource has expired and will check the meta information about the resource to check if the resource itself has changed and will require a fresh fetch from the source URL. If the meta data / version number indicates that a reload of the cached resource is not necessary (i.e. unless the resource itself actually changed) the updated meta information is used and the cache lease extended as appropriate.

[HttpClientWorker-1] DEBUG AbstractRegistry - Cached object has expired for key : transform/transform_back.xslt
[HttpClientWorker-1] DEBUG SimpleURLRegistry - Perform RegistryEntry lookup for key : transform/transform_back.xslt
[HttpClientWorker-1] DEBUG AbstractRegistry - Expired version number is same as current version in registry
[HttpClientWorker-1] DEBUG AbstractRegistry - Renew cache lease for another 15s 

Now edit the repository/conf/sample/resources/transform/transform_back.xslt file and add a blank line at the end. Now when you run the client again, and if the cache is expired, the resource would be re-fetched from its URL by the registry and this can be seen by the following debug log messages

[HttpClientWorker-1] DEBUG AbstractRegistry - Cached object has expired for key : transform/transform_back.xslt
[HttpClientWorker-1] DEBUG SimpleURLRegistry - Perform RegistryEntry lookup for key : transform/transform_back.xslt
[HttpClientWorker-1] INFO  SimpleURLRegistry - ==> Repository fetch of resource with key : transform/transform_back.xslt 

Thus the SimpleURLRegistry allows resource to be cached, and updates detected so that the changes could be reloaded without restarting the Synapse instance.

Sample 9: Introduction to dynamic sequences with the Registry

<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> 

Objective: Introduction to dynamic sequences with a Registry

Prerequisites:
Start the Synapse configuration numbered 9: i.e. synapse -sample 9
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

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.

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:

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
[HttpServerWorker-1] INFO  SimpleURLRegistry - ==> Repository fetch of resource with key : sequence/dynamic_seq_1.xml
...
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <dynamic_sequence> :: mediate()
...
[HttpServerWorker-1] INFO  LogMediator - message = *** Test Message 1 ***

Now if you execute the client immediately (i.e. within 15 seconds of the last execution) you will notice that the sequence was not reloaded. If you edit the sequence definition in repository/conf/sample/resources/sequence/dynamic_seq_1.xml (i.e. edit the log message to read as "*** Test Message 2 ***") and execute the client again, you will notice that the new message is not yet visible (i.e. if you execute this within 15 seconds of loading the resource for the first time) However, after 15 seconds elapsed since the original caching of the sequence, you will notice that the new sequence is loaded and executed by Synapse from the following log messages.

[HttpServerWorker-1] INFO  SimpleURLRegistry - ==> Repository fetch of resource with key : sequence/dynamic_seq_1.xml
...
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <dynamic_sequence> :: mediate()
...
[HttpServerWorker-1] INFO  LogMediator - message = *** Test Message 2 ***

The cache timeout could be tuned appropriately by configuring the URL registry to suite the environment and the needs.

Sample 10: Introduction to dynamic endpoints with the Registry

<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> 

Objective: Introduction to dynamic endpoints with the Registry

Prerequisites:
Start the Synapse configuration numbered 10: i.e. synapse -sample 10
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done
Start a second Axis2 server on http port 9001 and https port 9003 as follows:

./axis2server.sh -http 9001 -https 9003

This example introduces dynamic endpoints, where the definition of an endpoint is stored in the Registry. To follow this example execute the stock quote client as 'ant stockquote..' and see that the message is routed to the SimpleStockQuoteService on the default Axis2 instance on http port 9000. Repeat the above example immediately again, and notice that the endpoint is cached and reused by Synapse - similarly to example # 8.

ant stockquote -Dtrpurl=http://localhost:8080/

Now edit the repository/conf/sample/resources/endpoint/dynamic_endpt_1.xml definition and update the address to "http://localhost:9001/soap/SimpleStockQuoteService". After the cached expires, the Registry loads the new definition of the endpoint, and then the messages can be seen being routed to the second sample Axis2 server on http port 9001.

Sample 11: A full registry based configuration, and sharing a configuration between multiple instances

<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> 

Objective: A full registry based configuration

Prerequisites:
Start the Synapse configuration numbered 11: i.e. synapse -sample 11
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

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'.

(Note: Full registry based configuration is not dynamic atleast for the moment. i.e. it is not reloading itself)

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/
[HttpServerWorker-1] INFO LogMediator - message = This is a dynamic Synapse configuration

The actual synapse.xml loaded is:

<!-- a registry based Synapse configuration -->
<definitions xmlns="http://ws.apache.org/ns/synapse">
    <log level="custom">
        <property name="message" value="This is a dynamic Synapse configuration $$$"/>
    </log>
    <send/>
</definitions>

Sample 12: One way messaging / fireAndForget through synapse

Objective: Demonstrate one way messaging / fireAndForget through synapse

Prerequisites:
Start the Axis2 server and deploy the SimpleStockQuoteService (Refer steps above)
Start the Synapse configuration numbered 1: i.e. synapse -sample 1

This example invokes the one-way 'placeOrder' operation on the SimpleStockQuoteService using the custom client which uses the Axis2 ServiceClient.fireAndForget() API. To test this, use 'ant -Dmode=placeorder...' and you will notice the one way message flowing through Synapse into the sample Axis2 server instance, which reports the acceptance of the order as follows:

ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService -Dtrpurl=http://localhost:8080/ -Dmode=placeorder
SimpleStockQuoteService :: Accepted order for : 7482 stocks of IBM at $ 169.27205579038733

If you send your client request through TCPmon, you will notice that the SimpleStockQuoteService replies to Synapse with a HTTP 202 reply, and that Synapse in-turn replies to the client with a HTTP 202 acknowledgement

Advanced mediations with endpoints

Sample 50: POX to SOAP conversion

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <!-- filtering of messages with XPath and regex matches -->
    <filter source="get-property('To')" regex=".*/StockQuote.*">
        <send>
            <endpoint>
                <address uri="http://localhost:9000/soap/SimpleStockQuoteService" format="soap11"/>
            </endpoint>
        </send>
        <drop/>
    </filter>
    <send/>
</definitions> 

Objective: POX to SOAP conversion

Prerequisites:
Start the Synapse configuration numbered 50: i.e. synapse -sample 50

Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

Execute the 'ant stockquote' specifying that the request should be a REST request as follows:

ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuote -Drest=true

This example shows a http REST request (as shown below) being transformed into a SOAP request and forwarded to the stock quote service.

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

Sample 51: MTOM and SwA optimizations and request/response correlation

<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>

Objective: MTOM and SwA optimizations and request/response correlation

Prerequisites:
Start the Synapse configuration numbered 51: i.e. synapse -sample 51
Start the Axis2 server and deploy the MTOMSwASampleService if not already done

Execute the 'ant optimizeclient' specifying MTOM optimization as follows:

ant optimizeclient -Dopt_mode=mtom

The configuration now sets a local message context property, and forwards the message to 'http://localhost:9000/soap/MTOMSwASampleService' optimizing binary content as MTOM. By sending this message through TCPMon you would be able to see the actual message sent over the http transport if required. Thus during response processing, by checking the local message property 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.

When the client executes successfully, it will upload a file containing the ASF logo and receive its response back again and save it into a temporary file.

[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as MTOM
[java] Saved response to file : /tmp/mtom-36877.gif

Next try SwA as:

ant optimizeclient -Dopt_mode=swa
[java] Sending file : ./../../repository/conf/sample/resources/mtom/asf-logo.gif as SwA
[java] Saved response to file : /tmp/swa-47549.gif

By using TCPMon and sending the message through it, one can inspect that the requests and responses sent are indeed MTOM optimized or sent as http attachments as follows:

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 >>
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 >>

Sample 52: Session less load balancing between 3 endpoints

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main" onError="errorHandler">
        <in>
            <send>
                <endpoint>
                    <loadbalance>
                        <endpoint>
                            <address uri="http://localhost:9001/soap/LBService1">
                                <enableAddressing/>
                                <suspendDurationOnFailure>60</suspendDurationOnFailure>
                            </address>
                        </endpoint>
                        <endpoint>
                            <address uri="http://localhost:9002/soap/LBService1">
                                <enableAddressing/>
                                <suspendDurationOnFailure>60</suspendDurationOnFailure>
                            </address>
                        </endpoint>
                        <endpoint>
                            <address uri="http://localhost:9003/soap/LBService1">
                                <enableAddressing/>
                                <suspendDurationOnFailure>60</suspendDurationOnFailure>
                            </address>
                        </endpoint>
                    </loadbalance>
                </endpoint>
            </send>
<drop/>
        </in>

        <out>
            <!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
            <send/>
        </out>
    </sequence>

    <sequence name="errorHandler">

        <makefault>
            <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
        </makefault>

        <header name="To" action="remove"/>
        <property name="RESPONSE" value="true"/>

        <send/>
    </sequence>

</definitions>

Objective: Demonstrate the simple load balancing among set of endpoints

Prerequisites:

Start Synapse with sample configuration 52. (i.e. synapse -sample 52)

Deploy the LoadbalanceFailoverService by switching to <synapse installation directory>/samples/axis2Server/src/LoadbalanceFailoverService directory and running ant.

Start three instances of sample Axis2 server on HTTP ports 9001, 9002 and 9003 and give some unique names to each server.

Example commands to run sample Axis2 servers from the <synapse installation directory>/samples/axis2Server directory in Linux are listed below:

./axis2server.sh -http 9001 -https 9005 -name MyServer1
./axis2server.sh -http 9002 -https 9006 -name MyServer2
./axis2server.sh -http 9003 -https 9007 -name MyServer3

Now we are done with setting up the environment for load balance sample. Start the load balance and failover client using the following command:

ant loadbalancefailover -Di=100

This client sends 100 requests to the LoadbalanceFailoverService through 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:

[java] Request: 1 ==> Response from server: MyServer1
[java] Request: 2 ==> Response from server: MyServer2
[java] Request: 3 ==> Response from server: MyServer3
[java] Request: 4 ==> Response from server: MyServer1
[java] Request: 5 ==> Response from server: MyServer2
[java] Request: 6 ==> Response from server: MyServer3
[java] Request: 7 ==> Response from server: MyServer1
...

Now run the client without the -Di=100 parameter to send infinite requests. While running the client shutdown the server named MyServer1. You can observe that requests are only distributed among MyServer2 and MyServer3 after shutting down MyServer1. Console output before and after shutting down MyServer1 is listed below (MyServer1 was shutdown after request 63):

...
[java] Request: 61 ==> Response from server: MyServer1
[java] Request: 62 ==> Response from server: MyServer2
[java] Request: 63 ==> Response from server: MyServer3
[java] Request: 64 ==> Response from server: MyServer2
[java] Request: 65 ==> Response from server: MyServer3
[java] Request: 66 ==> Response from server: MyServer2
[java] Request: 67 ==> Response from server: MyServer3
...

Now restart MyServer1. You can observe that requets will be again sent to all three servers roughly after 60 seconds. This is because we have specified <suspendDurationOnFailure> as 60 seconds in the configuration. Therefore, load balance endpoint will suspend any failed child endpoint only for 60 seconds after detecting the failure.

Sample 53: Failover sending among 3 endpoints

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main" onError="errorHandler">
        <in>
            <send>
                <endpoint>
                    <failover>
                        <endpoint>
                            <address uri="http://localhost:9001/soap/LBService1">
                                <enableAddressing/>
                                <suspendDurationOnFailure>60</suspendDurationOnFailure>
                            </address>
                        </endpoint>
                        <endpoint>
                            <address uri="http://localhost:9002/soap/LBService1">
                                <enableAddressing/>
                                <suspendDurationOnFailure>60</suspendDurationOnFailure>
                            </address>
                        </endpoint>
                        <endpoint>
                            <address uri="http://localhost:9003/soap/LBService1">
                                <enableAddressing/>
                                <suspendDurationOnFailure>60</suspendDurationOnFailure>
                            </address>
                        </endpoint>
                    </failover>
                </endpoint>
            </send>
<drop/>
        </in>

        <out>
            <!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
            <send/>
        </out>
    </sequence>

    <sequence name="errorHandler">

        <makefault>
            <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
        </makefault>

        <header name="To" action="remove"/>
        <property name="RESPONSE" value="true"/>

        <send/>
    </sequence>

</definitions>

Objective: Demonstrate the failover sending

Prerequisites:

Start Synapse with sample configuration 53 (i.e. synapse -sample 53)

Deploy the LoadbalanceFailoverService and start three instances of sample Axis2 server as mentioned in sample 52.

Above configuration sends messages with the failover behavior. Initially the server at port 9001 is treated as primary and other two are treated as back ups. Messages are always directed only to the primary server. If the primary server has failed, next listed server is selected as the primary. Thus, messages are sent successfully as long as there is at least one active server. To test this, run the loadbalancefailover client to send infinite requests as follows:

ant loadbalancefailover

You can see that all requests are processed by MyServer1. Now shutdown MyServer1 and inspect the console output of the client. You will observe that all subsequent requests are processed by MyServer2.

The console output with MyServer1 shutdown after request 127 is listed below:

...
[java] Request: 125 ==> Response from server: MyServer1
[java] Request: 126 ==> Response from server: MyServer1
[java] Request: 127 ==> Response from server: MyServer1
[java] Request: 128 ==> Response from server: MyServer2
[java] Request: 129 ==> Response from server: MyServer2
[java] Request: 130 ==> Response from server: MyServer2
...

You can keep on shutting down servers like this. Client will get a response till you shutdown all listed servers. Once all servers are shutdown, the error sequence is activated and a fault message is sent to the client as follows.

[java] COULDN'T SEND THE MESSAGE TO THE SERVER.

Once a server is detected as failed, it will be added to the active servers list again after 60 seconds (specified in <suspendDurationOnFailure> in the configuration). Therefore, if you have restarted any of the stopped servers and have shutdown all other servers, messages will be directed to the newly started server.

Sample 54: Session affinity load balancing between 3 endpoints

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main" onError="errorHandler">
        <in>
            <send>
                <endpoint>
                    <!-- specify the session as the simple client session provided by Synapse for
                    testing purpose -->
                    <session type="simpleClientSession"/>

                    <loadbalance>
                        <endpoint>
                            <address uri="http://localhost:9001/soap/LBService1">
                                <enableAddressing/>
                            </address>
                        </endpoint>
                        <endpoint>
                            <address uri="http://localhost:9002/soap/LBService1">
                                <enableAddressing/>
                            </address>
                        </endpoint>
                        <endpoint>
                            <address uri="http://localhost:9003/soap/LBService1">
                                <enableAddressing/>
                            </address>
                        </endpoint>
                    </loadbalance>
                </endpoint>
            </send>
<drop/>
        </in>

        <out>
            <!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
            <send/>
        </out>
    </sequence>

    <sequence name="errorHandler">

        <makefault>
            <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
        </makefault>

        <header name="To" action="remove"/>
        <property name="RESPONSE" value="true"/>

        <send/>
    </sequence>

</definitions>

Objective: Demonstrate the load balancing with session affinity using client initiated sessions

Prerequisites:

Start Synapse with sample configuration 54 (i.e. synapse -sample 54).

Deploy the LoadbalanceFailoverService and start three instances of the sample Axis2 server as in sample 52.

Above configuration is same as the load balancing configuration in sample 52, except that the session type is specified as "simpleClientSession". This is a client initiated session, which means that the client generates the session identifier and send it to with each request. In this sample session type, client adds a SOAP header named ClientID containing the identifier of the client. 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.

ant loadbalancefailover -Dmode=session

In the session mode, client continuesly sends requests with three diferent client (session) IDs. One ID is selected among these three IDs for each request randomly. Then client prints the session ID with the responded server for each request. Client output for the first 10 requests are shown below.

[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
... 

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.

Sample 55: Session affinity load balancing between fail over endpoints

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main" onError="errorHandler">
        <in>
            <send>
                <endpoint>
                    <!-- specify the session as the simple client session provided by Synapse for
                    testing purpose -->
                    <session type="simpleClientSession"/>

                    <loadbalance>
                        <endpoint>
                            <failover>
                                <endpoint>
                                    <address uri="http://localhost:9001/soap/LBService1">
                                        <enableAddressing/>
                                    </address>
                                </endpoint>
                                <endpoint>
                                    <address uri="http://localhost:9002/soap/LBService1">
                                        <enableAddressing/>
                                    </address>
                                </endpoint>
                            </failover>
                        </endpoint>
                        <endpoint>
                            <failover>
                                <endpoint>
                                    <address uri="http://localhost:9003/soap/LBService1">
                                        <enableAddressing/>
                                    </address>
                                </endpoint>
                                <endpoint>
                                    <address uri="http://localhost:9004/soap/LBService1">
                                        <enableAddressing/>
                                    </address>
                                </endpoint>
                            </failover>
                        </endpoint>
                    </loadbalance>
                </endpoint>
            </send>
<drop/>
        </in>

        <out>
            <!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
            <send/>
        </out>
    </sequence>

    <sequence name="errorHandler">

        <makefault>
            <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
            <reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
        </makefault>

        <header name="To" action="remove"/>
        <property name="RESPONSE" value="true"/>

        <send/>
    </sequence>

</definitions>

Objective: Demonstrate the session affinity based load balancing with failover capability

Prerequisites:

Start Synapse with sample configuration 55 (i.e. synapse -sample 55).

Deploy the LoadbalanceFailoverService and start four sample Axis2 servers on http ports 9001, 9002, 9003 and 9004 respectively (make sure to specify unconflicting https ports).

This configuration also uses "simpleClientSession" to bind sessions as in the previous sample. But failover endpoints are specified as the child endpoints of the load balance endpoint. Therefore sessions are bound to the failover endpoints. Session information has to be replicated among the servers listed under each failover endpoint using some clustering mechanism. Therefore, if one endpoint bound to a session failed, successive requets for that session will be directed to the next endpoint in that failover group. Run the client using the following command to observe this behavoir.

ant loadbalancefailover -Dmode=session

You can see a client output as shown below.

...
[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
...

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.

...
[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
...

Sample 56: WSDL endpoint

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="main">
        <in>
            <send>
                <!-- get epr from the given wsdl -->
                <endpoint>
                    <wsdl uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl" service="SimpleStockQuoteService" port="SimpleStockQuoteServiceSOAP11port_http"/>
                </endpoint>
            </send>
        </in>

        <out>
            <send/>
        </out>
    </sequence>

</definitions>

Objective: Demonstrate the use of WSDL endpoints

Prerequisites:

Start the Synapse configuration numbered 56 (i.e. synapse -sample 56).

Deploy the SimpleStockQuoteService and start the sample Axis2 server.

This sample uses a WSDL endpoint inside the send mediator. WSDL endpoints can extract endpoint's address from the given WSDL. As WSDL documents can have many services and many ports inside each service, the service and port of the required endpoint has to be specified. As with address endpoints, QoS parameters for the endpoint can be specified inline in the configuration. An excerpt taken from the sample_proxy_1.wsdl containing the specified service and port is listed below.

<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>

Specified service and port refers to the endpoint address "http://localhost:9000/soap/SimpleStockQuoteService" according to the above WSDL. Now run the client using the following command.

ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080

Client will print the quote price for IBM received from the server running on port 9000. Observe the Axis2 console and the Synapse console to verify this behavior.

Quality of Service addition or deduction samples in message mediation

Sample 100: Using WS-Security for outgoing messages

<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>

Objective: Connecting to endpoints with WS-Security for outgoing messages

Prerequisites:

You may also need to download and install the unlimited strength policy files for your JDK before using Apache Rampart (e.g. see http://java.sun.com/javase/downloads/index_jdk5.jsp)

Start the Synapse configuration numbered 100: i.e. synapse -sample 100
Start the Axis2 server and deploy the SecureStockQuoteService if not already done

Use the stock quote client to send a request without WS-Security. 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:

ant stockquote -Dtrpurl=http://localhost:8080/

The message sent by Synapse to the secure service can be seen as follows, when TCPMon is used.

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

Sample 101: Reliable message exchange between Synapse and the back-end server using WS-ReliableMessaging

<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>
Objective: Demonstrate the message exchange between Synapse and the server using WS-ReliableMessaging (WS-RM)

Prerequisites:

Deploy the ReliableStockQuoteService in the sample Axis2 server by switching to the samples/axis2Server/src/ReliableStockQuoteService directory and running ant.

Start the sample Axis2 server on port 9000.

Start Synapse with the sample configuration 101 (i.e. synapse -sample 101).

In the above configuration, WS-RM is engaged to the endpoint using the <enableRM/> tag. It is possible to engage WS-RM to both Address and WSDL endpoints using this tag. In addition to the RM enabled endpoint, RMSequence mediator is specified before the send mediator. This mediator is used to specify the set of messages to be sent using a single RM sequence. In this sample it is specified as single message per sequence. It also specifies the version of the WS-RM to be used. Refer to the 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.

ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080

You can observer the client output displaying the quote price for IBM as follows:

[java] Standard :: Stock price = $189.2521262517493

There is no difference to be observed between the normal message exchange and WS-RM enabled message exchange as far as client and server outputs are considered. But if you look at the wire level messages, you would observe additional WS-RM messages and WS-RM elements. Synapse, the initiator of the RM sequence, first try to create a sequence by sending a message with CreateSequence element.

...
<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>
...

Sample Axis2 server responds to CreateSequence request with the following message:

...
<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>
...

Once the sequence is established, Synapse sends the request to the server with the pre-negotiated sequence ID.

<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>

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.

<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">
...

Now both Synapse and the server are done with the actual message exchange. Then Synapse sends a request to terminate the sequence as follows:

<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>

Server responds to the sequence termination message, accepting to terminate the sequence as follows.

<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>

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.

Synapse Proxy service samples

Sample 150: Introduction to proxy services

<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>

Objective: Introduction to Synapse proxy services

Prerequisites:
Start the Synapse configuration numbered 150: i.e. synapse -sample 150
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

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.

Execute the stock quote client by requesting for a stock quote on the proxy service as follows:

ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy

An 'inSequence' or 'endpoint' or both of these would decide how the message would be handled after the proxy service receives the message. In the above example, the request received is forwarded to the sample service hosted on Axis2. The 'outSequence' defines how the response is handled before it is sent back to the client. By default, a proxy service is exposed over all transports configured for Synapse, unless these are specifically mentioned through the 'transports' attribute.

Sample 151: Custom sequences and endpoints with proxy services

<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>

Objective: Using custom sequences and endpoints for message mediation with proxy services

Prerequisites:
Start the Synapse configuration numbered 151: i.e. synapse -sample 151
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This configuration creates two proxy services.. The first proxy service 'StockQuoteProxy1' uses the sequence named 'proxy_1' to process incoming messages and the sequence named "out" to process outgoing responses. The second proxy service 'StockQuoteProxy2' is set to directly forward messages that are received to the endpoint named 'proxy_2_endpoint' without any mediation.

You could send a stock quote request to each of these proxy services and receive the reply generated by the actual service hosted on the Axis2 instance.

ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy1
ant stockquote -Daddurl=http://localhost:8080/soap/StockQuoteProxy2

Sample 152: Switching transports and message format from SOAP to REST/POX

<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>

Objective: Switching transports and from SOAP to REST/POX

Prerequisites:
Start the Synapse configuration numbered 152: i.e. synapse -sample 152

Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

This configuration demonstrates how a proxy service could be exposed on a subset of available transports, and how it could switch from one transport to another. This example exposes the created proxy service only on https, and thus if the user tries to access it over http, would result in a fault.

ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy
...
     [java] org.apache.axis2.AxisFault: The service cannot be found for the endpoint reference (EPR) /soap/StockQuoteProxy

Accessing this over https (ant stockquote -Dtrpurl=https://localhost:8443/soap/StockQuoteProxy) causes the proxy service to access the SimpleStockQuoteService on the sample Axis2 server using REST/POX. This could be seen if the message exchange was captured using TCPMon as follows. The REST/POX response is now transformed back into a SOAP message and returned to the client.

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>
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>

Sample 153: Routing the messages arrived to a proxy service without processing the security headers

<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>

Objective: Routing the messages arrived to a proxy service without processing the MustUnderstand headers (Security header)

Prerequisites:
You may also need to download and install the unlimited strength policy files for your JDK before using Apache Rampart (e.g. see http://java.sun.com/javase/downloads/index_jdk5.jsp)

Start the Synapse configuration numbered 153: i.e. synapse -sample 153
Start the Axis2 server and deploy the SecureStockQuoteService if not already done

The proxy service will recieve secure messages with security headers which are MustUnderstand. But hence element 'engageSec' is not present in the proxy configuration 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:

ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy -Dpolicy=./../../repository/conf/sample/resources/policy/client_policy_3.xml

By following through the debug logs or TCPMon output, you could see that the request received by the proxy service was signed and encrypted. Also, looking up the WSDL of the proxy service by requesting the URL http://localhost:8080/soap/StockQuoteProxy?wsdl reveals the security policy attachments are not there and security is not engaged. When sending the message to the backend service, you could verify that the security headers were there as in the original message to 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.

Sample 154: Load Balancing with Proxy Service

   <!-- 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> 

Objective: Load Balancing with Proxy Service

Prerequisites: Sample setup is same as LoadBalance endpoints (#53 to #54).

Start the Synapse configuration numbered 154: i.e. synapse -sample 154
Start the Axis2 server and deploy the SecureStockQuoteService if not already done

Runs the client with

  ant loadbalancefailover -Dmode=session -Dtrpurl=http://localhost:8080/soap/LBProxy 

Functionality is similar to the sample #54.

QoS addition and deduction for service mediation (proxy) samples

Sample 200: Using WS-Security with policy attachments for proxy services

<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>

Objective: Using WS-Security signing and encryption with proxy services through WS-Policy

Prerequisites:
You may also need to download and install the unlimited strength policy files for your JDK before using Apache Rampart (e.g. see http://java.sun.com/javase/downloads/index_jdk5.jsp)

Start the Synapse configuration numbered 200: i.e. synapse -sample 200
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

The proxy service expects to receive a signed and encrypted message as specified by the security policy. Please see Apache Rampart and Axis2 documentation on the format of the policy file. The element 'engageSec' specifies that Apache Rampart should be engaged on this proxy service. Hence if Rampart rejects any request messages that does not conform to the specified policy, those messages will never reach the 'inSequence' to be processed. Since the proxy service is forwarding the received request to the simple stock quote service that does not use WS-Security, we are instructing 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:

ant stockquote -Dtrpurl=http://localhost:8080/soap/StockQuoteProxy -Dpolicy=./../../repository/conf/sample/resources/policy/client_policy_3.xml

By following through the debug logs or TCPMon output, you could see that the request received by the proxy service was signed and encrypted. Also, looking up the WSDL of the proxy service by requesting the URLhttp://localhost:8080/soap/StockQuoteProxy?wsdl reveals the security policy attachment to the supplied base WSDL. When sending the message to the backend service, you could verify that the security headers were removed, and that the response received does not use WS-Security, but that the response being forwarded back to the client is signed and encrypted as expected by the client.

Sample 201: Reliable message exchange between the client and proxy services using WS-ReliableMessaging

<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>
Objective: Demonstrate the reliable message exchange between the client and Synapse using WS-ReliableMessaging (WS-RM)

Prerequisites:

Deploy the SimpleStockQuoteService in the sample Axis2 server and start it on port 9000.

Start Synapse with the sample configuration number 201 (i.e. synapse -sample 201).

In the above configuration, a proxy service is created with WS-RM enabled using the <enableRM/> tag. Therefore, this proxy service is capable of communicating with a WS-RM client. It also removes the WS-RM headers in the In Sequence before the message is sent to the back end server. This is required as the reliable messaging is applicable only between the client and Synapse. Now start the client with WS-RM as follows:

ant stockquote -Dsymbol=IBM -Dmode=quote -Daddurl=http://localhost:8080/soap/StockQuoteProxy -Dwsrm=true

In this case, client sends WS-RM enabled request to 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.

Transport samples and switching transports

Sample 250: Introduction to switching transports - JMS to http/s

<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>

Objective: Introduction to switching transports with proxy services

Prerequisites:
Start the Axis2 server and deploy the SimpleStockQuoteService (Refer steps above)
Download, install and start a JMS server, and configure Synapse to listen on JMS (refer notes below)
Start the Synapse configuration numbered 250: i.e. synapse -sample 250
For this example we would use ActiveMQ as the JMS provider. Once ActiveMQ is installed and started you should get a message as follows:

INFO BrokerService - ActiveMQ JMS Message Broker (localhost) started

You will now need to configure the Axis2 instance used by 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.

For a default ActiveMQ v4.0 installation, you may uncomment the