AMQP 0.9.1 Support (since 9.1.0)

Overview

To enable users to use existing client libraries for AMQP 0.9.1, SwiftMQ supports this AMQP protocol version starting with release 9.1.0. Both protocol versions, 0.9.1 and 1.0, are supported on the same AMQP ports (default 5672 or 5671 for SSL).

Keep in mind, even if there are many client libraries out there, AMQP 0.9.1 is outdated. The official AMQP specification starts with AMQP 1.0. This is the only version to which backward compatibility from later versions is guaranteed.

Implemented Functionality of AMQP 0.9.1

  • SASL integrated with the Authentication Swiftlet.
  • Exchange type "direct" (named exchanges and the default empty name exchange).
  • Connection, Channel, Exchange, Queue, Basic classes.
  • Prefetch, Flow, large messages.

Unimplemented Functionality of AMQP 0.9.1

  • Exchange types "topic", "fanout", "header".
  • Prefetch global.
  • Transaction class.

Channel Class

A Channel.Flow to deactivate flow is sent to a producer if a flowcontrol delay of a queue is greater 100 milliseconds and another Channel.Flow to activate flow is sent when the flowcontrol delay time is over. To disable this, the flowcontrol start queue size of the queue resp. the queue controller (temp queues) needs to be set to -1.

Exchange Class

The only supported exchange type is "direct". Exchanges can be named or the default empty name exchange can be used. All exchanges map directly to SwiftMQ's Queue Manager Swiftlet, no matter what the queue binding is.

Queue Class

Queues marked as durable must be preconfigured as a regular queue via SwiftMQ's admin tool resp. the routerconfig.xml. It is not possible to create a durable queue via a Queue.Declare operation. Attempts will throw an error.

Preconfigured regular queues cannot be deleted via Queue.Delete. This operation does not throw an error but is ignored. Instead Queue.Purge should be used.

Nondurable queues can be created via Queue.Declare and deleted via Queue.Delete. The queue can be accessed through the name given in Queue.Declare but is internally mapped to a temporary queue which name starts with "tmp$". The lifetime of a nondurable queue is until Queue.Delete or until the connection which has created the queue is closed.

The routing key for Queue.Bind must be the queue name.

Basic Class

The routing key for Basic.Publish must be the queue name.

Message Transformation

SwiftMQ is a JMS messaging system so all messages from/to AMQP 0.9.1 clients are transformed to/from JMS messages on the fly by internal transformer classes.

Inbound Transformation (AMQP 0.9.1 to JMS Message)

Before transformation takes place, multiple body frames are concatenated to a single byte array.

If the content-type property of the AMQP header starts with "text/" (like "text/plain"), the resulting JMS message will be a JMS TextMessage where the message body is an UTF-8 decoded String from the AMQP bytes message body. Otherwise the resulting JMS message will be a JMS BytesMessage with the body set from the AMQP bytes message body.

The JMS message is flagged as a AMQP 0.9.1 message with a message property of type "Long" with name "JMS_AMQP_MESSAGE_FORMAT" and value 91.

Header translation takes place according to the following table:

AMQP header JMS message header/property
ContentType String: JMS_AMQP_ContentType
ContentEncoding String: JMS_AMQP_ContentEncoding
DeliveryMode JMSDeliveryMode (or default PERSISTENT)
Priority JMSPriority (or default priority)
CorrelationId JMSCorrelationID
ReplyTo JMSReplyTo
Expiration JMSExpiration (current time millis are added)
MessageId JMSMessageID (or default autogenerated)
Timestamp JMSTimestamp
Type String: JMS_AMQP_Type
UserId String: JMS_AMQP_UserId
AppId String: JMS_AMQP_AppId
ClusterId String: JMS_AMQP_ClusterId

The "Headers" map of the AMQP content header is transformed into JMS message properties. The name of the header is translated into a valid JMS message property name where all invalid characters are replaced with underscores '_'. The resulting type and value of the JMS message property is determined from the field type of the AMQP header value according to following conversion table. All other field types are ignored.

AMQP Field Type JMS Message Property Type
t Boolean
b, B, U, u, I Int
i, L Long
f, d Float
s Short
S String
T Long

Outbound Transformation (JMS to AMQP 0.9.1 Message)

Only JMS messages of type TextMessage or BytesMessage can be transformed to a AMQP 0.9.1 message. The body of a JMS TextMessage is converted to a byte array containing the UTF-8 encoded TextMessage body. The body of a BytesMessage is directly set as the body of the AMQP 0.9.1 message.

Header translation takes place according to the following table:

JMS message header/property AMQP header
JMS_AMQP_ContentType ContentType
JMS_AMQP_ContentEncoding ContentEncoding
JMSDeliveryMode DeliveryMode
JMSPriority Priority
JMSCorrelationID CorrelationId
JMSReplyTo ReplyTo
JMSExpiration Expiration
JMSMessageID MessageId
JMSTimestamp Timestamp
JMS_AMQP_Type Type
JMS_AMQP_UserId UserId
JMS_AMQP_AppId AppId
JMS_AMQP_ClusterId ClusterId

All other JMS message properties are converted into the "Headers" map of the content header of the AMQP 0.9.1 message. The header name is translated where each underscore '_' is changed to a dash '-' and the property value is converted to an AMQP 0.9.1 field type according to this conversion table:

JMS Message Property Type AMQP Field Type
String S
Long T
Integer I
Short s
Float f
Boolean t
null V