Upgrading to the Latest Version

If you are using an older version of Synapse (1.x/2.x) and now looking to migrate to the latest versions (3.x) this document would be a good starting point. This article provides information on steps that need to be carried out to smoothly migrate from an older release of Synapse to the latest version. If you are migrating from 1.x version to 3.x we recommend you follow the 1.x -> 2.x migration followed by the 2.x -> 3.x.

General comments

If you are using custom extensions (mediators, startups, etc.) implemented in Java and depending on Synapse APIs, you should go through the following process before upgrading to a new release:

  1. Compile the extension with the libraries from the Synapse release you are currently using and check for any deprecation warnings. You should change your code to eliminate all those warnings. In general the Javadoc of the deprecated class or method gives you a hint on how to change your code. Test all your changes with your current Synapse release.
  2. Recompile and test the extension with the libraries from the new Synapse release. We try to avoid introducing incompatible changes to Synapse's core APIs between releases (except if the related classes or methods were deprecated in the previous release). However, it is not always possible to maintain compatibility. In addition your code might depend on features that are not part of the core API. Therefore, even if you don't use deprecated methods and classes, there is no guarantee that your code will not break when upgrading to a new release and you always need to recompile and test them before deploying to the new release.
  3. Upgrade your Synapse installation and deploy the new version of your extensions.

If you are skipping releases when upgrading your installation, you might nevertheless want to go through the first step for all the intermediate releases. This will make the migration easier.

Upgrading from 2.1 to 3.0

Custom Extensions

Synapse 3.0 introduces the PassThrough HTTP Transport which improves HTTP transport performance by removing intermediary buffer use when there is no requirement to read an HTTP payload (i.e. message is merely passed through). If you have custom extensions that depend on accessing or reading buffers directly, you may require to change your code to trigger the PassThrough transport to build the payload. This can be done using the RelayUtils#buildMessage() static methods.

Respond and Loopback Mediators

Respond and Loopback are new mediators introduced in Apache Synapse 3.0. Respond provides a mechanism to send a message back to the client as a response. In older versions of Apache Synapse we would use the Send mediator to respond back to a client either after a message is received from a backend in an out sequence or force a response back to the client using a series of mediators as follows:

<header name="To" action="remove"/> <property name="RESPONSE" value="true" scope="default" type="STRING"/> <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/> <send/>

We can replace above methods with the Respond mediator anywhere in the mediation flow to respond back to the client with the current message. Any mediators residing after the Respond mediator will be ignored.

Similarly the Loopback mediator is used to jump the flow from an in sequence to the out sequence ignoring any mediators residing after the Loopback mediator. Loopback mediator has no effect from inside an out sequence.

Upgrading from 1.2 to 2.1

Configuration file vs multi XML configuration

In 1.2 you have been using a single synapse.xml file which resides on the repository/conf directory of the distribution, where as on 2.1 we have structured this into a configuration repository with multiple directories to have different artifact types and each and every artifact configuration to reside on a different files inside the desired repository directory. This repository directory on the 2.1 release resides in the repository/conf directory too, and named as synapse-config. The repository directory structure inside the synapse-config directory looks like follows;

synapse-config /api /endpoints /event-sources /local-entries /priority-executors /proxy-services /sequences main.xml fault.xml /tasks /templates registry.xml synapse.xml

As you can see in the above sketch of the repository though it is a repository based configuration, it also supports the old style single flat synapse.xml file in which case it has to reside inside the root of the repository.

So the easiest way to migrate the configuration is to move your already existing synapse.xml file in repository/conf directory in 1.2 version into the repository/conf/synapse-config directory of the 2.x version. Note: When doing this migration you should also delete the main.xml and fault.xml files which are there on the sequences directory of the repository, otherwise there will be 2 main and fault sequences one coming from the sequences directory and the other coming from your just copied synapse.xml file.

Endpoint URLs for proxy services

In release 2.1 the endpoint URLs for proxy services have changed from /soap to /services. E.g. http://localhost:8280/services/StockQuote should be used instead of http://localhost:8280/soap/StockQuote.

MediatorDeployer

Release 1.3 has enhanced capabilities for extension deployment. While in 1.2 extension deployment was limited to mediators bundled as simple JAR files, 1.3 extended this support to tasks and defined a new archive format (XAR) that allows to bundle these extensions together with their dependency JARs (see SYNAPSE-377 for more details). Enabling these features requires changes to the axis2.xml configuration file. In 1.2 the deployer was configured as follows:

<deployer extension="jar" directory="mediators" class="org.apache.synapse.core.axis2.MediatorDeployer"/>

In 2.1 the suggested configuration is:

<deployer extension="xar" directory="extensions" class="org.apache.synapse.deployers.ExtensionDeployer"/>

It is possible to have multiple configuration entries for the extension deployer with different settings. For example, if you used the deployer in 1.2 you might want to have the following configuration:

<deployer extension="jar" directory="mediators" class="org.apache.synapse.deployers.ExtensionDeployer"/> <deployer extension="xar" directory="extensions" class="org.apache.synapse.deployers.ExtensionDeployer"/>

JMS transport

The way the JMS transport determines the content type of incoming messages has slightly changed between Synapse 1.2 and 2.x. The mechanism is also more flexible. See SYNAPSE-304 and SYNAPSE-424 for the reasons of this change and refer to the WS-Commons Transport project for documentation.

Main Sequence

On Synapse 1.2 you could have mediator configuration on the top level definitions tag and they were treated as the main sequence if there is no main sequence defined in the configuration. How ever removing the conflict of having top level mediators and a main sequence leading the synapse to fail to start on 2.x Synapse configuration builder simply ignores the top level mediators. So you need to wrap the top level mediators, if there are any, with the sequence named main on the new 2.1 version.

To further explain this lets have a look at the following valid configuration bit (this is the sample 0 configuration) on the 1.2;

<definitions xmlns="http://ws.apache.org/ns/synapse"> <!-- log all attributes of messages passing through --> <log level="full"/> <!-- Send the message to implicit destination --> <send/> </definitions>
which needs to be changed to the following configuration on 2.1
<definitions xmlns="http://ws.apache.org/ns/synapse"> <sequence name="main"> <!-- log all attributes of messages passing through --> <log level="full"/> <!-- Send the message to implicit destination --> <send/> <sequence/> </definitions>

Filter Mediator

From 2.1 onwards Synapse filter mediator supports the else close as well, and hence the filter matching set of mediators has to be enclosed within a <then> element.

If we consider the following sample from the 1.2 version of synapse;

<filter source="get-property('To')" regex=".*/StockQuote.*"> <send> <endpoint> <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> </endpoint> </send> <drop/> </filter>
the equivalent configuration for the 2.1 release is going to be;
<filter source="get-property('To')" regex=".*/StockQuote.*"> <then> <send> <endpoint> <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> </endpoint> </send> <drop/> <then/> </filter>
You could also add an else close to this conditional statement as follows on 2.x which is not possible on 1.2
<filter source="get-property('To')" regex=".*/StockQuote.*"> <then> <send> <endpoint> <address uri="http://localhost:9000/soap/SimpleStockQuoteService"/> </endpoint> </send> <drop/> <then/> <else/> <log/> <else/> </filter>

Migration Tool

In general it is recommended to run the configuration through the migration tool provided with the Synapse 2.x release, on your synapse 1.2 configuration before using it with the 2.1.

To run the migration tool execute the synapse-config-migrator.sh by passing the synapse.xml file location of the 1.2 configuration. Which will create the 2.1 compatible configuration with the .new suffix. For example;

sh bin/synapse-config-migrator.sh synapse-i1.2/repository/conf/synapse.xml

Custom Extensions and API changes

Even though there is a migration tool it just takes care of your configuration and not custom extensions that you have done for example like CustomMediators or Tasks and so forth. There are some API changes that affect your custom extensions unfortunately. This section tries to list all the public API changes which affects the backward compatibility of the custom extensions that you have been running with the 1.2 version of Synapse.

Class Method Change Description
AbstractMediatorFactory createMediator(OMElement) This was the method that you have been overwriting on the 1.2 version to implement a new custom mediator factory to build the mediator by looking at the XML configuration. On the 2.1 version you should be extending the createSpecificMediator(OMElement, Properties) . Note that in the process of changing the method to be extended, the method createMediator method has been changed to be final. From a users point of view of this interface he/she should be using the createMediator method which is what Synapse does.
AbstractMediatorSerializer serializeMediator(Mediator) This was the method that you have been overwriting on the 1.2 version to implement a new custom mediator serializer to serialize to the XML Configuration by walking through the mediator properties. On the 2.1 version you should be extending the serializeSpecificMediator(Mediator) . Note that in the process of changing the method to be extended, the method serializeMediator method has been changed to be final. From a users point of view of this interface he/she should be using the serializeMediator method which is what Synapse does.

Further to that if you have been using ServerManager class you may have noticed that the class is no more a singleton and doesn't have the static getInstance method. Also note that the common utilities like data sources JMX and RMI registration stuff have been moved to a new module with org.apache.synapse.commons package name.

On the configuration building front all entities are given a properties map to construct its instance and that has been used to pass in any additional information required like RESOLVE_ROOT, or SYNAPSE_HOME startup parameters. For example if you look at the MediatorFactoryFinder class the getMediator method is expecting a properties map apart from the OMElement argument. It is safe to pass in a empty properties map if you are using these methods for any testing purposes or even in cases where you do not resolve dependencies.