2007/08/13
13 Aug, 2007

Stepping into Apache Synapse – Part I

  • Ruwan Linton
  • Director, Delivery - WSO2

IntroductionSynapse

Apache Synapse is a mediation framework for Web services,
based on the Apache Axis2 project, a set of XML, security, and Web services related projects and standards. Synapse provides a lightweight service bus and the basic infrastructure for the implementation of a Service Oriented Architecture (commonly known as SOA). In this article, you will learn the basic architecture of Synapse and how to configure it. In later parts you will be able to see some sample configurations with real world scenarios.

Applies To

Apache Synapse Version 1.0

 

Service Bus and Mediation

Let us first focus on the meaning of the terms 'Service Bus' and
'Mediation' in the context of messaging, before we dive-in deeper into Synapse. When it comes to enterprise application communication, Service Bus is the common communication channel that is used by all the parties in messaging. Mediation is the process of facilitated communication between parties by providing intermediary conflict resolutions.

Service Bus

Synapse supports most of the tasks of a service bus in a service oriented
infrastructure. Synapse is inherently extensible even though it is designed
to support a large set of useful functions out-of-the-box. The main functions
of Synapse can be divided into three major areas:

  • Connect - Connecting systems
  • Manage - Managing interactions
  • Transform - Transforming messages

Connect

Synapse is designed to support connecting systems with different
transports with different protocols and Quality of Service (QoS). The protocols/transports that Synapse currently supports include SOAP/HTTP,SOAP/HTTPS, SOAP/JMS, SOAP/SMTP, XML/HTTP, XML/JMS and many more. Synapse offers termination and initiation of QoS tasks like Reliable Messaging and WS Security. Synapse can route messages based on XPath expressions or Regular expressions applied over the message header or content to an endpoint reference. Virtualization is achieved by routing the messages from virtual/logical URIs to real EPRs.

Manage

Synapse supports Failover and Load-balancing to multiple endpoints. In the failover case, there are several sets of endpoints grouped as a failover group. When a particular endpoint fails to deliver the message, Synapse will try to deliver the message to other endpoints in the group. During load-balancing, Synapse will balance the load among the load-balancing endpoint group depending on the algorithm provided for load-balancing.

Synapse also lets you trace the messages flowing in the enterprise by enabling tracing in the mediation. Authorization and authentication tasks for an organization can be delegated to Synapse through mediation, by using WS Security. Synapse lets you collect and monitor the statistics for components such as proxy services in Synapse. The validation of messages using schemas is also very simple with Synapse.

Transform

Synapse can be used for message transformations through mediation with various languages, including most of the scripting languages, with the Bean Scripting Framework (BSF) and most importantly with XSLT. Apart from that, Synapse offers protocol switching, example - SOAP to JMS or XML/HTTP to SOAP.

Mediation inside Synapse is designed with care, and there are two possible types of mediations that can happen inside Synapse. They are:

  • Message Mediation - Managing and transforming the
    messages flowing between the client and a service in an enterprise.
  • Service Mediation - Mediating messages coming into a specific service by specifying the target URI as a Synapse mediation service.

In message mediation, the client does not know about the mediation of the message in the middle of transmission. When it comes to service mediation, the client directly speaks to Synapse and specifies the address of the service to which the message should go for mediation. Inside these services, it is not required to check the transport headers and take the routing
decision because the messages are already filtered. Whereas in message
mediation, most of the time Synapse will have to check the transport headers
to take the routing decision. These services are called Proxy
Services
in Synapse.

All these features make Synapse an attractive open source mediation
framework for you to try under Apache Software License version 2.0.

 

Architecture of Synapse

The high level architecture of Synapse is fairly simple. The Synapse
engine applies the rules specified to it through the Synapse configuration
language on the messages it receives via configured transports. The following
diagram depicts an abstract view of Synapse.

 

Synapse architectural overview

 

There are three message receivers (MRs) in Synapse,

  • Synapse Message Receiver - Receives messages from the
    underlying Axis2 transports for message mediation.
  • Proxy Service Message Receiver- Receives messages for
    service mediation.
  • Synapse Callback Receiver - Receives responses for
    outgoing messages through Synapse.

The Callback Receiver ties the responses with the requests made so that
the out flow mediation can execute within the proper context. Proxy services will be introduced in the next
section of this article.

When a message is received by the message receivers, Synapse will inject
these messages into the Synapse environment. The mediation takes place here
through a Synapse Message Context (SMC) created for each
message through a set of mediators. This context holds the message, message
context properties, and parameters for the environment. Similar to Axis2,
Synapse is also stateless, and if the mediators want to
share any data between them, they will have to use the Synapse Message
Context properties.

While in the process of mediation, if a message should be sent to a
particular endpoint, then the Send mediator sets the relevant properties on
the SMC and delegates the sending of the message to an Endpoint. This is a
logical representation of an actual endpoint, or else a collection of
endpoints wrapped within some logic. (For example, Load Balanced endpoints)
The endpoint will then apply additional modifications to the SMC and then
hand over the SMC to the Sender (which is an Axis2Sender) for sending the
message.

If this message is not a response, the Axis2Sender will send the message
to the specified endpoint given by the endpoint, or if not provided, to the
endpoint resolved from the implicit parameters in the MC. If it is a
response, the Axis2Sender will use the implicit parameters to send the
message back, by looking at its message properties that were set when the
message was received. (A detailed architectural view of Synapse will be
presented in a subsequent article.)

Before we dig into the command/control language of Synapse, that is the
Synapse Configuration Language, Let's look at a usage sample
for the better understanding of Synapse.

 

Getting Your Hands Dirty with Synapse

This section describes how you can get Synapse and run it. First, download
the latest release of Synapse from its official web site which is http://ws.apache.org/synapse and uncompress the
distribution. You will be able to see the following structure in the
extracted folder;

Extratcted folder structure

The bin directory in the uncompressed root folder contains the synapse.sh
and synapse.bat scripts which are used to start Synapse in the Unix and
Windows based environments respectively. Synapse has a set of samples that
consists of a built-in Axis2 Server and a set of Axis2 clients and
corresponding services, bundled with a set of Synapse configurations that
lets you try different features of Synapse out of the box.

Extract the binary distribution archive. In the
samples/axis2server/src/SimpleStockQuoteService directory, run 'ant' in a
console (you need Apache Ant to accomplish this task) which will build and
deploy the axis2 service archive for you to test a trivial example of
Synapse.
Now from the axis2Server folder, run the axis2Server.sh or axis2Server.bat
script. After that, start Synapse with the first sample configuration using
the synapse.sh or synapse.bat with the arguments “-sample 0”. The
complete command to be executed is as follows.

[SYNAPSE]/bin$ ./synapse.sh -sample 0
[SYNAPSE]\bin> synapse.bat -sample 0

The following log depicts the console output after synapse is started
successfully.

Starting Synapse/Java ...
Using SYNAPSE_HOME: /home/ruwan/dev/syn/trunk/java/synapse-1.0-RC1-SNAPSHOT
Using JAVA_HOME: /opt/software/java/jdk1.5_06
Using SYNAPSE_XML: -Dsynapse.xml=/home/ruwan/dev/syn/trunk/java/synapse-1.0-RC1-SNAPSHOT/repository/conf/sample/synapse_sample_0.xml
[SynapseServer] Using the Axis2 Repository /home/ruwan/dev/syn/trunk/java/synapse-1.0-RC1-SNAPSHOT/repository
[main] INFO SynapseModule - Initializing the Synapse configuration ...
[main] INFO SynapseModule - System property 'synapse.xml' specifies synapse configuration as /home/ruwan/dev/syn/trunk/java/synapse-1.0-RC1-SNAPSHOT/repository/conf/sample/synapse_sample_0.xml
[main] INFO XMLConfigurationBuilder - Generating the Synapse configuration model by parsing the XML configuration
[main] DEBUG MediatorFactoryFinder - Added MediatorFactory class org.apache.synapse.mediators.spring.SpringMediatorFactory to handle {http://ws.apache.org/ns/synapse/spring}spring
[main] DEBUG MediatorFactoryFinder - Added MediatorFactory class org.apache.synapse.mediators.bsf.ScriptMediatorFactory to handle {http://ws.apache.org/ns/synapse}script
[main] DEBUG MediatorFactoryFinder - Added MediatorFactory class org.apache.synapse.mediators.attachment.AttachmentMediatorFactory to handle {http://ws.apache.org/ns/synapse}attachments
[main] DEBUG MediatorFactoryFinder - Added MediatorFactory class org.apache.synapse.mediators.throttle.ThrottleMediatorFactory to handle {http://ws.apache.org/ns/synapse/throttle}throttle
[main] DEBUG MediatorFactoryFinder - getMediator({http://ws.apache.org/ns/synapse}log)
[main] DEBUG MediatorFactoryFinder - getMediator({http://ws.apache.org/ns/synapse}send)
[main] DEBUG MediatorFactoryFinder - getMediator({http://ws.apache.org/ns/synapse}log)
[main] INFO SynapseConfigurationBuilder - Loaded Synapse configuration from : /home/ruwan/dev/syn/trunk/java/synapse-1.0-RC1-SNAPSHOT/repository/conf/sample/synapse_sample_0.xml
[main] INFO SynapseModule - Deploying the Synapse service..
[main] INFO SynapseModule - Deploying Proxy services...
[main] INFO SynapseModule - Synapse initialized successfully...!
[main] INFO HttpCoreNIOSender - HTTPS Sender starting
[main] INFO HttpCoreNIOSender - HTTP Sender starting
[main] INFO HttpCoreNIOListener - HTTPS Listener starting on port : 8443
[SynapseServer] Starting transport https on port 8443
[main] INFO HttpCoreNIOListener - HTTP Listener starting on port : 8080
[SynapseServer] Starting transport http on port 8080
[SynapseServer] Ready

 

The configuration of Synapse which is used to start Synapse is as follows.
This will be explained later in the Synapse Configuration Language
section;

Sample Configuration

You can try out Synapse by using the sample clients available in the
axis2Client folder as follows. You can execute the stockquote client that
will send a message through Synapse to the Axis2 service deployed on the
sample server.

$ ant stockquote

This will compile the StockQuoteClient in the src/samples/userguide folder
and run it to invoke the service. This client will send a message specifying
the WSA-To address as SimpleStockQuoteService deployed on the axis2 server
running on port 9000, and specify the transport URL as Synapse running on
port 8080. Thus the message reaches Synapse through the transport and allows
Synapse to mediate the message flow.

 

[I/O reactor worker thread 5] INFO PipeImpl - Using native OS Pipes for event-driven to stream IO bridging
[HttpServerWorker-1] DEBUG SynapseMessageReceiver - Synapse received a new message for message mediation...
[HttpServerWorker-1] DEBUG SynapseMessageReceiver - Received To: https://localhost:9000/axis2/services/SimpleStockQuoteService
[HttpServerWorker-1] DEBUG SynapseMessageReceiver - SOAPAction: urn:getQuote
[HttpServerWorker-1] DEBUG SynapseMessageReceiver - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:wsa="https://www.w3.org/2005/08/addressing" xmlns:soapenv="https://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header> <wsa:To>https://localhost:9000/axis2/services/SimpleStockQuoteService</wsa:To> <wsa:MessageID>urn:uuid:D57514D7EA959684321175764218397</wsa:MessageID><wsa:Action>urn:getQuote</wsa:Action> </soapenv:Header><soapenv:Body><m0:getQuote xmlns:m0="https://services.samples/xsd"><m0:request><m0:symbol>IBM</m0:symbol></m0... </m0:getQuote></soapenv:Body></soapenv:Envelope>
[HttpServerWorker-1] DEBUG SequenceMediator - Sequence mediator <main> :: mediate()
[HttpServerWorker-1] DEBUG AbstractListMediator - Implicit Sequence <SequenceMediator> :: mediate()
[HttpServerWorker-1] DEBUG LogMediator - Log mediator :: mediate()
[HttpServerWorker-1] INFO LogMediator - To : https://localhost:9000/axis2/services/SimpleStockQuoteService, MessageID : urn:uuid:D57514D7EA959684321175764218397, Action : urn:getQuote, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:wsa="https://www.w3.org/2005/08/addressing" xmlns:soapenv="https://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header> <wsa:To>https://localhost:9000/axis2/services/SimpleStockQuoteService</wsa:To> <wsa:MessageID>urn:uuid:D57514D7EA959684321175764218397</wsa:MessageID><wsa:Action>urn:getQuote</wsa:Action> </soapenv:Header><soapenv:Body><m0:getQuote xmlns:m0="https://services.samples/xsd"><m0:request><m0:symbol>IBM</m0:symbol></m0... </m0:getQuote></soapenv:Body></soapenv:Envelope>
[HttpServerWorker-1] DEBUG SendMediator - Send mediator :: mediate()
[HttpServerWorker-1] DEBUG SendMediator - Sending message using implicit message properties..
[HttpServerWorker-1] DEBUG SendMediator - Sending To: https://localhost:9000/axis2/services/SimpleStockQuoteService
[HttpServerWorker-1] DEBUG SendMediator - SOAPAction: urn:getQuote
[HttpServerWorker-1] DEBUG SendMediator - Body :
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:wsa="https://www.w3.org/2005/08/addressing" xmlns:soapenv="https://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><wsa:To> https://localhost:9000/axis2/services/SimpleStockQuoteService</wsa:To><w... urn:uuid:D57514D7EA959684321175764218397</wsa:MessageID><wsa:Action>urn:getQuote</wsa:Action></soapenv:Header> <soapenv:Body><m0:getQuote xmlns:m0="https://services.samples/xsd"><m0:request><m0:symbol>IBM</m0:symbol></m0... </m0:getQuote></soapenv:Body></soapenv:Envelope>

 

In this case, a send mediator followed by the log
mediator. Executing these two mediators, first it logs the full message
because the configuration says the log level is full and then sends the
message onwards to the actual service running on port 9000 using the implicit
To header in the message. The response from the server comes to Synapse and
it will decide the response message's destination from its implicit
parameters. It then sends the response to the client after logging the
message by executing the main rule again. For help on running samples in
Synapse please refer to the Synapse Samples Guide .

Now we will look into the configuration language, from which you can
control synapse.

 

Synapse Configuration Language

Synapse at runtime is configured via an XML configuration file. It is
written using the Synapse configuration language which is defined in the Synapse
Configuration Language
. Let us examine the sample configuration we used
above to gain a better understanding of the syntax.

Synapse configuration sample 0

This is a basic configuration of Synapse. If we take the elements in this
configuration one by one, first the root element named definitions holds all the sub definitions of
Synapse. All the configuration elements belong to the Synapse namespace
"http://ws.apache.org/ns/synapse". However all the attributes remain
un-qualified by default.

Within these definitions, we can have several declarations in the
following categories;

  • Sequence declarations
  • Endpoint declarations
  • Local Registry Entry declarations
  • The Registry declaration
  • Proxy Service declarations

Sequences

Sequence declarations can contain any number of sequences with a name.
There are two mandatory sequences that should be present for Synapse to start
properly. They are: main and fault. The
Main sequence is the sequence where the mediation starts in Synapse when a
message has arrived, where as the Fault sequence will be executed if there is
an internal error in Synapse while doing the mediation.

Even though these two sequences are mandatory, Synapse does not rely on
the administrator to provide them in the configuration, instead it creates
two default sequences in the absence of one of these sequences. The default
sequence for main will be a Send mediator, where as the default sequence for
fault will be a Log mediator. In the above sample configuration, even though
there was no fault sequence, Synapse will create its own default fault
sequence with the Log mediator.

This is another sample sequence named "sample_sequence";

Sample sequence declaration

If you have specified a set of mediators inside a definitions tag, then
Synapse will consider that collection of mediators in the order of the
declaration as the main mediator. It is obvious that you cannot have the
sequence and a set of mediators with the name “main” in the root level,
which will be an erroneous configuration. Unlike presenting a main sequence,
in this case Synapse will not start and will throw a Runtime Exception.

Endpoints

An endpoint requires a name to be present when declaring at the
definitions level. It can be one of the following four categories:

  • Address Endpoint
  • WSDL Endpoint
  • Load-balancing Endpoint
  • Failover Endpoint

Address endpoint is the one defined with the address binding of the actual
endpoint, where as WSDL endpoint will be defined by giving the WSDL of the
actual endpoint, so that Synapse is able to extract the relevant information
from the WSDL. For example,

Address and WSDL endpoints

The remaining two endpoints do not represent actual endpoints, but they
are a representation of a particular logic like load balancing or failover as
shown below;

Sample Load balancing and Failover endpoints

Local Entries

If you have a resource that will be used several times (for example an
XSLT), you can define an entry for that resource and reuse the defined entry
rather than stating the resource itself each time. In entry declaration as
well, it is required to provide a name, so that when it is needed you can
just refer to the defined resource by referring to that name.

Sample entry declaration

Registry

Currently Synapse only supports a single registry per configuration, and
it should be declared inside the definitions tag. If you have declared a
registry, then you have access to the resources that are available in the
registry by referring to the registry key of a particular resource.

The main advantage of using a registry is that, these registry entries can
be used to change the behaviour of Synapse at runtime. For example, if you
have placed your main sequence in a registry and just refer to that registry
entry in the configuration giving the key, then you can change that registry
entry and expect Synapse to change its behaviour accordingly.

Sample Registry definition

Proxy Services

Proxy service definitions can contain any number of proxy services with a
name. There are some more parameters that you can provide when defining a
proxy service which includes the following;

  • Transports on which the service is exposed
  • WSDL under which the proxy is exposed
  • Incoming mediation sequence, out going mediation sequence and fault
    sequence
  • Target endpoint
  • Policy elements for QoS
  • Service parameters

Sample proxy service definition

You may have noticed that except for proxy services, it is possible to use
all the other declarations inline whenever needed, without a name.

Conclusion

Apache Synapse is a lightweight mediation framework which is very useful
in providing the infrastructure for SOA. Synapse is inherently architected in
a way to provide most of the functionalities of an ESB, and can be easily
configurable through the Synapse Configuration Language. In the next article,
you will learn how to carry out basic mediation with Synapse, an introduction
to Synapse proxy services, advanced mediation tasks of Synapse and extending
Synapse.

References/Resources

1. Synapse Home Page
2. Synapse
Samples Guide

3. Synapse
Configuration Language

 

Author

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

 

About Author

  • Ruwan Linton
  • Director, Delivery
  • WSO2 Inc