Submitted on March 27, 2008 - 20:58.
In Part-I of this series, you learned the basics of Apache Synapse. In this article, you will learn in detail about one basic operation model of Synapse named Proxy Services. At the end of this article, a real life integration scenario will be explained with a sample using the Proxy Services operation model. At the same time, this article will walk you through the pros and cons of the proxy services inside Synapse.
| Apache Synapse | Version 1.1.1 |
Let us first focus on the meaning of the term Proxy Service in the context of messaging, before we dive in deeper into Synapse Proxy Services. In general, the term proxy has an implied meaning of packet (or message) filtering and redirecting with or without content inspection. These packets can be HTTP requests, and they will be redirected to different servers depending on the content, or redirected blindly to a particular server. Proxy Services, or in other words Service Mediation, give you the same functionality over Service Oriented Architecture (SOA). This behavior of generic proxy servers is depicted in the following diagram

Apart from the proxy behavior specified above, synapse allows you to mediate the messages within the proxy services model. The common functions and use cases of proxy services can be divided into the following areas and more:
The high level architecture and the model of a Synapse proxy service is fairly simple. The Synapse engine receives all the messages and dispatches them to the specified proxy service depending on the service URL. Then the message will be injected to the proxy service, and the rules specified through the Synapse configuration language will be applied. The following diagram depicts an abstract view of a proxy service.

In part I of this article, the concept of three message receivers was introduced. Here we use the Proxy Service Message Receiver to receive messages to the proxy services.
Inside the proxy service, there are two major flows called the In message flow and the Out message flow. The messages incoming to the proxy service are treated by mediating the message using the in-sequence, and the outgoing messages will be treated by mediating the message with the out-sequence. Further, there is an option to specify the endpoint in the case of blind redirection (i.e., there is no routing logic). Therefore, every message that comes into the proxy service will be forwarded to the specified endpoint soon after the mediation of the in-sequence.
Apart from these major flows of the mediation, there is a special flow for the faults that come into the proxy service. For example, if the actual service, which is represented by a particular proxy service, sends a SOAPFault to the proxy in order to forward to the client, you might need to do a set of different actions than the normal out flow. These actions can be specified inside the fault sequence.
The responses from the actual services to the Synapse proxy service will also be received via the same SynapseCallbackReceiver, which receives the responses for normal mediation. Here, the message will be inspected to see whether it is a response message for a particular proxy service by comparing the properties of the relevant incoming message stored within the CallbackStore
Before we dig into some usage scenarios of the proxy services, let's have a look at the proxy service configuration under the feather of the Synapse Configuration Language.
Proxy Services are also configurable using the Synapse Configuration Language, and can be described using the BNF (Backus-Naur Form) of the language as follows;
<proxy name="string" [transports="(http | https | jms | mail | vfs )+ | all"] [trace="(enable | disable)"]
[statistics="(enable | disable)"]>
<description>..</description>?
<target [inSequence="name"] [outSequence="name"] [faultSequence="name"] [endpoint="name"]>
<endpoint>...</endpoint>
<inSequence>...</inSequence>
<outSequence>...</outSequence>
<faultSequence>...</faultSequence>
</target>
<publishWSDL uri=".." key="string">
<wsdl:definitions>...</wsdl:definitions>?
<wsdl20:description>...</wsdl20:description>?
<resource location="..." key="..."/>*
</publishWSDL>?
<enableSec/>?
<enableRM/>?
<policy key="string" [type="(in | out)"] [operationName="string"] [operationNamespace="string"]/>*
<parameter name="string">
text | xml
</parameter>*
</proxy>
The following section describes the above configuration, and the possible values for each element and attribute.
With this information on the proxy services configuration, we will be moving into a real life usage of the proxy services. If you have not already had a look at the samples on proxy services, which are shipped with Synapse distribution, it is recommended to have a look at a set of samples namely;
In order to present this real life usage scenario using the proxy service, we need to have an understanding about composite services. First we will be looking into the requirement of this scenario
Composite Services is a Web service that collects a set of existing services with or without new logic, and forms a new service as a mashed up service of the existing services. For our scenario, we will be looking at how we can get the proxy service to compose 3 quote services which provide the stock quote information of IBM, Microsoft and SUN, to form a new service that will give the highest quote among these three companies.
Note: Please note that these values are randomly generated and the names of the companies have no impact over the generated quotes
The following diagram shows the high level message flow of the proxy.

This section will explain how we can use the proxy services inside Synapse to achieve this service composition. In-order to understand the behavior, we will first have a look at the configuration (which has been shortened for presentation, by removing the XSLT declarations) of the proxy service that has been used to achieve this composition.
<?xml version="1.0" encoding="UTF-8"?>
<syn:definitions xmlns:syn="http://ws.apache.org/ns/synapse">
<syn:proxy name="HighestQuoteService" startOnLoad="true">
<syn:target inSequence="proxy_in_seq" outSequence="proxy_out_seq" faultSequence="fault"/>
</syn:proxy>
<syn:localEntry key="ibm_xslt">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
....
</xsl:stylesheet>
</syn:localEntry>
<syn:localEntry key="msft_xslt">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
....
</xsl:stylesheet>
</syn:localEntry>
<syn:localEntry key="sun_xslt">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
....
</xsl:stylesheet>
</syn:localEntry>
<syn:localEntry key="out_transform">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
....
</xsl:stylesheet>
</syn:localEntry>
<syn:endpoint name="target_ep">
<syn:address uri="http://localhost:9000/soap/SimpleStockQuoteService"/>
</syn:endpoint>
<syn:sequence name="ibm_quote">
<syn:xslt key="ibm_xslt"/>
<syn:send>
<syn:endpoint key="target_ep"/>
</syn:send>
</syn:sequence>
<syn:sequence name="sun_quote">
<syn:xslt key="sun_xslt"/>
<syn:send>
<syn:endpoint key="target_ep"/>
</syn:send>
</syn:sequence>
<syn:sequence name="msft_quote">
<syn:xslt key="msft_xslt"/>
<syn:send>
<syn:endpoint key="target_ep"/>
</syn:send>
</syn:sequence>
<syn:sequence name="proxy_in_seq">
<syn:clone>
<syn:target sequence="ibm_quote"/>
<syn:target sequence="msft_quote"/>
<syn:target sequence="sun_quote"/>
</syn:clone>
</syn:sequence>
<syn:sequence name="proxy_out_seq">
<syn:aggregate>
<syn:completeCondition timeout="30">
<syn:messageCount min="-1" max="-1"/>
</syn:completeCondition>
<syn:onComplete xmlns:m0="http://services.samples/xsd" expression="//m0:getQuoteResponse/m0:return">
<syn:log level="full" separator=","/>
<syn:xslt key="out_transform"/>
<syn:log level="full" separator=","/>
<syn:send/>
</syn:onComplete>
</syn:aggregate>
</syn:sequence>
<syn:sequence name="main">
<syn:log separator=","/>
</syn:sequence>
<syn:sequence name="fault">
<syn:log/>
</syn:sequence>
</syn:definitions>
In this configuration, a proxy service is defined with the name, HighestQuoteService, and is going to be the composite service in this particular case. Then if we look at the proxy target, the inSequence and the outSequence are specified as referred sequences with the names, proxy_in_seq and proxy_out_seq respectively. This implies that the incoming messages will be mediated through the proxy_in_seq and the outgoing messages will be mediated through the proxy_out_seq. So the action of the proxy configuration drills down to these two sequences.
If we look at the proxy_in_seq, there is a clone mediator and three targets for the clone mediator specified as sequence references. The clone mediator just clones the messages into an identical copy and mediates it with the specified target (in this case a set of referred sequences). So in effect the incoming message to the proxy will be cloned into three messages, and they will be parallely injected to the sequences named ibm_quote, msft_quote and sun_quote. Each of these sequences will take care of the message injected and these messages are transformed to fit the service schema of the three actual quote services. (This simulation uses three operations of one service. To change this to three separate services, you just have to change the endpoint addresses of the three endpoints representing the three services).

The final outcome of this sequence is going to be three requests to the three quote services, to get the three stock quotes of these companies. At the same time, you should note that there are three responses from these services.
This sequence accepts the responses for the proxy service and mediates them. In this particular case, for one actual request we receive three responses. So there has to be some party which aggregates these three responses into one. The Aggregate mediator plays this role and aggregates the three responses into one by the specified configuration. Then the aggregated message is forwarded to the sequence defined in the onComplete element. After the aggregation, the three response payloads are aggregated as a single message and that will be mediated through the XSLT transformation specified in the onComplete sequence. In this transformation, the message will be filtered and the response with the highest quote will be taken as the response payload and sent back to the client.

To test this, you will need to set up the server, Synapse and the client. Then invoke the client to send a request to Synapse to see this in action.
To test this composite service, you need synapse and need to deploy the SimpleStockQuoteService shipped with the Synapse samples in the Synapse distribution. You will need to have apache-ant-1.7 or above and Java installed. Follow the steps described below to set it up.
cd $SYNAPSE_HOME cd samples/axis2Server/src/SimpleStockQuoteService ant cd ../.. sh axis2server.sh
Go to the SYNAPSE_HOME and replace the synapse.xml file found at repository/conf/synapse.xml, with the configuration file downloaded from here. Then use the synapse.sh or synapse.bat file found in the bin folder to start the Syanspe server. (Note: You will need to download a patch to the 1.1.1 release aggregate mediator for this to work properly from here and put it in to the $SYNAPSE_HOME/lib/patches folder before starting synapse)
cd $SYNAPSE_HOME cp $DOWNLOADED_FILE repository/conf/synapse.xml sh bin/synapse.sh
Now we are ready to try this composite service and use the following command to send a stockquote request to the composite service.
cd $SYNAPSE_HOME cd samples/axis2Client ant stockquote -Dsymbol=HIGHEST -Dtrpurl=http://localhost:8080/soap/HighestQuoteService
On receiving the request from the client, Synapse will invoke the SimpleStockQuoteService. You can have a look at the service console to see the three requests with the different symbols, which are served from the Axis2 server. If we look at the message flows (you can do so by monitoring the messages through a tcpmon) these messages will look something like the following.
Request message from client to synapse
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Body>
<m0:getQuote xmlns:m0="http://services.samples/xsd">
<m0:request>
<m0:symbol>HIGHEST</m0:symbol>
</m0:request>
</m0:getQuote>
</soapenv:Body>
</soapenv:Envelope>
Request from Syanpse to three services
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<m0:getQuote xmlns:m0="http://services.samples/xsd" xmlns:ns="http://services.samples/xsd">
<m0:request>
<m0:symbol>MSFT</m0:symbol>
</m0:request>
</m0:getQuote>
</soapenv:Body>
</soapenv:Envelope>
Response from three services to Synapse
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getQuoteResponse xmlns:ns="http://services.samples/xsd">
<ns:return type="samples.services.GetQuoteResponse">
<ns:change>-2.757242439429394</ns:change>
<ns:earnings>13.926070553389701</ns:earnings>
<ns:high>-79.99660594704424</ns:high>
<ns:last>81.90254083344033</ns:last>
<ns:lastTradeTimestamp>Thu Mar 27 14:36:49 LKT 2008</ns:lastTradeTimestamp>
<ns:low>-80.02562455961932</ns:low>
<ns:marketCap>309592.02627594396</ns:marketCap>
<ns:name>MSFT Company</ns:name>
<ns:open>85.83639924522409</ns:open>
<ns:peRatio>23.24419444176838</ns:peRatio>
<ns:percentageChange>-3.09564134617401</ns:percentageChange>
<ns:prevClose>89.06853640642665</ns:prevClose>
<ns:symbol>MSFT</ns:symbol>
<ns:volume>5238</ns:volume>
</ns:return>
</ns:getQuoteResponse>
</soapenv:Body>
</soapenv:Envelope>
Aggregated response message
This message cannot be seen out of the synapse, and it represents the message inside synapse just after aggregation whihc will be transformed to remove two response segments and only one (highest quote) can be seen in the response whihc goes out from synapse. You may put a log mediator just after the aggregation and before the transformation to observe this message within the synapse console or change the log level of synapse to DEBUG to observe the traces of the message.
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getQuoteResponse xmlns:ns="http://services.samples/xsd">
<ns:return type="samples.services.GetQuoteResponse">
<ns:change>4.462968020386499</ns:change>
<ns:earnings>13.471360130234485</ns:earnings>
<ns:high>-154.61523860622725</ns:high>
<ns:last>154.8932926618978</ns:last>
<ns:lastTradeTimestamp>Thu Mar 27 14:36:49 LKT 2008</ns:lastTradeTimestamp>
<ns:low>160.49531857882639</ns:low>
<ns:marketCap>-4772597.076954884</ns:marketCap>
<ns:name>IBM Company</ns:name>
<ns:open>-154.5429010268229</ns:open>
<ns:peRatio>24.43118178596917</ns:peRatio>
<ns:percentageChange>2.513772963420755</ns:percentageChange>
<ns:prevClose>177.54061664794378</ns:prevClose>
<ns:symbol>IBM</ns:symbol>
<ns:volume>9913</ns:volume>
</ns:return>
<ns:return type="samples.services.GetQuoteResponse">
<ns:change>-2.9921002202631746</ns:change>
<ns:earnings>12.152974355548952</ns:earnings>
<ns:high>96.57893911367476</ns:high>
<ns:last>94.02448935872526</ns:last>
<ns:lastTradeTimestamp>Thu Mar 27 14:36:49 LKT 2008</ns:lastTradeTimestamp>
<ns:low>98.65295506037018</ns:low>
<ns:marketCap>-1466954.6426709667</ns:marketCap>
<ns:name>SUN Company</ns:name>
<ns:open>-92.16779342982966</ns:open>
<ns:peRatio>25.29595199699729</ns:peRatio>
<ns:percentageChange>3.233176500747909</ns:percentageChange>
<ns:prevClose>-92.54367089365618</ns:prevClose>
<ns:symbol>SUN</ns:symbol>
<ns:volume>15470</ns:volume>
</ns:return>
<ns:return type="samples.services.GetQuoteResponse">
<ns:change>-2.757242439429394</ns:change>
<ns:earnings>13.926070553389701</ns:earnings>
<ns:high>-79.99660594704424</ns:high>
<ns:last>81.90254083344033</ns:last>
<ns:lastTradeTimestamp>Thu Mar 27 14:36:49 LKT 2008</ns:lastTradeTimestamp>
<ns:low>-80.02562455961932</ns:low>
<ns:marketCap>309592.02627594396</ns:marketCap>
<ns:name>MSFT Company</ns:name>
<ns:open>85.83639924522409</ns:open>
<ns:peRatio>23.24419444176838</ns:peRatio>
<ns:percentageChange>-3.09564134617401</ns:percentageChange>
<ns:prevClose>89.06853640642665</ns:prevClose>
<ns:symbol>MSFT</ns:symbol>
<ns:volume>5238</ns:volume>
</ns:return>
</ns:getQuoteResponse>
</soapenv:Body>
</soapenv:Envelope>
Transformed highest quote response to the client
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getQuoteResponse xmlns:ns="http://services.samples/xsd" xmlns:m0="http://services.samples/xsd">
<ns:return>
<ns:change>4.462968020386499</ns:change>
<ns:earnings>13.471360130234485</ns:earnings>
<ns:high>-154.61523860622725</ns:high>
<ns:last>154.8932926618978</ns:last>
<ns:lastTradeTimestamp>Thu Mar 27 14:36:49 LKT 2008</ns:lastTradeTimestamp>
<ns:low>160.49531857882639</ns:low>
<ns:marketCap>-4772597.076954884</ns:marketCap>
<ns:name>IBM Company</ns:name>
<ns:open>-154.5429010268229</ns:open>
<ns:peRatio>24.43118178596917</ns:peRatio>
<ns:percentageChange>2.513772963420755</ns:percentageChange>
<ns:prevClose>177.54061664794378</ns:prevClose>
<ns:symbol>IBM</ns:symbol>
<ns:volume>9913</ns:volume>
</ns:return>
</ns:getQuoteResponse>
</soapenv:Body>
</soapenv:Envelope>
Apache Synapse is a lightweight mediation framework, and it provides the ability to proxy the Web services by creating the proxy services inside Synapse. These proxy services can be used to add or deduct the quality of service and expose the services with different protocols, transports, and schemas. Also, it is very important in service aggregation and service composition. Proxy services can be used to achieve the location transparency of the actual service implementation.
Ruwan Linton - Software Engineer - WSO2 Inc. (ruwan AT wso2 DOT com)