User login

Stepping into Apache Synapse - PART II (Proxy Services)

Story :

Level : Realm : Project :

This article by Ruwan Linton is the second of a series of articles on Apache Synapse. In this series, you will learn what Synapse is, how it works, and how you can use it to solve common enterprise problems. You will understand some of the advanced features of Synapse, how you can extend it, and also some of its limitations.

 

Introduction

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.

Applies To

Apache Synapse Version 1.1.1

 

Table of Contents

  1. Proxy Service
  2. Model of a Synapse Proxy Service
  3. Proxy Service Configuration
  4. Composite Services using Proxy Services
  5. Conclusion
  6. References/Resources

 

Proxy Service

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

Proxy Service model

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:

  • Transport Switching - Exposing a service on a different transport than the ones on which it is currently deployed
  • Protocol Switching - Exposing a service on a different protocol than the ones on which the service is currently exposed
  • QoS Addition or Reduction - Exposing a running service with quality of service (QoS), by adding security and reliability to the proxy service
  • Location Transparency - Changing the actual service implementation and the location without changing the interface
  • Message Transformation - Exposing a service with a different schema
  • Composite Services - Exposing a service as a composite service of two or more services
  • Aggregated Services - Exposing a set of services as a single service providing all the operations
  • EJB Services - Exposing an EJB as a Web service

 

Model of a Synapse Proxy Service

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.

Synapse proxy servicve architectural overview

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

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.

  • The name attribute value of the proxy element represents the name of the proxy service to be deployed. It has to be a string without special characters.
  • The transports attribute value of the proxy element represents the set of transports on which this particular service is deployed. It can be any combination of the existing transports including http, https, jms, mail, vfs or the keyword all. If the attribute is not specified, it represents that this proxy service is deployed on all the existing transports.
  • The attributes trace and statistics represent the tracing state and the statistics reporting state respectively. The attribute value can be either enable or disable.
  • The description element specifies a description of the proxy, which has no impact over the functionality of the proxy service. This is an optional element.
  • Each proxy must contain only one target element that describes the target information of the proxy service.
    • The sequence of mediation for the incoming messages can be defined two ways. It can either be a reference using the inSequence attribute of the target element or defined inline enclosed with the inSequence element
    • In the same manner, the sequence for the outgoing message mediation can also be defined two ways, either as a referencec using the outSequence attribute of the target element or defined inline enclosed with the outSequence element.
    • The same holds true for the fault message processing sequence with the attribute and tag names as faultSequence
    • endpoint as an attribute or element inside the  target element represents the message delivery endpoint after the mediation. This is optional. However, when it is present in the target, the inSequence becomes optional, allowing the messages to be directly forwarded to the specified endpoint without any mediation.
  • If a particular service has to represent a WSDL, then that can be specified by using the publishWSDL element as an external URL. This can be done by using the uri attribute, as an registry entry using the key attribute, or it can be specified inline. This particular WSDL can be a WSDL11 document or a WSDL20 document.
  • Further, if there are any resources like XSD files refered to in the WSDL, those resources can be specified with the location and the key attributes of the resource element within the publishWSDL element
  • enableSec and the enableRM elements represent whether this service has to be secured and made reliable respectively, if present.
  • policy elements can be used to specify any service level policies with the key attribute to configure the above specified QoS features on a per service basis. If the type of the policy is specified, then the policy will only be effective for the specified type which can be either in or out. Also, it is possible to configure the operation level policies by providing the operationName and the operationNamespace attributes of the policy, which is only effective if there is a WSDL specified.
  • Some of the transports will require service parameters to be present for them to configure their behavior. For example, vfs transport requires a file location to be listened, a mail transport requires an email address to be listened, and so on. These parameters can be specified in the configuration using the parameter element with a name and a value inside the parameter

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;

 

Composite Services using Proxy Services

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 Service

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.

Proxy Service solution

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.

Sequence proxy_in_seq

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

Clone Mediator action

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.

Sequence proxy_out_seq

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.

Aggragte Mediator action

Composite Service in Action

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.

Setting up the server side

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.

  • Go to the SYNAPSE_HOME folder (where you have extracted the Synapse distribution) using a console in Unix or using the command prompt on MS Windows
  • Go to the samples/axis2Server/src/SimpleStockQuoteService folder and type the command ant
  • Go back to the axis2Server folder and start the axis2 server using the relevant command for the operating system (For Unix: axis2server.sh and for MS Windows: axis2server.bat)
 cd $SYNAPSE_HOME
 cd samples/axis2Server/src/SimpleStockQuoteService
 ant
 cd ../..
 sh axis2server.sh

Setting up Synapse

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

Executing the client and observing it

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>
 

 

Conclusion

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.

 

References/Resources

  1. Synapse Home Page
  2. Synapse Samples Guide
  3. Synapse Configuration Language
  4. Stepping into Apache Synapse - PART I

 

Author

Ruwan Linton - Software Engineer - WSO2 Inc. (ruwan AT wso2 DOT com)

0
No votes yet
Tags :