Skip to content

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>

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.

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.

  1. Implement a custom InboundTransformer and/or OutboundTransformer class.
  2. Deploy the transformer class to the SwiftMQ router.
  3. 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.

  1. Define a listener in the configuration.
  2. 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.

  1. 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>