Chapter 4. Addresses, Queues, and Topics

AMQ Broker has a unique addressing model that is both powerful and flexible and that offers great performance. The addressing model comprises three main concepts: addresses, queues and routing types.

An address represents a messaging endpoint. Within the configuration, a typical address is given a unique name, 0 or more queues, and a routing type.

A queue is associated with an address. There can be multiple queues per address. Once an incoming message is matched to an address, the message is sent on to one or more of its queues, depending on the routing type configured. Queues can be configured to be automatically created and deleted.

A routing type determines how messages are sent to the queues associated with an address. A AMQ Broker address can be configured with two different routing types.

Table 4.1. Routing Types

If you want your messages routed to…​Use this routing type …​

A single queue within the matching address, in a point-to-point manner.

anycast

Every queue within the matching address, in a publish-subscribe manner.

multicast

Note

An address must have at least one routing type.

It is possible to define more than one routing type per address, but this typically results in an anti-pattern and is therefore not recommended.

If an address does use both routing types, however, and the client does not show a preference for either one, the broker typically defaults to the anycast routing type. The one exception is when the client uses the MQTT protocol. In that case, the default routing type is multicast.

4.1. Address and Queue Naming Requirements

You should be aware of the following requirements when you configure addresses and queues:

  • To ensure that a client can connect to a queue regardless of which wire protocol it uses, your address and queue names should not include any of the following characters:

    & :: , ? >

  • The # and * characters are reserved for wildcard expressions. For more information, see the section called “AMQ Broker Wildcard Syntax”.
  • Address and queue names should not include any spaces.
  • To separate words in an address or queue name, use the configured delimiter character (the default is the . character). For more information, see the section called “AMQ Broker Wildcard Syntax”.

4.2. Configuring Point-to-Point Messaging

Point-to-point messaging is a common scenario in which a message sent by a producer has only one consumer. AMQP and JMS message producers and consumers can make use of point-to-point messaging queues, for example. Define an anycast routing type for an address so that its queues receive messages in a point-to-point manner.

When a message is received on an address using anycast, AMQ Broker locates the queue associated with the address and routes the message to it. When consumers request to consume from the address, the broker locates the relevant queue and associates this queue with the appropriate consumers. If multiple consumers are connected to the same queue, messages are distributed amongst each consumer equally, providing the consumers are equally able to handle them.

Figure 4.1. Point-to-Point

Publish-Subscribe

Procedure

  1. Open the file BROKER_INSTANCE_DIR/etc/broker.xml for editing.
  2. Wrap an anycast configuration element around the chosen queue element of an address. Ensure the value of address name and queue name elements are same.

    <configuration ...>
      <core ...>
        ...
        <address name="durable">
          <anycast>
            <queue name="durable"/>
          </anycast>
        </address>
      </core>
    </configuration>

4.3. Configuring Publish-Subscribe Messaging

In a publish-subscribe scenario, messages are sent to every consumer subscribed to an address. JMS topics and MQTT subscriptions are two examples of publish-subscribe messaging. When a message is received on an address with a multicast routing type, AMQ Broker routes a copy of the message to each queue. To reduce the overhead of copying, each queue is sent only a reference to the message and not a full copy.

Figure 4.2. Publish-Subscribe

Publish-Subscribe

Procedure

  1. Open the file BROKER_INSTANCE_DIR/etc/broker.xml for editing.
  2. Add an empty multicast configuration element to the chosen address.

    <configuration ...>
      <core ...>
        ...
        <address name="topic.foo">
          <multicast/>
        </address>
      </core>
    </configuration>
  3. (Optional) Add one more queue elements to the address and wrap the multicast element around them. This step is typically not needed since the broker automatically creates a queue for each subscription requested by a client.

    <configuration ...>
      <core ...>
        ...
        <address name="topic.foo">
          <multicast>
            <queue name="client123.topic.foo"/>
            <queue name="client456.topic.foo"/>
          </multicast>
        </address>
      </core>
    </configuration>

4.4. Configuring a Point-to-Point Using Two Queues

You can define more than one queue on an address by using an anycast routing type. Messages semt to an anycast address are distributed evenly across all associated queues. By using Fully Qualified Queue Names, which are described later, you can have clients connect to a specific queue. If more than one consumer connects to the same queue, AMQ Broker distributes messages between them.

Figure 4.3. Point-to-Point with Two Queues

Point-to-Point with Two Queues
Note

This is how AMQ Broker handles load balancing of queues across multiple nodes in a cluster.

Procedure

  1. Open the file BROKER_INSTANCE_DIR/etc/broker.xml for editing.
  2. Wrap an anycast configuration element around the queue elements in the address.

    <configuration ...>
      <core ...>
        ...
        <address name="address.foo">
          <anycast>
            <queue name="q1"/>
            <queue name="q2"/>
          </anycast>
        </address>
      </core>
    </configuration>

4.5. Using Point-to-Point and Publish-Subscribe Together

It is possible to define an address with both point-to-point and publish-subscribe semantics enabled. While not typically recommended, this can be useful when you want, for example, a JMS Queue named orders and a JMS topic named orders. The different routing types make the addresses appear to be distinct.

Using an example of JMS clients, the messages sent by a JMS queue producer are routed using the anycast routing type. Messages sent by a JMS topic producer uses the multicast routing type. In addition, when a JMS topic consumer attaches, it is attached to its own subscription queue. The JMS queue consumer, however, is attached to the anycast queue.

Figure 4.4. Point-to-Point and Publish-Subscribe

Point-to-Point and Publish-Subscribe
Note

The behavior in this scenario is dependent on the protocol being used. For JMS there is a clear distinction between topic and queue producers and consumers, which makes the logic straightforward. Other protocols like AMQP do not make this distinction. A message being sent via AMQP is routed by both anycast and multicast and consumers default to anycast. For more information, check the behavior of each protocol in the sections on protocols.

The XML excerpt below is an example of what the configuration for an address using both anycast and multicast routing types would look like in BROKER_INSTANCE_DIR/etc/broker.xml. Note that subscription queues are typically created on demand, so there is no need to list specific queue elements inside the multicast routing type.

<configuration ...>
  <core ...>
    ...
    <address name="foo.orders">
      <anycast>
        <queue name="orders"/>
      </anycast>
      <multicast/>
    </address>
  </core>
</configuration>

4.6. Configuring Subscription Queues

In most cases it is not necessary to pre-create subscription queues because protocol managers create subscription queues automatically when clients first request to subscribe to an address. See Protocol Managers and Addresses for more information. For durable subscriptions, the generated queue name is usually a concatenation of the client id and the address.

Configuring a Durable Subscription Queue

When an queue is configured as a durable subscription, the broker saves messages for any inactive subscribers and delivers them to the subscribers when they reconnect. Clients are therefore guaranteed to receive each message delivered to the queue after subscribing to it.

Procedure

  1. Open the file BROKER_INSTANCE_DIR/etc/broker.xml for editing.
  2. Add the durable configuration element to the chosen queue and assign it a value of true.

    <configuration ...>
      <core ...>
        ...
        <address name="durable.foo">
          <multicast>
            <queue name="q1">
              <durable>true</durable>
            </queue>
          </multicast>
        </address>
      </core>
    </configuration>

Configuring a Non-Shared Durable Subscription

The broker can be configured to prevent more than one consumer from connecting to a queue at any one time. The subscriptions to queues configured this way are therefore "non-shared".

Procedure

  1. Open the file BROKER_INSTANCE_DIR/etc/broker.xml for editing.
  2. Add the durable configuration element to each chosen queue.

    <configuration ...>
      <core ...>
        ...
        <address name="non.shared.durable.foo">
          <multicast>
            <queue name="orders1">
              <durable>true</durable>
            </queue>
            <queue name="orders2">
              <durable>true</durable>
            </queue>
          </multicast>
        </address>
      </core>
    </configuration>
  3. Add the max-consumers attribute to each chosen queue element and assign it a value of 1.

    <configuration ...>
      <core ...>
        ...
        <address name="non.shared.durable.foo">
          <multicast>
            <queue name="orders1" max-consumers="1">
              <durable>true</durable>
            </queue>
            <queue name="orders2" max-consumers="1">
              <durable>true</durable>
            </queue>
          </multicast>
        </address>
      </core>
    </configuration>

4.7. Using a Fully Qualified Queue Name

Internally the broker maps a client’s request for an address to specific queues. The broker decides on behalf of the client which queues to send messages, or from which queue to receive messages. However, more advanced use cases might require that the client specify a queue directly. In these situations the client can use a Fully Qualified Queue Name (FQQN), by specifying both the address name and the queue name, separated by a ::.

Prerequisites

  • An address is configured with two or more queues. In the example below the address foo has two queues, q1 and q2.

    <configuration ...>
      <core ...>
        ...
        <addresses>
           <address name="foo">
              <anycast>
                 <queue name="q1" />
                 <queue name="q2" />
              </anycast>
           </address>
        </addresses>
      </core>
    </configuration>

Procedure

  • In the client code, use both the address name and the queue name when requesting a connection from the broker. Remember to use two colons, ::, to separate the names, as in the example Java code below.

    String FQQN = "foo::q1";
    Queue q1 session.createQueue(FQQN);
    MessageConsumer consumer = session.createConsumer(q1);

4.8. Configuring Sharded Queues

A common pattern for processing of messages across a queue where only partial ordering is required is to use queue sharding. In AMQ Broker this can be achieved by creating an anycast address that acts as a single logical queue, but which is backed by many underlying physical queues.

Procedure

  1. Open BROKER_INSTANCE_DIR/etc/broker.xml and add an address with the desired name. In the example below the address named sharded is added to the configuration.

    <configuration ...>
      <core ...>
        ...
        <addresses>
           <address name="sharded"></address>
        </addresses>
      </core>
    </configuration>
  2. Add the anycast routing type and include the desired number of sharded queues. In the example below, the queues q1, q2, and q3 are added as anycast destinations.

    <configuration ...>
      <core ...>
        ...
        <addresses>
           <address name="sharded">
              <anycast>
                 <queue name="q1" />
                 <queue name="q2" />
                 <queue name="q3" />
              </anycast>
           </address>
        </addresses>
    </core>
    </configuration>

Using the configuration above, messages sent to sharded are distributed equally across q1, q2 and q3. Clients are able to connect directly to a specific physical queue when using a fully qualified queue name and receive messages sent to that specific queue only.

To tie particular messages to a particular queue, clients can specify a message group for each message. The broker routes grouped messages to the same queue, and one consumer processes them all. See the chapter on Message Grouping for more information.

4.9. Configuring Last Value Queues

A last value queue is a type of queue that discards messages in the queue when a newer message with the same last value property name is placed in the queue. Through this behavior, last value queues retain only the last values for messages of the same property.

A simple use case for a last value queue is for monitoring stock prices, where only the latest value for a particular stock is of interest.

Note

The broker delivers messages that are sent to a last value queue without a configured last value property as normal messages. Such messages are not purged from the queue when a new message with a configured last value property arrives.

You can configure last value queues using:

  • The broker.xml configuration file
  • The JMS client
  • The Core API
  • Address wildcards

For each of the above methods, apart from the Core API, you can specify a custom value for the last value key (also called the last value property), or leave this value unset, meaning that the key is set to the default value instead. The default value for the last value key is _AMQ_LVQ_NAME.

For the Core API, you create last value queues using the constant last value key Message.HDR_LAST_VALUE_NAME to identify last value messages.

4.9.1. Configuring Last Value Queues Using broker.xml

To specify a custom value for the last value key, include lines in your broker.xml configuration file that look like the following:

<address name="my.address">
<multicast>
<queue name="prices1" last-value-key="stock_ticker"/>
</multicast>
</address>

Alternatively, you can configure a last value queue that uses the default last value key name of _AMQ_LVQ_NAME. To do this, set the last-value configuration parameter to true in your broker.xml configuration file, without specifying a value for the last value key. An example of this configuration is shown below.

<address name="my.address">
<multicast>
<queue name="prices1" last-value="true"/>
</multicast>
</address>

4.9.2. Configuring Last Value Queues Using the JMS Client

When using the JMS Client to auto-create destinations used by a consumer, you can specify a last value key as part of the address settings. In this case, the auto-created queues are last value queues. An example of this configuration is shown below.

Queue queue = session.createQueue("my.destination.name?last-value-key=stock_ticker");
Topic topic = session.createTopic("my.destination.name?last-value-key=stock_ticker");

Alternatively, configure a last value queue that uses the default last value key name of _AMQ_LVQ_NAME. To do this, set the last-value configuration parameter to true, without specifying a value for the last value key. An example of this configuration is shown below.

Queue queue = session.createQueue("my.destination.name?last-value=true");
Topic topic = session.createTopic("my.destination.name?last-value=true");

4.9.3. Configuring Last Value Queues Using the Core API

To create a last value queue using the Core API, set the lastvalue parameter to true when creating a queue. To do this, use the createQueue method of the ClientSession interface. The syntax for creating a last value queue using this method is shown below.

void createQueue(
SimpleString address,
RoutingType routingType,
SimpleString queueName,
SimpleString filter,
Boolean durable,
Boolean autoCreated,
int maxConsumers,
Boolean purgeOnNoConsumers,
Boolean exclusive,
Boolean lastValue
)

In this case, the API uses the constant Message.HDR_LAST_VALUE_NAME to identify last value messages delivered to the queue.

Additional Resources

  • For more information about using the createQueue method of the Core API to create a last value queue, see createQueue.

4.9.4. Configuring Last Value Queues Using Address Wildcards

You can use address wildcards in the broker.xml configuration file to configure last value queues for a set of addresses. An example of this configuration is shown below.

<address-setting match="lastValueQueue">
   <default-last-value-key>stock_ticker</default-last-value-key>
</address-setting>

By default, the value of default-last-value-key is null.

When using address wildcards, you can also use the default last value key name. To do this, set the default-last-value-queue parameter to true, without specifying a value for the last value key.

4.9.5. Example of Last Value Queue Behavior

This example shows the configuration and behavior of a last value queue.

In your broker.xml configuration file, suppose that you have added configuration that looks like the following:

<address name="my.address">
<multicast>
<queue name="prices1" last-value-key="stock_ticker"/>
</multicast>
</address>

The configuration shown above creates a last value queue called prices1, with a last value key of stock_ticker.

Now, suppose that a client sends two messages with the same last value property name to the prices1 queue, as shown below:

TextMessage message = session.createTextMessage("First message with last value property set");
message.setStringProperty("stock_ticker", "36.83");
producer.send(message);
TextMessage message = session.createTextMessage("Second message with last value property set");
message.setStringProperty("stock_ticker", "37.02");
producer.send(message);

When two messages with the same last value property name arrive to the last value queue prices1, only the latest message remains in the queue, with the first message being purged. At the command line, you can enter the following lines to validate this behavior:

TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
System.out.format("Received message: %s\n", messageReceived.getText());

In this example, the output you see is the second message, since both messages use the last value property and the second message was received in the queue after the first.

4.9.6. Creating Non-Destructive Consumers

When a consumer attaches to a queue, the normal behavior is that messages sent to that consumer are acquired exclusively by the consumer. When the consumer acknowledges receipt of the messages, the broker removes the messages from the queue.

An alternative way to configure a consumer is to configure it as a queue browser. In this case, the queue still sends all messages to the consumer. However the browser does not prevent other consumers from receiving the messages. In addition, the messages remain in the queue once the browser has consumed the messages. A consumer configured as a browser is an instance of a non-destructive consumer.

In the case of a last value queue, configuring all consumers as non-destructive consumers ensures that the queue always retains the most up-to-date value for every last value key. The examples in the following sub-sections show how to configure a last value queue to ensure that all consumers are non-destructive.

4.9.6.1. Configuring Non-destructive Consumers Using broker.xml

In the broker.xml configuration file, to create a last value queue, set the non-destructive parameter to true. An example of this configuration is shown below.

<address name="my.address">
   <multicast>
      <queue name="orders1" last-value-key="stock_ticker" non-destructive="true" />
   </multicast>
</address>

4.9.6.2. Creating Non-destructive Consumers Using the JMS Client

When using the JMS Client to auto-create destinations used by a consumer, you configure last value queue behavior and non-destructive consumers as part of the address settings. An example of this configuration is shown below.

Queue queue = session.createQueue("my.destination.name?last-value-key=stock_ticker&non-destructive=true");
Topic topic = session.createTopic("my.destination.name?last-value-key=stock_ticker&non-destructive=true");

4.9.6.3. Configuring Non-destructive Consumers Using Address Wildcards

You can use address wildcards in the broker.xml configuration file to configure last value queues for a set of addresses. As part of this configuration, you can also specify that consumers are non destructive, by setting default-non-destructive to true. An example of this configuration is shown below.

<address-setting match="lastValueQueue">
   <default-last-value-key>stock_ticker </default-last-value-key>
   <default-non-destructive>true</default-non-destructive>
</address-setting>

By default, the value of default-non-destructive is false.

4.9.6.4. Configuring Message Expiry Delay

For a queue other than a last value queue, if you have only non-destructive consumers, the broker never deletes messages from the queue, causing the queue size to increase over time. To prevent this unconstrained growth in queue size, use the expiry-delay parameter to specify when messages expire.

Specify a message expiry delay in the address-setting element of your broker.xml configuration file, as shown in the following example:

<address-setting match="exampleQueue">
   <expiry-delay>10</expiry-delay>
</address-setting>

When you add the preceding lines to your broker.xml configuration file, the broker sends expired messages in exampleQueue to the expiry address expiryQueue.

expiry-delay defines the expiration time, in milliseconds, that will be applied to messages that are using the default expiration time. By default, messages have an expiration time of 0, meaning that they don’t expire. For messages with an expiration time greater than the default, expiry-delay has no effect.

For example, suppose you set expiry-delay on a queue to 10. If a message with the default expiration time of 0 arrives in the queue, then the broker changes the expiration time of the message from 0 to 10. However, if another message that is using an expiration time of 20 arrives in the queue, then its expiration time remains unchanged. If you set expiry-delay to -1, this feature is disabled. By default, expiry-delay is set to -1.

4.10. Limiting the Number of Consumers Connected to a Queue

Limit the number of consumers connected to a particular queue by using the max-consumers attribute. Create an exclusive consumer by setting max-consumers flag to 1. The default value is -1, which is sets an unlimited number of consumers.

Procedure

  1. Open BROKER_INSTANCE_DIR/etc/broker.xml and add the max-consumers attribute to the desired queue. In the example below, only 20 consumers can connect to the queue q3 at the same time.

    <configuration ...>
      <core ...>
        ...
        <addresses>
           <address name="foo">
              <anycast>
                 <queue name="q3" max-consumers="20"/>
              </anycast>
           </address>
        </addresses>
      </core>
    </configuration>
  2. (Optional) Create an exclusive consumer by setting max-consumers to 1, as in the example below.

    <configuration ...>
      <core ...>
        ...
        <address name="foo">
          <anycast>
            <queue name="q3" max-consumers="1"/>
          </anycast>
        </address>
      </core>
    </configuration>
  3. (Optional) Have an unlimited number of consumers by setting max-consumers to -1, as in the example below.

    <configuration ...>
      <core ...>
        ...
        <address name="foo">
          <anycast>
             <queue name="q3" max-consumers="-1"/>
          </anycast>
        </address>
      </core>
    </configuration>

4.11. Exclusive Queues

Exclusive queues are special queues that route all messages to only one consumer at a time. This is useful when you want all messages to be processed serially by the same consumer. If there are multiple consumers on a queue only one consumer will receive messages. If this consumer disconnects then another consumer is chosen.

4.11.1. Configuring Exclusive Queues

You configure exclusive queues in the broker.xml configuration file something like this.

<configuration ...>
  <core ...>
    ...
    <address name="foo.bar">
      <multicast>
        <queue name="orders1" exclusive="true"/>
      </multicast>
    </address>
  </core>
</configuration>

Or on auto-create when using the JMS Client by using address parameters when creating the destination used by the consumer.

Queue queue = session.createQueue("my.destination.name?exclusive=true");
Topic topic = session.createTopic("my.destination.name?exclusive=true");

4.11.2. Setting the Exclusive Queue Default

<address-setting match="myQueue">
    <default-exclusive-queue>true</default-exclusive-queue>
</address-setting>

The default value for default-exclusive-queue is false.

4.12. Configuring a Prefix to Connect to a Specific Routing Type

Normally, if a message is received by an address that uses both anycast and multicast, one of the anycast queues receive the message and all of the multicast queues. However, clients can specify a special prefix when connecting to an address to specify whether to connect using anycast or multicast. The prefixes are custom values that are designated using the anycastPrefix and multicastPrefix parameters within the URL of an acceptor.

Configuring an Anycast Prefix

  • In BROKER_INSTANCE_DIR/etc/broker.xml, add the anycastPrefix to the URL of the desired acceptor. In the example below, the acceptor is configured to use anycast:// for the anycastPrefix. Client code can specify anycast://foo/ if the client needs to send a message to only one of the anycast queues.
<configuration ...>
  <core ...>
    ...
      <acceptors>
         <!-- Acceptor for every supported protocol -->
         <acceptor name="artemis">tcp://0.0.0.0:61616?protocols=AMQP;anycastPrefix=anycast://</acceptor>
      </acceptors>
    ...
  </core>
</configuration>

Configuring a Multicast Prefix

  • In BROKER_INSTANCE_DIR/etc/broker.xml, add the anycastPrefix to the URL of the desired acceptor. In the example below, the acceptor is configured to use multicast:// for the multicastPrefix. Client code can specify multicast://foo/ if the client needs the message sent to only the multicast queues of the address.
<configuration ...>
  <core ...>
    ...
      <acceptors>
         <!-- Acceptor for every supported protocol -->
         <acceptor name="artemis">tcp://0.0.0.0:61616?protocols=AMQP;multicastPrefix=multicast://</acceptor>
      </acceptors>
    ...
  </core>
</configuration>

4.13. Protocol Managers and Addresses

A protocol manager maps protocol-specific concepts down to the AMQ Broker address model concepts: queues and routing types. For example, when a client sends a MQTT subscription packet with the addresses /house/room1/lights and /house/room2/lights, the MQTT protocol manager understands that the two addresses require multicast semantics. The protocol manager therefore first looks to ensure that multicast is enabled for both addresses. If not, it attempts to dynamically create them. If successful, the protocol manager then creates special subscription queues for each subscription requested by the client.

Each protocol behaves slightly differently. The table below describes what typically happens when subscribe frames to various types of queue are requested.

Table 4.2. Protocol Manager Actions

If the queue is of this type…​The typical action for a protocol manager is to…​

Durable Subscription Queue

Look for the appropriate address and ensures that multicast semantics is enabled. It then creates a special subscription queue with the client ID and the address as its name and multicast as its routing type.

The special name allows the protocol manager to quickly identify the required client subscription queues should the client disconnect and reconnect at a later date.

When the client unsubscribes the queue is deleted.

Temporary Subscription Queue

Look for the appropriate address and ensures that multicast semantics is enabled. It then creates a queue with a random (read UUID) name under this address with multicast routing type.

When the client disconnects the queue is deleted.

Point-to-Point Queue

Look for the appropriate address and ensures that anycast routing type is enabled. If it is, it aims to locate a queue with the same name as the address. If it does not exist, it looks for the first queue available. It this does not exist then it automatically creates the queue (providing auto create is enabled). The queue consumer is bound to this queue.

If the queue is auto created, it is automatically deleted once there are no consumers and no messages in it.

4.14. Disabling Advisory Messages

By default, AMQ creates advisory messages about addresses and queues when an OpenWire client is connected to the broker. Advisory messages are sent to internally managed addresses created by the broker. These addresses appear on the AMQ Console within the same display as user-deployed addresses and queues. Although they provide useful information, advisory messages can cause unwanted consequences when the broker manages a large number of destinations. For example, the messages might increase memory usage or strain connection resources. Also, the AMQ Console might become cluttered when attempting to display all of the addresses created to send advisory messages. To avoid these situations, use the supportAdvisory and suppressInternalManagementObjects parameters to manage the advisory messages behavior on the broker side.

  • supportAdvisory: Set this option to true to enable creation of advisory messages or false to disable them. The default value is true.
  • suppressInternalManagementObjects: Set this option to true to expose the advisory messages to the management service such as JMX registry and AMQ Console, or false to not expose them. The default value is true.

Use these parameters by editing the BROKER_INSTANCE_DIR/etc/broker.xml configuration file and configure the parameters on openwire acceptors by using URLs. For example:

<acceptor name="artemis">tcp://127.0.0.1:61616?protocols=CORE,AMQP,OPENWIRE;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>

4.15. Configuring Address Settings

AMQ Broker has several configurable options that control aspects of how and when a message is delivered, how many attempts should be made, and when the message expires. These configuration options all exist within the <address-setting> configuration element. You can have AMQ Broker apply a single <address-setting> to multiple destinations by using a wildcard syntax.

AMQ Broker Wildcard Syntax

AMQ Broker uses a specific syntax for representing wildcards in security settings, address settings, and when creating consumers.

  • A wildcard expression contains words delimited by the character ‘.’.
  • The special characters ‘#’ and ‘*’ also have special meaning and can take the place of a word.
  • The character ‘#’ means 'match any sequence of zero or more words'. Use this at the end of your expression.
  • The character ‘*’ means 'match a single word'. Use this anywhere within your expression.

Matching is not done character by character, but at each delimiter boundary. For example, an address-setting looking to match queues using my in their name would not match with a queue named myqueue.

When more than one address-setting matches a queue, the broker will overlay configurations, using the configuration of the least specific match as the baseline. Literal expressions are more specific than wildcards, and * is more specific than #. For example, both my.queue and my.* match the queue my.queue. In this case, the broker first applies the configuration found under my.*, since a wildcard expression is less specific than a literal. Next, the broker overlays the configuration of the my.queue address-setting, which will overwrite any configuration shared with my.*. Given the configuration below, the queue my.queue would have max-delivery-attempts set to 3 and last-value-queue set to false.

<address-setting match="my.*">
    <max-delivery-attempts>3</max-delivery-attempts>
    <last-value-queue>true</last-value-queue>
</address-setting>
<address-setting match="my.queue">
    <last-value-queue>false</last-value-queue>
</address-setting>

The examples in the table below illustrate how wildcards are used to match a set of addresses.

Table 4.3. Wildcard Examples

ExampleDescription

#

The default address-setting used in broker.xml. Matches every address. You can continue to apply this catch-all, or you can add a new address-setting for each address or group of addresses as the need arises.

news.europe.#

Matches news.europe, news.europe.sport, news.europe.politics.fr, but not news.usa or europe.

news.*

Matches news.europe and news.usa, but not news.europe.sport.

news.*.sport

Matches news.europe.sport and news.usa.sport, but not news.europe.fr.sport.

Configuring Wildcard Syntax

You can customize the syntax used for wildcard addresses by adding configuration to broker.xml.

Procedure

  • Edit broker.xml by adding a <wildcard-addresses> section to the configuration, as in the example below.
<configuration>
  <core>
    ...
    <wildcard-addresses> 1
      <enabled>true</enabled> 2
      <delimiter>,</delimiter> 3
      <any-words>@</any-words> 4
      <single-word>$</single-word> 5
    </wildcard-addresses>
    ...
  </core>
</configuration>
1
Add wildcard-addresses beneath the core configuration element.
2
Set enabled to true to tell the broker to use your custom settings.
3
Provide a custom character to use as the delimiter instead of the default, which is ..
4
The character provided as the value for any-words is used to mean 'match any sequence of zero or more words' and will replace the default #. Use this character at the end of your expression.
5
The character provided as the value for single-word is used to mean 'match a single word' and will replaced the default *. Use this character anywhere within your expression.

4.16. Creating and Deleting Queues and Addresses Automatically

You can configure AMQ Broker to automatically create addresses and queues, and to delete them after they are no longer in use. This saves you from having to pre-configure each address before a client can connect to it.

Automatic creation and deletion of queues and addresses is configured on a per address-setting basis. The configuration is applied to any address or queue that is a match for the address-setting. For more information about how to use wildcard syntax to match addresses and queues to an address-setting see Configuring Address Settings.

Important

Disabling the automatic creation of queues and addresses can cause problems and is not recommended. AMQ Broker must be able to auto-create addresses and queues by using the activemq.# pattern. For an example see the example address setting.

The following table lists the configuration elements available when configuring an address-setting to automatically create and delete its queues and addresses.

If you want the address-setting to…​Add this configuration…​

Create addresses when a client sends a message to or attempts to consume a message from a queue mapped to an address that does not exist.

auto-create-addresses

Create a queue when a client sends a message to or attempts to consume a message from a queue.

auto-create-queues

Delete an automatically created address when it no longer has any queues.

auto-delete-addresses

Delete an automatically created queue when the queue has 0 consumers and 0 messages.

auto-delete-queues

Use a specific routing type if the client does not specify one.

default-address-routing-type

Procedure

Edit the BROKER_INSTANCE_DIR/etc/broker.xml file and configure an address-setting for automatic creation and deletion. The following example uses all of the configuration elements mentioned in the previous table.

<configuration ...>
 <core ...>
  ...
  <address-settings>
    <address-setting match="activemq.#"> 1
      <auto-create-addresses>true</auto-create-addresses> 2
      <auto-delete-addresses>true</auto-delete-addresses> 3
      <auto-create-queues>true</auto-create-queues> 4
      <auto-delete-queues>true</auto-delete-queues> 5
      <default-address-routing-type>ANYCAST</default-address-routing-type> 6
    </address-setting>
  </address-settings>
  ...
 </core>
</configuration>
1
The configuration included in this address-setting is applied to any address or queue that matches the wildcard activemq.#. For more information on using wildcard syntax see AMQ Broker Wildcard Syntax.
2
The broker creates an address that does not exist when a client requests it.
3
An automatically created address is deleted when it no longer has any queues associated with it.
4
The broker creates a queue that does not exist when a client requests it.
5
An automatically created queue is deleted when it no longer has any consumers or messages.
6
If the client does not specify a routing type when connecting, the broker uses ANYCAST when delivering messages to an address. The default value is MULTICAST. See the introduction of this chapter for more information about routing types.