High Quality and Affordable JMS Messaging.

Versioning

SwiftMQ is a distributed system. Like all distributed systems, administrative problems occur when upgrading from one version to another. Say, there are 100 JMS clients connected to a single SwiftMQ router. Both, the JMS clients and the router, are using the same swiftmq.jar. What if the new swiftmq.jar is incompatible with the old one? Yes, one has to stop the whole distributed system (all clients and the router), upgrade all clients with the new swiftmq.jar, upgrade the router, and then restart the whole system. A nightmare for administrators.

However, this is only a local distributed system. Say, there are 100 worldwide subsidiaries of a company, each running a single router with each 100 JMS clients. Each router is connected to a main router at the company's headquarter which is connected to several other routers within departments, running several JMS clients. That's not only a nightmare, it becomes impossible to upgrade to a newer version at all!

Implementation

In SwiftMQ releases prior to 4.0.0, we have strived to ensure a compatibility between minor and patch releases. Major releases were mostly incompatible because of the lot of enhancements and changes in behavior or router/client interaction, respectively.

Starting with SwiftMQ 4.0.0, we introduce versioning to ensure a compatibility not only between major releases but back to any prior release we like, starting with 4.0.0.

Versioning takes place within the following areas:

SMQP Protocol

SMQP is the abbreviation of "SwiftMQ Protocol" and is used as the underlying protocol between JMS clients and a SwiftMQ router. The complete SMQP protocol stack is versioned. That means, there is a complete 4.0.0 stack and it will be a complete 4.1.0 protocol stack in case there is a protocol change. So far, it is possible to remove complete stacks out of swiftmq.jar once it expires in future. There is one non-versioned SMQP request to select the protocol stack which is used from JMS clients as the first request to negotiate the protocol version. Thereafter, a complete versioned protocol stack is used.

SMQPR Protocol

SMQPR is the abbreviation of "SwiftMQ Protocol for Routing" and is used as the underlying protocol between SwiftMQ routers to exchange messages over routing connections. It uses also versioned protocol stacks and a non-versioned SMQPR request to negotiate the protocol version.

SMQPHA Protocol

SMQPHA is the abbreviation of "SwiftMQ Protocol for High Availability" and is used as the underlying protocol between ACTIVE and STANDBY HA instances of a SwiftMQ HA Router. It uses also versioned protocol stacks and a non-versioned SMQPHA request to negotiate the protocol version.

HA Replication Tunnel Protocol

HA replication tunnel protocol is used on top of a SMQPHA replication tunnel. The versioning takes place per tunnel. So it's possible to have different protocol versions per replication tunnel.

JMS

JMS clients and a SwiftMQ router are using SMQP to interact. All JMS client classes as well as all corresponding classes at the JMS Swiftlet of the router are versioned. The JMS Swiftlet provides multiple versions, where each version is completely separated from each other version. A JMS connection is created via a connection factory which is either obtained from JNDI or created the proprietary way. Both ways result in a versioned connection factory which launches a versioned connection object on the JMS client. The JMS client uses versioned SMQP to connect to a router, negotiate the version with the router which then launches a versioned connection by itself. Therefore, it is possible to connect a 4.0.0 and a 5.0.0 JMS client to the same 5.0.0 router, using different versioned connection classes on the router side.

JNDI

JNDI is realized on top of a JMS connection. Before the JNDI request is sent to the router, a versioned JMS connection will be established. Thereafter, JNDI requests are sent to the topic "swiftmq.jndi". These JNDI requests are versioned as well. The JNDI Swiftlet provides sets of versioned request handlers, where each set is completely separated from each other.

The JMS Swiftlet registers connection factories within JNDI. It does this by registering a container under the given name, e.g. "QueueConnectionFactory". The container has a dedicated entry with a connection factory for every version the JMS Swiftlet provides. Each entry contains a factory name to create the connection factory. For example, if a JMS Swiftlet provides versions 4.0.0, 4.1.0 and 5.0.0, then the container has 3 entries. When a JMS client performs a JNDI lookup, the container is returned, the appropriate version entry is selected (e.g. if the client has 4.0.0 then the 4.0.0 entry is selected out of 4.0.0, 4.1.0, 5.0.0), and the connection factory is created from the factory with the name, specified in the entry. Thereafter, the connection factory is returned from the JNDI lookup.

Routing Connections

SwiftMQ Routers are using SMQPR to interact. All connection classes are versioned and completely separated. During the connect, the appropriate version is negotiated and versioned routing connections are launched on each side. New releases will contain multiple versions and can therefore interact with older releases.

Route Exchange

After a versioned routing connection has been established, routes are exchanged between the corresponding routers. Routes are versioned and being converted to the version the corresponding router accepts.

Pub/Sub Subscription Exchange

Those notifications are exchanged between Topic Manager Swiftlets to ensure that pub/sub messages are sent to remote routers if they have at least one subscription for a particular topic. Notification exchange starts first after a route is known and continues on each appropriate event. The notifications are versioned and being converted to the version the corresponding Topic Manager Swiftlets accepts.

Management via SwiftMQ Explorer, CLI, CLI Admin API

A SwiftMQ administration tool and the corresponding Management Swiftlet of the particular router negotiate a protocol version during the connect. If the Management Swiftlet supports the requested protocol version, it loads the protocol stack and uses it for any further communication with that tool. Therefore, an administration tool is able to manage a router network containing routers with different protocol versions simultaneously.