activemq-artemis/docs/user-manual/en/management.xml

1118 lines
68 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!-- ============================================================================= -->
<!-- Licensed to the Apache Software Foundation (ASF) under one or more -->
<!-- contributor license agreements. See the NOTICE file distributed with -->
<!-- this work for additional information regarding copyright ownership. -->
<!-- The ASF licenses this file to You under the Apache License, Version 2.0 -->
<!-- (the "License"); you may not use this file except in compliance with -->
<!-- the License. You may obtain a copy of the License at -->
<!-- -->
<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
<!-- -->
<!-- Unless required by applicable law or agreed to in writing, software -->
<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -->
<!-- See the License for the specific language governing permissions and -->
<!-- limitations under the License. -->
<!-- ============================================================================= -->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "ActiveMQ_User_Manual.ent">
%BOOK_ENTITIES;
]>
<chapter id="management">
<title>Management</title>
<para>ActiveMQ has an extensive management API that allows a user to modify a server
configuration, create new resources (e.g. JMS queues and topics), inspect these resources
(e.g. how many messages are currently held in a queue) and interact with it (e.g. to remove
messages from a queue). All the operations allows a client to <emphasis>manage</emphasis>
ActiveMQ. It also allows clients to subscribe to management notifications.</para>
<para>There are 3 ways to manage ActiveMQ:</para>
<itemizedlist>
<listitem>
<para>Using JMX -- JMX is the standard way to manage Java applications</para>
</listitem>
<listitem>
<para>Using the core API -- management operations are sent to ActiveMQ server using
<emphasis>core messages</emphasis></para>
</listitem>
<listitem>
<para>Using the JMS API -- management operations are sent to ActiveMQ server using
<emphasis>JMS messages</emphasis></para>
</listitem>
</itemizedlist>
<para>Although there are 3 different ways to manage ActiveMQ each API supports the same
functionality. If it is possible to manage a resource using JMX it is also possible to achieve
the same result using Core messages or JMS messages.</para>
<para>This choice depends on your requirements, your application settings and your environment to
decide which way suits you best.</para>
<section>
<title>The Management API</title>
<para>Regardless of the way you <emphasis>invoke</emphasis> management operations, the
management API is the same.</para>
<para>For each <emphasis>managed resource</emphasis>, there exists a Java interface describing
what can be invoked for this type of resource.</para>
<para>ActiveMQ exposes its managed resources in 2 packages:</para>
<itemizedlist>
<listitem>
<para><emphasis>Core</emphasis> resources are located in the <literal
>org.apache.activemq.api.core.management</literal> package</para>
</listitem>
<listitem>
<para><emphasis>JMS</emphasis> resources are located in the <literal
>org.apache.activemq.api.jms.management</literal> package</para>
</listitem>
</itemizedlist>
<para>The way to invoke a <emphasis>management operations</emphasis> depends whether JMX, core
messages, or JMS messages are used.</para>
<note>
<para>A few management operations requires a <literal>filter</literal> parameter to chose
which messages are involved by the operation. Passing <literal>null</literal> or an
empty string means that the management operation will be performed on <emphasis>all
messages</emphasis>.</para>
</note>
<section>
<title>Core Management API</title>
<para>ActiveMQ defines a core management API to manage core resources. For full details of
the API please consult the javadoc. In summary:</para>
<section id="management.core.server">
<title>Core Server Management</title>
<itemizedlist>
<listitem>
<para>Listing, creating, deploying and destroying queues</para>
<para>A list of deployed core queues can be retrieved using the <literal
>getQueueNames()</literal> method.</para>
<para>Core queues can be created or destroyed using the management operations
<literal>createQueue()</literal> or <literal>deployQueue()</literal> or
<literal>destroyQueue()</literal>)on the <literal
>ActiveMQServerControl</literal> (with the ObjectName <literal
>org.apache.activemq:module=Core,type=Server</literal> or the resource name <literal
>core.server</literal>)</para>
<para><literal>createQueue</literal> will fail if the queue already exists while
<literal>deployQueue</literal> will do nothing.</para>
</listitem>
<listitem>
<para>Pausing and resuming Queues</para>
<para>The <literal>QueueControl</literal> can pause and resume the underlying
queue. When a queue is paused, it will receive messages but will not deliver
them. When it's resumed, it'll begin delivering the queued messages, if any.
</para>
</listitem>
<listitem>
<para>Listing and closing remote connections</para>
<para>Client's remote addresses can be retrieved using <literal
>listRemoteAddresses()</literal>. It is also possible to close the
connections associated with a remote address using the <literal
>closeConnectionsForAddress()</literal> method.</para>
<para>Alternatively, connection IDs can be listed using <literal
>listConnectionIDs()</literal> and all the sessions for a given connection
ID can be listed using <literal>listSessions()</literal>.</para>
</listitem>
<listitem>
<para>Transaction heuristic operations</para>
<para>In case of a server crash, when the server restarts, it it possible that
some transaction requires manual intervention. The <literal
>listPreparedTransactions()</literal> method lists the transactions which
are in the prepared states (the transactions are represented as opaque Base64
Strings.) To commit or rollback a given prepared transaction, the <literal
>commitPreparedTransaction()</literal> or <literal
>rollbackPreparedTransaction()</literal> method can be used to resolve
heuristic transactions. Heuristically completed transactions can be listed
using the <literal>listHeuristicCommittedTransactions()</literal> and <literal
>listHeuristicRolledBackTransactions</literal> methods.</para>
</listitem>
<listitem>
<para>Enabling and resetting Message counters</para>
<para>Message counters can be enabled or disabled using the <literal
>enableMessageCounters()</literal> or <literal
>disableMessageCounters()</literal> method. To reset message counters, it is
possible to invoke <literal>resetAllMessageCounters()</literal> and <literal
>resetAllMessageCounterHistories()</literal> methods.</para>
</listitem>
<listitem>
<para>Retrieving the server configuration and attributes</para>
<para>The <literal>ActiveMQServerControl</literal> exposes ActiveMQ server
configuration through all its attributes (e.g. <literal>getVersion()</literal>
method to retrieve the server's version, etc.)</para>
</listitem>
<listitem>
<para>Listing, creating and destroying Core bridges and diverts</para>
<para>A list of deployed core bridges (resp. diverts) can be retrieved using the <literal
>getBridgeNames()</literal> (resp. <literal>getDivertNames()</literal>) method.</para>
<para>Core bridges (resp. diverts) can be created or destroyed using the management operations
<literal>createBridge()</literal> and <literal>destroyBridge()</literal>
(resp. <literal>createDivert()</literal> and <literal>destroyDivert()</literal>) on the <literal
>ActiveMQServerControl</literal> (with the ObjectName <literal
>org.apache.activemq:module=Core,type=Server</literal> or the resource name <literal
>core.server</literal>).</para>
</listitem>
<listitem>
<para>It is possible to stop the server and force failover to occur with any currently attached clients.</para>
<para>to do this use the <literal>forceFailover()</literal> on the <literal
>ActiveMQServerControl</literal> (with the ObjectName <literal
>org.apache.activemq:module=Core,type=Server</literal> or the resource name <literal
>core.server</literal>) </para>
<note>
<para>Since this method actually stops the server you will probably receive some sort of error
depending on which management service you use to call it.
</para>
</note>
</listitem>
</itemizedlist>
</section>
<section>
<title>Core Address Management</title>
<para>Core addresses can be managed using the <literal>AddressControl</literal> class
(with the ObjectName <literal>org.apache.activemq:module=Core,type=Address,name="&lt;the
address name>"</literal> or the resource name <literal>core.address.&lt;the
address name></literal>). </para>
<itemizedlist>
<listitem>
<para>Modifying roles and permissions for an address</para>
<para>You can add or remove roles associated to a queue using the <literal
>addRole()</literal> or <literal>removeRole()</literal> methods. You can
list all the roles associated to the queue with the <literal
>getRoles()</literal> method</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Core Queue Management</title>
<para>The bulk of the core management API deals with core queues. The <literal
>QueueControl</literal> class defines the Core queue management operations (with
the ObjectName <literal>org.apache.activemq:module=Core,type=Queue,address="&lt;the bound
address>",name="&lt;the queue name>"</literal> or the resource name <literal
>core.queue.&lt;the queue name></literal>).</para>
<para>Most of the management operations on queues take either a single message ID (e.g.
to remove a single message) or a filter (e.g. to expire all messages with a given
property.)</para>
<itemizedlist>
<listitem>
<para>Expiring, sending to a dead letter address and moving messages</para>
<para>Messages can be expired from a queue by using the <literal
>expireMessages()</literal> method. If an expiry address is defined,
messages will be sent to it, otherwise they are discarded. The queue's
expiry address can be set with the <literal>setExpiryAddress()</literal>
method.</para>
<para>Messages can also be sent to a dead letter address with the <literal
>sendMessagesToDeadLetterAddress()</literal> method. It returns the number
of messages which are sent to the dead letter address. If a dead letter address
is not defined, message are removed from the queue and discarded. The queue's
dead letter address can be set with the <literal
>setDeadLetterAddress()</literal> method.</para>
<para>Messages can also be moved from a queue to another queue by using the
<literal>moveMessages()</literal> method.</para>
</listitem>
<listitem>
<para>Listing and removing messages</para>
<para>Messages can be listed from a queue by using the <literal
>listMessages()</literal> method which returns an array of <literal
>Map</literal>, one <literal>Map</literal> for each message.</para>
<para>Messages can also be removed from the queue by using the <literal
>removeMessages()</literal> method which returns a <literal
>boolean</literal> for the single message ID variant or the number of
removed messages for the filter variant. The <literal
>removeMessages()</literal> method takes a <literal>filter</literal>
argument to remove only filtered messages. Setting the filter to an empty
string will in effect remove all messages.</para>
</listitem>
<listitem>
<para>Counting messages</para>
<para>The number of messages in a queue is returned by the <literal
>getMessageCount()</literal> method. Alternatively, the <literal
>countMessages()</literal> will return the number of messages in the queue
which <emphasis>match a given filter</emphasis></para>
</listitem>
<listitem>
<para>Changing message priority</para>
<para>The message priority can be changed by using the <literal
>changeMessagesPriority()</literal> method which returns a <literal
>boolean</literal> for the single message ID variant or the number of
updated messages for the filter variant.</para>
</listitem>
<listitem>
<para>Message counters</para>
<para>Message counters can be listed for a queue with the <literal
>listMessageCounter()</literal> and <literal
>listMessageCounterHistory()</literal> methods (see <xref
linkend="management.message-counters"/>). The message counters can also be
reset for a single queue using the <literal>resetMessageCounter()</literal>
method.</para>
</listitem>
<listitem>
<para>Retrieving the queue attributes</para>
<para>The <literal>QueueControl</literal> exposes Core queue settings through its
attributes (e.g. <literal>getFilter()</literal> to retrieve the queue's filter
if it was created with one, <literal>isDurable()</literal> to know whether the
queue is durable or not, etc.)</para>
</listitem>
<listitem>
<para>Pausing and resuming Queues</para>
<para>The <literal>QueueControl</literal> can pause and resume the underlying
queue. When a queue is paused, it will receive messages but will not deliver
them. When it's resume, it'll begin delivering the queued messages, if any.
</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Other Core Resources Management</title>
<para>ActiveMQ allows to start and stop its remote resources (acceptors, diverts,
bridges, etc.) so that a server can be taken off line for a given period of time
without stopping it completely (e.g. if other management operations must be performed
such as resolving heuristic transactions). These resources are:</para>
<itemizedlist>
<listitem>
<para>Acceptors</para>
<para>They can be started or stopped using the <literal>start()</literal> or.
<literal>stop()</literal> method on the <literal>AcceptorControl</literal>
class (with the ObjectName <literal
>org.apache.activemq:module=Core,type=Acceptor,name="&lt;the acceptor
name>"</literal> or the resource name <literal>core.acceptor.&lt;the
address name></literal>). The acceptors parameters can be retrieved using
the <literal>AcceptorControl</literal> attributes (see <xref
linkend="configuring-transports.acceptors"/>)</para>
</listitem>
<listitem>
<para>Diverts</para>
<para>They can be started or stopped using the <literal>start()</literal> or
<literal>stop()</literal> method on the <literal>DivertControl</literal>
class (with the ObjectName <literal
>org.apache.activemq:module=Core,type=Divert,name=&lt;the divert name></literal>
or the resource name <literal>core.divert.&lt;the divert name></literal>).
Diverts parameters can be retrieved using the <literal>DivertControl</literal>
attributes (see <xref linkend="diverts"/>)</para>
</listitem>
<listitem>
<para>Bridges</para>
<para>They can be started or stopped using the <literal>start()</literal> (resp.
<literal>stop()</literal>) method on the <literal>BridgeControl</literal>
class (with the ObjectName <literal
>org.apache.activemq:module=Core,type=Bridge,name="&lt;the bridge
name>"</literal> or the resource name <literal>core.bridge.&lt;the bridge
name></literal>). Bridges parameters can be retrieved using the <literal
>BridgeControl</literal> attributes (see <xref linkend="core-bridges"
/>)</para>
</listitem>
<listitem>
<para>Broadcast groups</para>
<para>They can be started or stopped using the <literal>start()</literal> or
<literal>stop()</literal> method on the <literal
>BroadcastGroupControl</literal> class (with the ObjectName <literal
>org.apache.activemq:module=Core,type=BroadcastGroup,name="&lt;the broadcast group
name>"</literal> or the resource name <literal
>core.broadcastgroup.&lt;the broadcast group name></literal>). Broadcast
groups parameters can be retrieved using the <literal
>BroadcastGroupControl</literal> attributes (see <xref
linkend="clusters"/>)</para>
</listitem>
<listitem>
<para>Discovery groups</para>
<para>They can be started or stopped using the <literal>start()</literal> or
<literal>stop()</literal> method on the <literal
>DiscoveryGroupControl</literal> class (with the ObjectName <literal
>org.apache.activemq:module=Core,type=DiscoveryGroup,name="&lt;the discovery group
name>"</literal> or the resource name <literal>core.discovery.&lt;the
discovery group name></literal>). Discovery groups parameters can be
retrieved using the <literal>DiscoveryGroupControl</literal> attributes (see
<xref linkend="clusters"/>)</para>
</listitem>
<listitem>
<para>Cluster connections</para>
<para>They can be started or stopped using the <literal>start()</literal> or
<literal>stop()</literal> method on the <literal
>ClusterConnectionControl</literal> class (with the ObjectName <literal
>org.apache.activemq:module=Core,type=ClusterConnection,name="&lt;the cluster
connection name>"</literal> or the resource name <literal
>core.clusterconnection.&lt;the cluster connection name></literal>).
Cluster connections parameters can be retrieved using the <literal
>ClusterConnectionControl</literal> attributes (see <xref
linkend="clusters"/>)</para>
</listitem>
</itemizedlist>
</section>
</section>
<section>
<title>JMS Management API</title>
<para>ActiveMQ defines a JMS Management API to manage JMS <emphasis>administrated
objects</emphasis> (i.e. JMS queues, topics and connection factories).</para>
<section>
<title>JMS Server Management</title>
<para>JMS Resources (connection factories and destinations) can be created using the
<literal>JMSServerControl</literal> class (with the ObjectName <literal
>org.apache.activemq:module=JMS,type=Server</literal> or the resource name <literal
>jms.server</literal>).</para>
<itemizedlist>
<listitem>
<para>Listing, creating, destroying connection factories</para>
<para>Names of the deployed connection factories can be retrieved by the <literal
>getConnectionFactoryNames()</literal> method.</para>
<para>JMS connection factories can be created or destroyed using the <literal
>createConnectionFactory()</literal> methods or <literal
>destroyConnectionFactory()</literal> methods. These connection factories
are bound to JNDI so that JMS clients can look them up. If a graphical console
is used to create the connection factories, the transport parameters are
specified in the text field input as a comma-separated list of key=value (e.g.
<literal>key1=10, key2="value", key3=false</literal>). If there are multiple
transports defined, you need to enclose the key/value pairs between curly
braces. For example <literal>{key=10}, {key=20}</literal>. In that case, the
first <literal>key</literal> will be associated to the first transport
configuration and the second <literal>key</literal> will be associated to the
second transport configuration (see <xref linkend="configuring-transports"/>
for a list of the transport parameters)</para>
</listitem>
<listitem>
<para>Listing, creating, destroying queues</para>
<para>Names of the deployed JMS queues can be retrieved by the <literal
>getQueueNames()</literal> method.</para>
<para>JMS queues can be created or destroyed using the <literal
>createQueue()</literal> methods or <literal>destroyQueue()</literal>
methods. These queues are bound to JNDI so that JMS clients can look them
up</para>
</listitem>
<listitem>
<para>Listing, creating/destroying topics</para>
<para>Names of the deployed topics can be retrieved by the <literal
>getTopicNames()</literal> method.</para>
<para>JMS topics can be created or destroyed using the <literal
>createTopic()</literal> or <literal>destroyTopic()</literal> methods. These
topics are bound to JNDI so that JMS clients can look them up</para>
</listitem>
<listitem>
<para>Listing and closing remote connections</para>
<para>JMS Clients remote addresses can be retrieved using <literal
>listRemoteAddresses()</literal>. It is also possible to close the
connections associated with a remote address using the <literal
>closeConnectionsForAddress()</literal> method.</para>
<para>Alternatively, connection IDs can be listed using <literal
>listConnectionIDs()</literal> and all the sessions for a given connection
ID can be listed using <literal>listSessions()</literal>.</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>JMS ConnectionFactory Management</title>
<para>JMS Connection Factories can be managed using the <literal
>ConnectionFactoryControl</literal> class (with the ObjectName <literal
>org.apache.activemq:module=JMS,type=ConnectionFactory,name="&lt;the connection factory
name>"</literal> or the resource name <literal>jms.connectionfactory.&lt;the
connection factory name></literal>).</para>
<itemizedlist>
<listitem>
<para>Retrieving connection factory attributes</para>
<para>The <literal>ConnectionFactoryControl</literal> exposes JMS
ConnectionFactory configuration through its attributes (e.g. <literal
>getConsumerWindowSize()</literal> to retrieve the consumer window size for
flow control, <literal>isBlockOnNonDurableSend()</literal> to know whether the
producers created from the connection factory will block or not when sending
non-durable messages, etc.)</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>JMS Queue Management</title>
<para>JMS queues can be managed using the <literal>JMSQueueControl</literal> class (with
the ObjectName <literal>org.apache.activemq:module=JMS,type=Queue,name="&lt;the queue
name>"</literal> or the resource name <literal>jms.queue.&lt;the queue
name></literal>). </para>
<para><emphasis>The management operations on a JMS queue are very similar to the
operations on a core queue. </emphasis></para>
<itemizedlist>
<listitem>
<para>Expiring, sending to a dead letter address and moving messages</para>
<para>Messages can be expired from a queue by using the <literal
>expireMessages()</literal> method. If an expiry address is defined,
messages will be sent to it, otherwise they are discarded. The queue's
expiry address can be set with the <literal>setExpiryAddress()</literal>
method.</para>
<para>Messages can also be sent to a dead letter address with the <literal
>sendMessagesToDeadLetterAddress()</literal> method. It returns the number
of messages which are sent to the dead letter address. If a dead letter address
is not defined, message are removed from the queue and discarded. The queue's
dead letter address can be set with the <literal
>setDeadLetterAddress()</literal> method.</para>
<para>Messages can also be moved from a queue to another queue by using the
<literal>moveMessages()</literal> method.</para>
</listitem>
<listitem>
<para>Listing and removing messages</para>
<para>Messages can be listed from a queue by using the <literal
>listMessages()</literal> method which returns an array of <literal
>Map</literal>, one <literal>Map</literal> for each message.</para>
<para>Messages can also be removed from the queue by using the <literal
>removeMessages()</literal> method which returns a <literal
>boolean</literal> for the single message ID variant or the number of
removed messages for the filter variant. The <literal
>removeMessages()</literal> method takes a <literal>filter</literal>
argument to remove only filtered messages. Setting the filter to an empty
string will in effect remove all messages.</para>
</listitem>
<listitem>
<para>Counting messages</para>
<para>The number of messages in a queue is returned by the <literal
>getMessageCount()</literal> method. Alternatively, the <literal
>countMessages()</literal> will return the number of messages in the queue
which <emphasis>match a given filter</emphasis></para>
</listitem>
<listitem>
<para>Changing message priority</para>
<para>The message priority can be changed by using the <literal
>changeMessagesPriority()</literal> method which returns a <literal
>boolean</literal> for the single message ID variant or the number of
updated messages for the filter variant.</para>
</listitem>
<listitem>
<para>Message counters</para>
<para>Message counters can be listed for a queue with the <literal
>listMessageCounter()</literal> and <literal
>listMessageCounterHistory()</literal> methods (see <xref
linkend="management.message-counters"/>)</para>
</listitem>
<listitem>
<para>Retrieving the queue attributes</para>
<para>The <literal>JMSQueueControl</literal> exposes JMS queue settings through
its attributes (e.g. <literal>isTemporary()</literal> to know whether the queue
is temporary or not, <literal>isDurable()</literal> to know whether the queue is
durable or not, etc.)</para>
</listitem>
<listitem>
<para>Pausing and resuming queues</para>
<para>The <literal>JMSQueueControl</literal> can pause and resume the underlying
queue. When the queue is paused it will continue to receive messages but will
not deliver them. When resumed again it will deliver the enqueued messages, if
any. </para>
</listitem>
</itemizedlist>
</section>
<section>
<title>JMS Topic Management</title>
<para>JMS Topics can be managed using the <literal>TopicControl</literal> class (with
the ObjectName <literal>org.apache.activemq:module=JMS,type=Topic,name="&lt;the topic
name>"</literal> or the resource name <literal>jms.topic.&lt;the topic
name></literal>).</para>
<itemizedlist>
<listitem>
<para>Listing subscriptions and messages</para>
<para>JMS topics subscriptions can be listed using the <literal
>listAllSubscriptions()</literal>, <literal
>listDurableSubscriptions()</literal>, <literal
>listNonDurableSubscriptions()</literal> methods. These methods return
arrays of <literal>Object</literal> representing the subscriptions information
(subscription name, client ID, durability, message count, etc.). It is also
possible to list the JMS messages for a given subscription with the <literal
>listMessagesForSubscription()</literal> method.</para>
</listitem>
<listitem>
<para>Dropping subscriptions</para>
<para>Durable subscriptions can be dropped from the topic using the <literal
>dropDurableSubscription()</literal> method.</para>
</listitem>
<listitem>
<para>Counting subscriptions messages</para>
<para>The <literal>countMessagesForSubscription()</literal> method can be used to
know the number of messages held for a given subscription (with an optional
message selector to know the number of messages matching the selector)</para>
</listitem>
</itemizedlist>
</section>
</section>
</section>
<section id="management.jmx">
<title>Using Management Via JMX</title>
<para>ActiveMQ can be managed using <ulink
url="http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html"
>JMX</ulink>. </para>
<para>The management API is exposed by ActiveMQ using MBeans interfaces. ActiveMQ registers its
resources with the domain <literal>org.apache.activemq</literal>.</para>
<para>For example, the <literal>ObjectName</literal> to manage a JMS Queue <literal
>exampleQueue</literal> is:</para>
<programlisting>
org.apache.activemq:module=JMS,type=Queue,name="exampleQueue"</programlisting>
<para>and the MBean is:</para>
<programlisting>
org.apache.activemq.api.jms.management.JMSQueueControl</programlisting>
<para>The MBean's <literal>ObjectName</literal> are built using the helper class <literal
>org.apache.activemq.api.core.management.ObjectNameBuilder</literal>. You can also use <literal
>jconsole</literal> to find the <literal>ObjectName</literal> of the MBeans you want to
manage. </para>
<para>Managing ActiveMQ using JMX is identical to management of any Java Applications using
JMX. It can be done by reflection or by creating proxies of the MBeans.</para>
<section id="management.jmx.configuration">
<title>Configuring JMX</title>
<para>By default, JMX is enabled to manage ActiveMQ. It can be disabled by setting <literal
>jmx-management-enabled</literal> to <literal>false</literal> in <literal
>activemq-configuration.xml</literal>:</para>
<programlisting>
&lt;!-- false to disable JMX management for ActiveMQ -->
&lt;jmx-management-enabled>false&lt;/jmx-management-enabled></programlisting>
<para>If JMX is enabled, ActiveMQ can be managed locally using <literal>jconsole</literal>.</para>
<note>
<para>Remote connections to JMX are not enabled by default for security reasons. Please refer
to <ulink url="http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html"
>Java Management guide</ulink> to configure the server for remote management (system
properties must be set in <literal>run.sh</literal> or <literal>run.bat</literal>
scripts).</para>
</note>
<para>By default, ActiveMQ server uses the JMX domain "org.apache.activemq". To manage several
ActiveMQ servers from the <emphasis>same</emphasis> MBeanServer, the JMX domain can be
configured for each individual ActiveMQ server by setting <literal>jmx-domain</literal>
in <literal>activemq-configuration.xml</literal>: </para>
<programlisting>
&lt;!-- use a specific JMX domain for ActiveMQ MBeans -->
&lt;jmx-domain>my.org.apache.activemq&lt;/jmx-domain></programlisting>
<section>
<title>MBeanServer configuration</title>
<para>When ActiveMQ is run in standalone, it uses the Java Virtual Machine's <literal
>Platform MBeanServer</literal> to register its MBeans. This is configured in
JBoss Microcontainer Beans file (see <xref
linkend="server.microcontainer.configuration"/>):</para>
<programlisting>
&lt;!-- MBeanServer -->
&lt;bean name="MBeanServer" class="javax.management.MBeanServer">
&lt;constructor factoryClass="java.lang.management.ManagementFactory"
factoryMethod="getPlatformMBeanServer" />
&lt;/bean></programlisting>
<para>When it is integrated in JBoss AS 5+, it uses the Application Server's own MBean
Server so that it can be managed using AS 5's jmx-console:</para>
<programlisting>
&lt;!-- MBeanServer -->
&lt;bean name="MBeanServer" class="javax.management.MBeanServer">
&lt;constructor factoryClass="org.jboss.mx.util.MBeanServerLocator"
factoryMethod="locateJBoss" />
&lt;/bean></programlisting>
</section>
</section>
<section>
<title>Example</title>
<para>See <xref linkend="examples.jmx"/> for an example which shows how to use a remote
connection to JMX and MBean proxies to manage ActiveMQ.</para>
</section>
</section>
<section>
<title>Using Management Via Core API</title>
<para>The core management API in ActiveMQ is called by sending Core messages to a special
address, the <emphasis>management address</emphasis>.</para>
<para><emphasis>Management messages</emphasis> are regular Core messages with well-known
properties that the server needs to understand to interact with the management API:</para>
<itemizedlist>
<listitem>
<para>The name of the managed resource</para>
</listitem>
<listitem>
<para>The name of the management operation</para>
</listitem>
<listitem>
<para>The parameters of the management operation</para>
</listitem>
</itemizedlist>
<para>When such a management message is sent to the management address, ActiveMQ server will
handle it, extract the information, invoke the operation on the managed resources and send
a <emphasis>management reply</emphasis> to the management message's reply-to address
(specified by <literal>ClientMessageImpl.REPLYTO_HEADER_NAME</literal>). </para>
<para>A <literal>ClientConsumer</literal> can be used to consume the management reply and
retrieve the result of the operation (if any) stored in the reply's body. For portability,
results are returned as a <ulink url="http://json.org">JSON</ulink> String rather than Java
Serialization (the <literal>org.apache.activemq.api.core.management.ManagementHelper</literal> can
be used to convert the JSON string to Java objects).</para>
<para>These steps can be simplified to make it easier to invoke management operations using
Core messages:</para>
<orderedlist>
<listitem>
<para>Create a <literal>ClientRequestor</literal> to send messages to the management
address and receive replies</para>
</listitem>
<listitem>
<para>Create a <literal>ClientMessage</literal></para>
</listitem>
<listitem>
<para>Use the helper class <literal
>org.apache.activemq.api.core.management.ManagementHelper</literal> to fill the message
with the management properties</para>
</listitem>
<listitem>
<para>Send the message using the <literal>ClientRequestor</literal></para>
</listitem>
<listitem>
<para>Use the helper class <literal
>org.apache.activemq.api.core.management.ManagementHelper</literal> to retrieve the
operation result from the management reply</para>
</listitem>
</orderedlist>
<para>For example, to find out the number of messages in the core queue <literal
>exampleQueue</literal>:</para>
<programlisting>
ClientSession session = ...
ClientRequestor requestor = new ClientRequestor(session, "jms.queue.activemq.management");
ClientMessage message = session.createMessage(false);
ManagementHelper.putAttribute(message, "core.queue.exampleQueue", "messageCount");
session.start();
ClientMessage reply = requestor.request(m);
int count = (Integer) ManagementHelper.getResult(reply);
System.out.println("There are " + count + " messages in exampleQueue");</programlisting>
<para>Management operation name and parameters must conform to the Java interfaces defined in
the <literal>management</literal> packages.</para>
<para>Names of the resources are built using the helper class <literal
>org.apache.activemq.api.core.management.ResourceNames</literal> and are straightforward
(<literal>core.queue.exampleQueue</literal> for the Core Queue <literal
>exampleQueue</literal>, <literal>jms.topic.exampleTopic</literal> for the JMS Topic
<literal>exampleTopic</literal>, etc.).</para>
<section id="management.core.configuration">
<title>Configuring Core Management</title>
<para>The management address to send management messages is configured in <literal
>activemq-configuration.xml</literal>:</para>
<programlisting>
&lt;management-address>jms.queue.activemq.management&lt;/management-address></programlisting>
<para>By default, the address is <literal>jms.queue.activemq.management</literal> (it is
prepended by "jms.queue" so that JMS clients can also send management messages).</para>
<para>The management address requires a <emphasis>special</emphasis> user permission
<literal>manage</literal> to be able to receive and handle management messages. This
is also configured in activemq-configuration.xml:</para>
<programlisting>
&lt;!-- users with the admin role will be allowed to manage -->
&lt;!-- ActiveMQ using management messages -->
&lt;security-setting match="jms.queue.activemq.management">
&lt;permission type="manage" roles="admin" />
&lt;/security-setting></programlisting>
</section>
</section>
<section id="management.jms">
<title>Using Management Via JMS</title>
<para>Using JMS messages to manage ActiveMQ is very similar to using core API.</para>
<para>An important difference is that JMS requires a JMS queue to send the messages to
(instead of an address for the core API).</para>
<para>The <emphasis>management queue</emphasis> is a special queue and needs to be
instantiated directly by the client:</para>
<programlisting>
Queue managementQueue = ActiveMQJMSClient.createQueue("activemq.management");</programlisting>
<para>All the other steps are the same than for the Core API but they use JMS API
instead:</para>
<orderedlist>
<listitem>
<para>create a <literal>QueueRequestor</literal> to send messages to the management
address and receive replies</para>
</listitem>
<listitem>
<para>create a <literal>Message</literal></para>
</listitem>
<listitem>
<para>use the helper class <literal
>org.apache.activemq.api.jms.management.JMSManagementHelper</literal> to fill the message
with the management properties</para>
</listitem>
<listitem>
<para>send the message using the <literal>QueueRequestor</literal></para>
</listitem>
<listitem>
<para>use the helper class <literal
>org.apache.activemq.api.jms.management.JMSManagementHelper</literal> to retrieve the
operation result from the management reply</para>
</listitem>
</orderedlist>
<para>For example, to know the number of messages in the JMS queue <literal
>exampleQueue</literal>:</para>
<programlisting>
Queue managementQueue = ActiveMQJMSClient.createQueue("activemq.management");
QueueSession session = ...
QueueRequestor requestor = new QueueRequestor(session, managementQueue);
connection.start();
Message message = session.createMessage();
JMSManagementHelper.putAttribute(message, "jms.queue.exampleQueue", "messageCount");
Message reply = requestor.request(message);
int count = (Integer)JMSManagementHelper.getResult(reply);
System.out.println("There are " + count + " messages in exampleQueue");</programlisting>
<section>
<title>Configuring JMS Management</title>
<para>Whether JMS or the core API is used for management, the configuration steps are the
same (see <xref linkend="management.core.configuration"/>).</para>
</section>
<section>
<title>Example</title>
<para>See <xref linkend="examples.management"/> for an example which shows how to use JMS
messages to manage ActiveMQ server.</para>
</section>
</section>
<section id="management.notifications">
<title>Management Notifications</title>
<para>ActiveMQ emits <emphasis>notifications</emphasis> to inform listeners of potentially
interesting events (creation of new resources, security violation, etc.).</para>
<para>These notifications can be received by 3 different ways:</para>
<itemizedlist>
<listitem>
<para>JMX notifications</para>
</listitem>
<listitem>
<para>Core messages</para>
</listitem>
<listitem>
<para>JMS messages</para>
</listitem>
</itemizedlist>
<section>
<title>JMX Notifications</title>
<para>If JMX is enabled (see <xref linkend="management.jmx.configuration"/>), JMX
notifications can be received by subscribing to 2 MBeans:</para>
<itemizedlist>
<listitem>
<para><literal>org.apache.activemq:module=Core,type=Server</literal> for notifications on
<emphasis>Core</emphasis> resources</para>
</listitem>
<listitem>
<para><literal>org.apache.activemq:module=JMS,type=Server</literal> for notifications on
<emphasis>JMS</emphasis> resources</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Core Messages Notifications</title>
<para>ActiveMQ defines a special <emphasis>management notification address</emphasis>. Core
queues can be bound to this address so that clients will receive management
notifications as Core messages</para>
<para>A Core client which wants to receive management notifications must create a core
queue bound to the management notification address. It can then receive the
notifications from its queue.</para>
<para>Notifications messages are regular core messages with additional properties
corresponding to the notification (its type, when it occurred, the resources which were
concerned, etc.).</para>
<para>Since notifications are regular core messages, it is possible to use message
selectors to filter out notifications and receives only a subset of all the
notifications emitted by the server.</para>
<section id="management.notifications.core.configuration">
<title>Configuring The Core Management Notification Address</title>
<para>The management notification address to receive management notifications is
configured in <literal>activemq-configuration.xml</literal>:</para>
<programlisting>
&lt;management-notification-address>activemq.notifications&lt;/management-notification-address></programlisting>
<para>By default, the address is <literal>activemq.notifications</literal>.</para>
</section>
</section>
<section>
<title>JMS Messages Notifications</title>
<para>ActiveMQ's notifications can also be received using JMS messages.</para>
<para>It is similar to receiving notifications using Core API but an important difference
is that JMS requires a JMS Destination to receive the messages (preferably a
Topic).</para>
<para>To use a JMS Destination to receive management notifications, you must change the server's
management notification address to start with <literal>jms.queue</literal> if it is a JMS Queue
or <literal>jms.topic</literal> if it is a JMS Topic:</para>
<programlisting>
&lt;!-- notifications will be consumed from "notificationsTopic" JMS Topic -->
&lt;management-notification-address>jms.topic.notificationsTopic&lt;/management-notification-address></programlisting>
<para>Once the notification topic is created, you can receive messages from it or set a
<literal>MessageListener</literal>:</para>
<programlisting>
Topic notificationsTopic = ActiveMQJMSClient.createTopic("notificationsTopic");
Session session = ...
MessageConsumer notificationConsumer = session.createConsumer(notificationsTopic);
notificationConsumer.setMessageListener(new MessageListener()
{
public void onMessage(Message notif)
{
System.out.println("------------------------");
System.out.println("Received notification:");
try
{
Enumeration propertyNames = notif.getPropertyNames();
while (propertyNames.hasMoreElements())
{
String propertyName = (String)propertyNames.nextElement();
System.out.format(" %s: %s\n", propertyName, notif.getObjectProperty(propertyName));
}
}
catch (JMSException e)
{
}
System.out.println("------------------------");
}
});</programlisting>
</section>
<section>
<title>Example</title>
<para>See <xref linkend="examples.management-notifications"/> for an example which shows
how to use a JMS <literal>MessageListener</literal> to receive management notifications
from ActiveMQ server.</para>
</section>
<section id="notification.types.and.headers">
<title>Notification Types and Headers</title>
<para>Below is a list of all the different kinds of notifications as well as which headers are
on the messages. Every notification has a <literal>_HQ_NotifType</literal> (value noted in parentheses)
and <literal>_HQ_NotifTimestamp</literal> header. The timestamp is the un-formatted result of a call
to <literal>java.lang.System.currentTimeMillis()</literal>.</para>
<itemizedlist>
<listitem>
<para><literal>BINDING_ADDED</literal> (0)</para>
<para><literal>_HQ_Binding_Type</literal>, <literal>_HQ_Address</literal>,
<literal>_HQ_ClusterName</literal>, <literal>_HQ_RoutingName</literal>,
<literal>_HQ_Binding_ID</literal>, <literal>_HQ_Distance</literal>,
<literal>_HQ_FilterString</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>BINDING_REMOVED</literal> (1)</para>
<para><literal>_HQ_Address</literal>, <literal>_HQ_ClusterName</literal>,
<literal>_HQ_RoutingName</literal>, <literal>_HQ_Binding_ID</literal>,
<literal>_HQ_Distance</literal>, <literal>_HQ_FilterString</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>CONSUMER_CREATED</literal> (2)</para>
<para><literal>_HQ_Address</literal>, <literal>_HQ_ClusterName</literal>,
<literal>_HQ_RoutingName</literal>, <literal>_HQ_Distance</literal>,
<literal>_HQ_ConsumerCount</literal>, <literal>_HQ_User</literal>,
<literal>_HQ_RemoteAddress</literal>, <literal>_HQ_SessionName</literal>,
<literal>_HQ_FilterString</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>CONSUMER_CLOSED</literal> (3)</para>
<para><literal>_HQ_Address</literal>, <literal>_HQ_ClusterName</literal>,
<literal>_HQ_RoutingName</literal>, <literal>_HQ_Distance</literal>,
<literal>_HQ_ConsumerCount</literal>, <literal>_HQ_User</literal>,
<literal>_HQ_RemoteAddress</literal>, <literal>_HQ_SessionName</literal>,
<literal>_HQ_FilterString</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>SECURITY_AUTHENTICATION_VIOLATION</literal> (6)</para>
<para><literal>_HQ_User</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>SECURITY_PERMISSION_VIOLATION</literal> (7)</para>
<para><literal>_HQ_Address</literal>, <literal>_HQ_CheckType</literal>,
<literal>_HQ_User</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>DISCOVERY_GROUP_STARTED</literal> (8)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>DISCOVERY_GROUP_STOPPED</literal> (9)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>BROADCAST_GROUP_STARTED</literal> (10)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>BROADCAST_GROUP_STOPPED</literal> (11)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>BRIDGE_STARTED</literal> (12)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>BRIDGE_STOPPED</literal> (13)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>CLUSTER_CONNECTION_STARTED</literal> (14)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>CLUSTER_CONNECTION_STOPPED</literal> (15)</para>
<para><literal>name</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>ACCEPTOR_STARTED</literal> (16)</para>
<para><literal>factory</literal>, <literal>id</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>ACCEPTOR_STOPPED</literal> (17)</para>
<para><literal>factory</literal>, <literal>id</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>PROPOSAL</literal> (18)</para>
<para><literal>_JBM_ProposalGroupId</literal>, <literal>_JBM_ProposalValue</literal>,
<literal>_HQ_Binding_Type</literal>, <literal>_HQ_Address</literal>,
<literal>_HQ_Distance</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>PROPOSAL_RESPONSE</literal> (19)</para>
<para><literal>_JBM_ProposalGroupId</literal>, <literal>_JBM_ProposalValue</literal>,
<literal>_JBM_ProposalAltValue</literal>, <literal>_HQ_Binding_Type</literal>,
<literal>_HQ_Address</literal>, <literal>_HQ_Distance</literal></para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para><literal>CONSUMER_SLOW</literal> (21)</para>
<para><literal>_HQ_Address</literal>, <literal>_HQ_ConsumerCount</literal>,
<literal>_HQ_RemoteAddress</literal>, <literal>_HQ_ConnectionName</literal>,
<literal>_HQ_ConsumerName</literal>, <literal>_HQ_SessionName</literal></para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="management.message-counters">
<title>Message Counters</title>
<para>Message counters can be used to obtain information on queues <emphasis>over
time</emphasis> as ActiveMQ keeps a history on queue metrics.</para>
<para>They can be used to show <emphasis>trends</emphasis> on queues. For example, using the
management API, it would be possible to query the number of messages in a queue at regular
interval. However, this would not be enough to know if the queue is used: the number of
messages can remain constant because nobody is sending or receiving messages from the queue
or because there are as many messages sent to the queue than messages consumed from it. The
number of messages in the queue remains the same in both cases but its use is widely
different.</para>
<para>Message counters gives additional information about the queues:</para>
<itemizedlist>
<listitem>
<para><literal>count</literal></para>
<para>The <emphasis>total</emphasis> number of messages added to the queue since the
server was started</para>
</listitem>
<listitem>
<para><literal>countDelta</literal></para>
<para>the number of messages added to the queue <emphasis>since the last message counter
update</emphasis></para>
</listitem>
<listitem>
<para><literal>messageCount</literal></para>
<para>The <emphasis>current</emphasis> number of messages in the queue</para>
</listitem>
<listitem>
<para><literal>messageCountDelta</literal></para>
<para>The <emphasis>overall</emphasis> number of messages added/removed from the queue
<emphasis>since the last message counter update</emphasis>. For example, if
<literal>messageCountDelta</literal> is equal to <literal>-10</literal> this means that
overall 10 messages have been removed from the queue (e.g. 2 messages were added and
12 were removed)</para>
</listitem>
<listitem>
<para><literal>lastAddTimestamp</literal></para>
<para>The timestamp of the last time a message was added to the queue</para>
</listitem>
<listitem>
<para><literal>udpateTimestamp</literal></para>
<para>The timestamp of the last message counter update</para>
</listitem>
</itemizedlist>
<para>These attributes can be used to determine other meaningful data as well. For example, to know
specifically how many messages were <emphasis>consumed</emphasis> from the queue since the last update
simply subtract the <literal>messageCountDelta</literal> from <literal>countDelta</literal>.</para>
<section id="configuring.message.counters">
<title>Configuring Message Counters</title>
<para>By default, message counters are disabled as it might have a small negative effect on
memory.</para>
<para>To enable message counters, you can set it to <literal>true</literal> in <literal
>activemq-configuration.xml</literal>:</para>
<programlisting>
&lt;message-counter-enabled>true&lt;/message-counter-enabled></programlisting>
<para>Message counters keeps a history of the queue metrics (10 days by default) and
samples all the queues at regular interval (10 seconds by default). If message counters
are enabled, these values should be configured to suit your messaging use case in
<literal>activemq-configuration.xml</literal>:</para>
<programlisting>
&lt;!-- keep history for a week -->
&lt;message-counter-max-day-history>7&lt;/message-counter-max-day-history>
&lt;!-- sample the queues every minute (60000ms) -->
&lt;message-counter-sample-period>60000&lt;/message-counter-sample-period></programlisting>
<para>Message counters can be retrieved using the Management API. For example, to retrieve
message counters on a JMS Queue using JMX:</para>
<programlisting>
// retrieve a connection to ActiveMQ's MBeanServer
MBeanServerConnection mbsc = ...
JMSQueueControlMBean queueControl = (JMSQueueControl)MBeanServerInvocationHandler.newProxyInstance(mbsc,
on,
JMSQueueControl.class,
false);
// message counters are retrieved as a JSON String
String counters = queueControl.listMessageCounter();
// use the MessageCounterInfo helper class to manipulate message counters more easily
MessageCounterInfo messageCounter = MessageCounterInfo.fromJSON(counters);
System.out.format("%s message(s) in the queue (since last sample: %s)\n",
messageCounter.getMessageCount(),
messageCounter.getMessageCountDelta());</programlisting>
</section>
<section>
<title>Example</title>
<para>See <xref linkend="examples.message-counters"/> for an example which shows how to use
message counters to retrieve information on a JMS <literal>Queue</literal>.</para>
</section>
</section>
<section>
<title>Administering ActiveMQ Resources Using The JBoss AS Admin Console</title>
<para>Its possible to create and configure ActiveMQ resources via the admin console within the JBoss Application Server.</para>
<para>The Admin Console will allow you to create destinations (JMS Topics and Queues) and JMS Connection Factories.</para>
<para>Once logged in to the admin console you will see a JMS Manager item in the left hand tree. All ActiveMQ resources
will be configured via this. This will have a child items for JMS Queues, Topics and Connection Factories, clicking
on each node will reveal which resources are currently available. The following sections explain how to create
and configure each resource in turn.</para>
<section>
<title>JMS Queues</title>
<para>To create a new JMS Queue click on the JMS Queues item to reveal the available queues. On the right hand
panel you will see an add a new resource button, click on this and then choose the default(JMS Queue) template
and click continue. The important things to fill in here are the name of the queue and the JNDI name of the
queue. The JNDI name is what you will use to look up the queue in JNDI from your client. For most queues this
will be the only info you will need to provide as sensible defaults are provided for the others. You will also
see a security roles section near the bottom. If you do not provide any roles for this queue then the servers
default security configuration will be used, after you have created the queue these will be shown in the configuration.
All configuration values, except the name and JNDI name, can be changed via the configuration tab after clicking
on the queue in the admin console. The following section explains these in more detail</para>
<para>After highlighting the configuration you will see the following screen</para>
<para>
<graphic fileref="images/console1.png" scalefit="1" width="500" align="center"/>
</para>
<para>The name and JNDI name can't be changed, if you want to change these recreate the queue with the appropriate
settings. The rest of the configuration options, apart from security roles, relate to address settings for a particular
address. The default address settings are picked up from the servers configuration, if you change any of these
settings or create a queue via the console a new Address Settings entry will be added. For a full explanation on
Address Settings see <xref linkend="queue-attributes.address-settings"/></para>
<para>To delete a queue simply click on the delete button beside the queue name in the main JMS Queues screen.
This will also delete any address settings or security settings previously created for the queues address</para>
<para>The last part of the configuration options are security roles. If non are provided on creation then the
servers default security settings will be shown. If these are changed or updated then new security settings are
created for the address of this queue. For more information on security setting see <xref linkend="security"/> </para>
<para>It is also possible via the metrics tab to view statistics for this queue. This will show statistics such
as message count, consumer count etc.</para>
<para>Operations can be performed on a queue via the control tab. This will allow you to start and stop the queue,
list,move,expire and delete messages from the queue and other useful operations. To invoke an operation click on
the button for the operation you want, this will take you to a screen where you can parameters for the operation can be set.
Once set clicking the ok button will invoke the operation, results appear at the bottom of the screen.</para>
</section>
<section>
<title>JMS Topics</title>
<para>Creating and configuring JMS Topics is almost identical to creating queues. The only difference is that the
configuration will be applied to the queue representing a subscription.</para>
</section>
<section>
<title>JMS Connection Factories</title>
<para>The format for creating connection factories is the same as for JMS Queues and topics apart from the configuration
being different. For as list of all the connection factory settings see the configuration index </para>
</section>
</section>
</chapter>