AMQP Swiftlet
Overview
The AMQP Swiftlet provides AMQP 0.9.1 and 1.0.0 protocol support for SwiftMQ routers, enabling AMQP clients to connect, exchange messages, and interoperate with SwiftMQ queues and topics. It manages AMQP listeners, connections, sessions, message transformation, and protocol-specific features, bridging the AMQP protocol with SwiftMQ's internal messaging model.
Features
AMQP Protocol Support (0.9.1 and 1.0.0)
The Swiftlet implements both AMQP 0.9.1 and AMQP 1.0.0 protocol versions, automatically negotiating the version with connecting clients. Each incoming connection is handled by a versioned connection handler, which selects the appropriate protocol handler (AMQPHandler for 1.0.0, AMQPHandler for 0.9.1) based on the protocol header received. The Swiftlet supports all core AMQP messaging patterns, including queues, topics, and temporary queues, and provides full mapping between AMQP and SwiftMQ's internal destinations.
AMQP Listeners
Listeners define network endpoints (IP address and port) for incoming AMQP connections. Each listener can be configured with SASL authentication, host access restrictions, and a connection template that controls low-level socket and protocol parameters. Listeners are dynamically managed, and changes (add/remove) take effect without restart.
Connection Templates
Connection templates define protocol and socket parameters such as buffer sizes, idle timeouts, maximum frame/message/channel/handle numbers, and link credit. Templates are referenced by listeners and allow fine-tuning of resource usage and protocol behavior for different classes of clients.
SASL Authentication
The Swiftlet supports SASL authentication mechanisms (PLAIN, ANONYMOUS) for AMQP connections. SASL can be enabled or disabled per listener. When enabled, the SASL handshake is performed before protocol negotiation, and user credentials are validated against SwiftMQ's authentication Swiftlet.
Configuration Example:
<swiftlet name="sys$amqp">
<listeners>
<listener name="amqp-listener" port="5672" sasl-enabled="true" connection-template="default"/>
</listeners>
</swiftlet>
Message Transformation and Mapping
The AMQP Swiftlet provides a flexible message transformation framework that maps between AMQP messages and SwiftMQ's JMS message model. This is achieved through configurable inbound and outbound transformers, which can be set globally or per destination. The default transformers (JMSMappingInboundTransformer and JMSMappingOutboundTransformer) handle the conversion of AMQP message properties, headers, annotations, and body types to and from JMS message types (Text, Bytes, Map, Stream, Object).
Custom Transformers
Users can implement custom message transformers by extending the abstract classes InboundTransformer or OutboundTransformer (in com.swiftmq.impl.amqp.amqp.v01_00_00.transformer). InboundTransformer defines the method transform(TransferFrame frame, DestinationFactory destinationFactory) for converting AMQP frames to JMS messages, and setConfiguration(Map config) for transformer-specific configuration. OutboundTransformer defines transform(Delivery delivery) for converting JMS messages to AMQP deliveries, and setConfiguration(Map config) for configuration. Custom transformers can be registered globally or per destination via the router configuration.
Destination-based Transformation
Transformers can be configured on a per-queue or per-topic basis, allowing different mapping strategies for different destinations. This is useful for interoperability scenarios where certain queues require special property mapping, body handling, or annotation processing.
Configuration Example:
<swiftlet name="sys$amqp">
<declarations>
<transformer>
<destination-transformers>
<destination-transformer name="orders">
<inbound-transformers>
<inbound-transformer name="0" class-name="com.example.CustomInboundTransformer"/>
</inbound-transformers>
<outbound-transformers>
<outbound-transformer name="0" class-name="com.example.CustomOutboundTransformer"/>
</outbound-transformers>
</destination-transformer>
</destination-transformers>
</transformer>
</declarations>
</swiftlet>
AMQP Session, Link, and Flow Control Management
Each AMQP connection can create multiple sessions, and each session can create multiple links (senders and receivers). The Swiftlet manages the mapping of AMQP sessions to SwiftMQ resources, including dynamic and durable subscriptions, temporary queues, and flow control. Link credit and window sizes are enforced according to the connection template. The Swiftlet supports AMQP selectors (JMS selectors via Apache Qpid conventions) and the no-local filter for message consumption.
Session and Link Usage Monitoring
The Swiftlet tracks active connections, sessions, and links, exposing usage statistics such as message rates, total messages, link credit, unsettled transfers, and selectors. This information is available via the management interface for monitoring and troubleshooting.
Temporary Queues and Dynamic Addresses
AMQP dynamic addresses are mapped to SwiftMQ temporary queues, which are automatically created and deleted as links are established and closed. The naming convention for temporary queues is tmp$
Connection and Resource Management
The Swiftlet enforces resource limits and manages connection lifecycle, including maximum connections per listener, idle timeouts, and clean shutdown. Connections are tracked in the usage list, and administrative actions (such as disconnect) are available via management tools. The Swiftlet can optionally enforce unique container IDs per connection, similar to JMS client ID semantics.
Host Access Control
Each listener can be configured with a host access list, restricting inbound connections to specific IP addresses or patterns. The access list is dynamically managed and enforced at connection establishment.
Idle Timeout and Heartbeat
Idle timeout is enforced per connection, and AMQP heartbeats are used to detect and close stale connections. Heartbeat intervals are negotiated with the client according to the connection template and protocol version.
Configuration Example:
<swiftlet name="sys$amqp">
<listeners>
<listener name="restricted-listener" port="5672">
<host-access-list>
<host-access-entry name="192.168.1.%"/>
</host-access-list>
</listener>
</listeners>
</swiftlet>
Internal Queue Naming
tmp$<sequence>-<startuptime>— Temporary queue for dynamic AMQP addresses and temporary destinations
Configuration Guide
Custom Message Transformer for a Specific Queue
Use this scenario when you need to apply a custom message mapping for a particular queue, for example to handle special property translation or body formats for interoperability.
- Implement a custom InboundTransformer and/or OutboundTransformer class.
- Deploy the transformer class to the SwiftMQ router.
- Configure the transformer for the target queue in routerconfig.xml under the
section.
<swiftlet name="sys$amqp">
<declarations>
<transformer>
<destination-transformers>
<destination-transformer name="myqueue">
<inbound-transformers>
<inbound-transformer name="0" class-name="com.example.MyInboundTransformer"/>
</inbound-transformers>
<outbound-transformers>
<outbound-transformer name="0" class-name="com.example.MyOutboundTransformer"/>
</outbound-transformers>
</destination-transformer>
</destination-transformers>
</transformer>
</declarations>
</swiftlet>
Restricting AMQP Connections to Specific Hosts
Use this scenario to allow only clients from specific IP address ranges to connect to an AMQP listener.
- Define a listener in the configuration.
- Add host access entries with allowed IP patterns under the listener's host-access-list.
<swiftlet name="sys$amqp">
<listeners>
<listener name="secure-listener" port="5672">
<host-access-list>
<host-access-entry name="10.0.0.%"/>
<host-access-entry name="192.168.100.5"/>
</host-access-list>
</listener>
</listeners>
</swiftlet>
Disabling Duplicate Container IDs
Use this scenario to enforce unique AMQP container IDs per connection, similar to JMS client ID enforcement.
- Set the allow-same-containerid attribute to false on the sys$amqp swiftlet.
<swiftlet name="sys$amqp" allow-same-containerid="false"/>
Custom Message Transformer API
Custom AMQP message transformers allow you to control how AMQP messages are converted to/from JMS messages. Implement a custom transformer by extending one of the abstract base classes below.
InboundTransformer
Package: com.swiftmq.impl.amqp.amqp.v01_00_00.transformer
Converts an incoming AMQP 1.0 TransferFrame into a JMS MessageImpl.
public abstract class InboundTransformer {
/**
* Called once after instantiation with the configuration properties
* defined in routerconfig.xml for this transformer.
*
* Supported configuration properties:
* - name-translator: class name of a NameTranslator (default: InvalidToUnderscoreNameTranslator)
* - prefix-vendor: vendor prefix for AMQP properties (default: "JMS_AMQP_")
* - default-delivery-mode: "PERSISTENT" or "NON_PERSISTENT" (default: "PERSISTENT")
* - default-priority: default JMS priority (default: 4)
* - default-ttl: default time-to-live in ms (default: 0)
*/
public void setConfiguration(Map config) throws Exception;
/**
* Transform an AMQP TransferFrame into a JMS MessageImpl.
* Implement this method in your custom transformer.
*
* @param frame the incoming AMQP transfer frame
* @param destinationFactory factory to resolve destination names
* @return the transformed JMS message
*/
public abstract MessageImpl transform(TransferFrame frame,
DestinationFactory destinationFactory)
throws AMQPException, JMSException;
}
OutboundTransformer
Package: com.swiftmq.impl.amqp.amqp.v01_00_00.transformer
Converts an outgoing JMS MessageImpl into an AMQP 1.0 message for delivery.
public abstract class OutboundTransformer {
/**
* Called once after instantiation with the configuration properties
* defined in routerconfig.xml for this transformer.
*
* Supported configuration properties:
* - name-translator: class name of a NameTranslator (default: NullNameTranslator)
* - prefix-vendor: vendor prefix for AMQP properties (default: "JMS_AMQP_")
*/
public void setConfiguration(Map config) throws Exception;
/**
* Transform a JMS message into an AMQP delivery.
* The Delivery object contains the JMS MessageImpl (delivery.getMessage()).
* Set the AMQP message on the delivery (delivery.setAmqpMessage(...)).
*
* @param delivery the delivery containing the JMS message to transform
*/
public abstract void transform(Delivery delivery)
throws AMQPException, JMSException;
}
Built-in Transformers
| Transformer | Direction | Description |
|---|---|---|
JMSMappingInboundTransformer |
Inbound | Standard AMQP-to-JMS mapping per AMQP/JMS spec |
JMSMappingOutboundTransformer |
Outbound | Standard JMS-to-AMQP mapping per AMQP/JMS spec |
AMQPNativeInboundTransformer |
Inbound | Preserves AMQP native message structure |
AMQPNativeOutboundTransformer |
Outbound | Preserves AMQP native message structure |
BasicInboundTransformer |
Inbound | Minimal transformation |
BasicOutboundTransformer |
Outbound | Minimal transformation |
Registering a Custom Transformer
<swiftlet name="sys$amqp">
<declarations>
<transformer>
<default-inbound-transformers>
<default-inbound-transformer name="0"
class-name="com.example.MyInboundTransformer"/>
</default-inbound-transformers>
<default-outbound-transformers>
<default-outbound-transformer name="0"
class-name="com.example.MyOutboundTransformer"/>
</default-outbound-transformers>
</transformer>
</declarations>
</swiftlet>
Per-destination transformers override the defaults for a specific queue or topic:
<swiftlet name="sys$amqp">
<declarations>
<transformer>
<destination-transformers>
<destination-transformer name="orders">
<inbound-transformers>
<inbound-transformer name="0"
class-name="com.example.OrdersInboundTransformer"/>
</inbound-transformers>
</destination-transformer>
</destination-transformers>
</transformer>
</declarations>
</swiftlet>
Configuration Reference
The top-level entity in routerconfig.xml is <swiftlet name="sys$amqp">.
<swiftlet name="sys$amqp"> Properties
These properties are attributes of the <swiftlet name="sys$amqp"> entity.
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
allow-same-containerid |
Boolean | true |
No | No | If set to false, it is handled like a JMS Client Id |
collect-interval |
Long | 1000 |
No | No | Collect Interval Messages/Sec |
<swiftlet name="sys$amqp" allow-same-containerid="true" collect-interval="1000"/>
<declarations> Entity
Declarations Section
This is a fixed child entity of <swiftlet name="sys$amqp">.
<swiftlet name="sys$amqp">
<declarations/>
</swiftlet>
<connection-templates> in <declarations>
Templates for Connections
Each <connection-template> entry is identified by its name attribute (the Connection Template).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
socketfactory-class |
String | com.swiftmq.net.PlainSocketFactory |
No | No | Socketfactory Class |
use-tcp-no-delay |
Boolean | true |
No | No | Use Tcp No Delay |
idle-timeout |
Long | 90000 |
No | No | Inactivity timeout (ms) after which a Connection is disconnected |
max-frame-size |
Long | 2147483647 |
No | No | Maximum Frame Size (range: 0–2147483647) |
max-message-size |
Long | 10485760 |
No | No | Maximum Message Size (range: 0–2147483647) |
max-channel-number |
Integer | 65535 |
No | No | Maximum Channel Number (range: 0–65535) |
target-link-credit |
Long | 20 |
No | No | Link Credit for Targets (range: 1–2147483647) |
max-handle-number |
Long | 2147483647 |
No | No | Maximum Handle Number (range: 0–2147483647) |
incoming-window-size |
Integer | 100 |
No | No | Maximum Number of incoming unsettled Transfer Frames (range: 1–2147483647) |
outgoing-window-size |
Integer | 100 |
No | No | Maximum Number of outgoing unsettled Transfer Frames (range: 1–2147483647) |
reject-disconnect-delay |
Long | 5000 |
No | No | Time (ms) after which a rejected Connection is closed (min: 1000) |
router-input-buffer-size |
Integer | 131072 |
No | No | Router Network Input Buffer Size (min: 1024) |
router-input-extend-size |
Integer | 65536 |
No | No | Router Network Input Extend Size (min: 1024) |
router-output-buffer-size |
Integer | 131072 |
No | No | Router Network Output Buffer Size (min: 1024) |
router-output-extend-size |
Integer | 65536 |
No | No | Router Network Output Extend Size (min: 1024) |
<swiftlet name="sys$amqp">
<declarations>
<connection-templates>
<connection-template name="..."/>
</connection-templates>
</declarations>
</swiftlet>
<listeners> in <swiftlet name="sys$amqp">
Listener Definitions
Each <listener> entry is identified by its name attribute (the Listener).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
bindaddress |
String | — | No | No | Listener Bind IP Address |
port |
Integer | 5672 |
Yes | No | Listener Port |
max-connections |
Integer | -1 |
Yes | No | Maximum Connections for Listener |
sasl-enabled |
Boolean | true |
No | No | Enabled/Disabled SASL Authentication |
connection-template |
String | default |
Yes | No | Connection Template to use |
<swiftlet name="sys$amqp">
<listeners>
<listener name="..." port="..." max-connections="..." connection-template="..."/>
</listeners>
</swiftlet>
<host-access-list> in <listeners>
Host Access List
Each <host-access-entry> entry is identified by its name attribute (the Host Access Entry).
<swiftlet name="sys$amqp">
<listeners>
<listener name="...">
<host-access-list>
<host-access-entry name="..."/>
</host-access-list>
</listener>
</listeners>
</swiftlet>