Skip to content

AMQP Swiftlet

Overview

The AMQP Swiftlet enables SwiftMQ routers to accept and process AMQP 0.9.1 and 1.0.0 protocol connections, providing full AMQP broker functionality. It manages AMQP listeners, authentication (SASL), connection/session/link lifecycle, and message transformation between AMQP and JMS formats. The Swiftlet supports advanced features such as message selectors, durable subscriptions, and per-destination message transformation.

Features

AMQP Protocol Support (0.9.1 and 1.0.0)

The AMQP Swiftlet implements both AMQP 0.9.1 and AMQP 1.0.0 protocols, allowing clients using either version to connect and interact with queues and topics on the SwiftMQ router. Protocol negotiation is handled automatically upon connection establishment, and each protocol version is managed by its own handler class (AMQPHandler for 1.0.0, AMQPHandler for 0.9.1). The Swiftlet manages the full lifecycle of AMQP connections, sessions, channels, and links, including flow control, heartbeats, and idle timeouts. AMQP 1.0.0 features such as selectors, no-local, and dynamic addresses are supported, as well as the mapping of AMQP concepts to JMS destinations.

AMQP Listeners

Listeners are defined under the listeners entity list, each specifying a TCP port, optional bind address, SASL authentication enablement, and a connection template. Each listener may restrict inbound connections via a host access list. Listeners are dynamically managed and can be added or removed at runtime.

Connection Templates

Connection templates define network and protocol parameters for AMQP connections, such as buffer sizes, idle timeouts, frame/message size limits, channel and handle limits, and link credit. Each listener references a connection template by name, allowing for flexible tuning of connection characteristics.

SASL Authentication

The Swiftlet supports SASL authentication mechanisms (PLAIN and ANONYMOUS by default) for AMQP connections. SASL is enabled or disabled per listener. Authentication integrates with the router's authentication Swiftlet, and user credentials are validated accordingly.

Configuration Example:

<swiftlet name="sys$amqp">
  <listeners>
    <listener name="amqp-default" port="5672" sasl-enabled="true" connection-template="default"/>
  </listeners>
</swiftlet>

Message Transformation and Custom Transformers

The AMQP Swiftlet provides a flexible message transformation framework for converting between AMQP and JMS message formats. This is achieved through configurable inbound and outbound transformers, which can be specified globally (default) or per destination (queue or topic). The default transformers (JMSMappingInboundTransformer and JMSMappingOutboundTransformer) map AMQP message properties, headers, and bodies to JMS equivalents and vice versa. Custom transformers can be implemented by extending the abstract classes InboundTransformer and OutboundTransformer (located in com.swiftmq.impl.amqp.amqp.v01_00_00.transformer). These base classes define the contract for transformation logic and provide a setConfiguration(Map config) method for runtime configuration. Transformers are instantiated and configured via the transformer entity in the Swiftlet configuration.

InboundTransformer (Base Class)

Custom inbound transformers must extend the abstract class InboundTransformer and implement the method transform(TransferFrame frame, DestinationFactory destinationFactory) (for AMQP 1.0.0) or transform(MessageWrap messageWrap, DestinationFactory destinationFactory) (for AMQP 0.9.1). The setConfiguration(Map config) method is called with transformer-specific properties from the configuration. The base class provides utility methods for property lookup and message ID generation.

OutboundTransformer (Base Class)

Custom outbound transformers must extend the abstract class OutboundTransformer and implement the method transform(Delivery delivery) (for AMQP 1.0.0) or transform(MessageImpl jmsMessage) (for AMQP 0.9.1). The setConfiguration(Map config) method is called with transformer-specific properties from the configuration. The base class provides property lookup and naming utilities.

Per-Destination Transformers

Transformers can be assigned per destination (queue or topic) using the destination-transformers entity list. Each destination can have its own set of inbound and outbound transformers, allowing for fine-grained message format control.

Configuration Example:

<swiftlet name="sys$amqp">
  <declarations>
    <transformer>
      <default-inbound-transformers>
        <default-inbound-transformer name="0" class-name="com.swiftmq.impl.amqp.amqp.v01_00_00.transformer.JMSMappingInboundTransformer"/>
      </default-inbound-transformers>
      <default-outbound-transformers>
        <default-outbound-transformer name="0" class-name="com.swiftmq.impl.amqp.amqp.v01_00_00.transformer.JMSMappingOutboundTransformer"/>
      </default-outbound-transformers>
      <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 Connection and Session Management

The Swiftlet tracks all active AMQP connections, sessions, and links, exposing detailed runtime usage statistics and properties. Each active connection is represented under the usage entity list, including properties such as container ID, connect time, username, AMQP version, and message counters. Sessions and links (source and target) are tracked per connection, with detailed statistics for each. The Swiftlet implements flow control, heartbeats, and idle timeout handling per connection and session, ensuring robust resource management and protocol compliance.

Connection Usage Monitoring

All active connections are listed under the usage entity list, with properties for message throughput, total messages, and authentication details. Sessions and links are nested under each connection, providing a hierarchical view of AMQP activity.

Flow Control and Heartbeats

The Swiftlet enforces AMQP flow control semantics using link credit and window sizes, as defined in the connection template. Heartbeats and idle timeouts are managed per connection, and connections are closed if idle for longer than the configured threshold.

Configuration Example:

<swiftlet name="sys$amqp" collect-interval="2000"/>

AMQP Transaction Support

The AMQP Swiftlet supports AMQP 1.0.0 transactions, enabling clients to group message sends and receives into atomic units of work. The transaction registry manages the lifecycle of active transactions, including creation, discharge (commit/rollback), and association with links. Transactional state is propagated and enforced according to the AMQP specification, and all transactional operations are integrated with the SwiftMQ queue and topic managers.

Queue and Topic Mapping

AMQP queues and topics are mapped to SwiftMQ JMS destinations using the QueueMapper and ExchangeRegistry components. The mapping ensures that AMQP operations such as queue declare, bind, and publish are correctly routed to the appropriate SwiftMQ queue or topic. Temporary queues are created on demand and are automatically cleaned up when the connection or link is closed. Durable subscriptions and selectors are supported for topics, and queue naming follows AMQP and SwiftMQ conventions.

Host Access Control

Each AMQP listener can restrict inbound connections based on the connecting host's address. The host-access-list entity list allows administrators to specify allowed host patterns for each listener. If the list is empty, no restrictions are enforced; otherwise, only hosts matching the specified patterns are permitted to connect.

Configuration Example:

<swiftlet name="sys$amqp">
  <listeners>
    <listener name="restricted" port="5672" connection-template="default">
      <host-access-list>
        <host-access-entry name="192.168.1.%"/>
        <host-access-entry name="10.0.0.5"/>
      </host-access-list>
    </listener>
  </listeners>
</swiftlet>

Internal Queue Naming

  • tmp$<sequence>-<startuptime> — Temporary queue created for AMQP dynamic or non-durable subscriptions and cleaned up when the connection or link is closed.

Configuration Guide

Restricting AMQP Listener to Specific Hosts

Use this scenario to limit which hosts can connect to a given AMQP listener, for security or compliance reasons.

  1. Define a listener under the listeners entity list.
  2. Add one or more host-access-entry elements under the listener's host-access-list, using % as a wildcard.
  3. Only hosts matching these patterns will be allowed to connect.
<swiftlet name="sys$amqp">
  <listeners>
    <listener name="secure-listener" port="5672" connection-template="default">
      <host-access-list>
        <host-access-entry name="10.1.1.%"/>
        <host-access-entry name="192.168.0.10"/>
      </host-access-list>
    </listener>
  </listeners>
</swiftlet>

Assigning a Custom Message Transformer to a Destination

Use this scenario to apply a custom transformation logic for messages sent to or received from a specific queue or topic.

  1. Implement a custom transformer class by extending InboundTransformer or OutboundTransformer.
  2. Add a destination-transformer entry under the destination-transformers entity list in the configuration.
  3. Specify the custom class name in the class-name property for inbound or outbound transformers.
<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>

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>