activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clebertsuco...@apache.org
Subject [06/25] activemq-6 git commit: ACTIVEMQ6-9 - port to markdown
Date Mon, 08 Dec 2014 15:49:37 GMT
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/queue-attributes.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/queue-attributes.md b/docs/user-manual/en/queue-attributes.md
new file mode 100644
index 0000000..d2dafa5
--- /dev/null
+++ b/docs/user-manual/en/queue-attributes.md
@@ -0,0 +1,182 @@
+Queue Attributes
+================
+
+Queue attributes can be set in one of two ways. Either by configuring
+them using the configuration file or by using the core API. This chapter
+will explain how to configure each attribute and what effect the
+attribute has.
+
+Predefined Queues
+=================
+
+Queues can be predefined via configuration at a core level or at a JMS
+level. Firstly let's look at a JMS level.
+
+The following shows a queue predefined in the `activemq-jms.xml`
+configuration file.
+
+    <queue name="selectorQueue">
+       <entry name="/queue/selectorQueue"/>
+       <selector string="color='red'"/>
+       <durable>true</durable>
+    </queue>
+
+This name attribute of queue defines the name of the queue. When we do
+this at a jms level we follow a naming convention so the actual name of
+the core queue will be `jms.queue.selectorQueue`.
+
+The entry element configures the name that will be used to bind the
+queue to JNDI. This is a mandatory element and the queue can contain
+multiple of these to bind the same queue to different names.
+
+The selector element defines what JMS message selector the predefined
+queue will have. Only messages that match the selector will be added to
+the queue. This is an optional element with a default of null when
+omitted.
+
+The durable element specifies whether the queue will be persisted. This
+again is optional and defaults to true if omitted.
+
+Secondly a queue can be predefined at a core level in the
+`activemq-configuration.xml` file. The following is an example.
+
+    <queues>
+       <queue name="jms.queue.selectorQueue">
+          <address>jms.queue.selectorQueue</address>
+          <filter string="color='red'"/>
+          <durable>true</durable>
+        </queue>
+    </queues>
+
+This is very similar to the JMS configuration, with 3 real differences
+which are.
+
+1.  The name attribute of queue is the actual name used for the queue
+    with no naming convention as in JMS.
+
+2.  The address element defines what address is used for routing
+    messages.
+
+3.  There is no entry element.
+
+4.  The filter uses the *Core filter syntax* (described in ?), *not* the
+    JMS selector syntax.
+
+Using the API
+=============
+
+Queues can also be created using the core API or the management API.
+
+For the core API, queues can be created via the
+`org.apache.activemq.api.core.client.ClientSession` interface. There are
+multiple `createQueue` methods that support setting all of the
+previously mentioned attributes. There is one extra attribute that can
+be set via this API which is `temporary`. setting this to true means
+that the queue will be deleted once the session is disconnected.
+
+Take a look at ? for a description of the management API for creating
+queues.
+
+Configuring Queues Via Address Settings
+=======================================
+
+There are some attributes that are defined against an address wildcard
+rather than a specific queue. Here an example of an `address-setting`
+entry that would be found in the `activemq-configuration.xml` file.
+
+    <address-settings>
+       <address-setting match="jms.queue.exampleQueue">
+          <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
+          <max-delivery-attempts>3</max-delivery-attempts>
+          <redelivery-delay>5000</redelivery-delay>
+          <expiry-address>jms.queue.expiryQueue</expiry-address>
+          <last-value-queue>true</last-value-queue>
+          <max-size-bytes>100000</max-size-bytes>
+          <page-size-bytes>20000</page-size-bytes>
+          <redistribution-delay>0</redistribution-delay>
+          <send-to-dla-on-no-route>true</send-to-dla-on-no-route>
+          <address-full-policy>PAGE</address-full-policy>
+          <slow-consumer-threshold>-1</slow-consumer-threshold>
+          <slow-consumer-policy>NOTIFY</slow-consumer-policy>
+          <slow-consumer-check-period>5</slow-consumer-check-period>
+       </address-setting>
+    </address-settings>
+
+The idea with address settings, is you can provide a block of settings
+which will be applied against any addresses that match the string in the
+`match` attribute. In the above example the settings would only be
+applied to any addresses which exactly match the address
+`jms.queue.exampleQueue`, but you can also use wildcards to apply sets
+of configuration against many addresses. The wildcard syntax used is
+described [here](#wildcard-syntax).
+
+For example, if you used the `match` string `jms.queue.#` the settings
+would be applied to all addresses which start with `jms.queue.` which
+would be all JMS queues.
+
+The meaning of the specific settings are explained fully throughout the
+user manual, however here is a brief description with a link to the
+appropriate chapter if available.
+
+`max-delivery-attempts` defines how many time a cancelled message can be
+redelivered before sending to the `dead-letter-address`. A full
+explanation can be found [here](#undelivered-messages.configuring).
+
+`redelivery-delay` defines how long to wait before attempting redelivery
+of a cancelled message. see [here](#undelivered-messages.delay).
+
+`expiry-address` defines where to send a message that has expired. see
+[here](#message-expiry.configuring).
+
+`expiry-delay` defines the expiration time that will be used for
+messages which are using the default expiration time (i.e. 0). For
+example, if `expiry-delay` is set to "10" and a message which is using
+the default expiration time (i.e. 0) arrives then its expiration time of
+"0" will be changed to "10." However, if a message which is using an
+expiration time of "20" arrives then its expiration time will remain
+unchanged. Setting `expiry-delay` to "-1" will disable this feature. The
+default is "-1".
+
+`last-value-queue` defines whether a queue only uses last values or not.
+see [here](#last-value-queues).
+
+`max-size-bytes` and `page-size-bytes` are used to set paging on an
+address. This is explained [here](#paging).
+
+`redistribution-delay` defines how long to wait when the last consumer
+is closed on a queue before redistributing any messages. see
+[here](#clusters).
+
+`send-to-dla-on-no-route`. If a message is sent to an address, but the
+server does not route it to any queues, for example, there might be no
+queues bound to that address, or none of the queues have filters that
+match, then normally that message would be discarded. However if this
+parameter is set to true for that address, if the message is not routed
+to any queues it will instead be sent to the dead letter address (DLA)
+for that address, if it exists.
+
+`address-full-policy`. This attribute can have one of the following
+values: PAGE, DROP, FAIL or BLOCK and determines what happens when an
+address where `max-size-bytes` is specified becomes full. The default
+value is PAGE. If the value is PAGE then further messages will be paged
+to disk. If the value is DROP then further messages will be silently
+dropped. If the value is FAIL then further messages will be dropped and
+an exception will be thrown on the client-side. If the value is BLOCK
+then client message producers will block when they try and send further
+messages. See the following chapters for more info ?, ?.
+
+`slow-consumer-threshold`. The minimum rate of message consumption
+allowed before a consumer is considered "slow." Measured in
+messages-per-second. Default is -1 (i.e. disabled); any other valid
+value must be greater than 0.
+
+`slow-consumer-policy`. What should happen when a slow consumer is
+detected. `KILL` will kill the consumer's connection (which will
+obviously impact any other client threads using that same connection).
+`NOTIFY` will send a CONSUMER\_SLOW management notification which an
+application could receive and take action with. See ? for more details
+on this notification.
+
+`slow-consumer-check-period`. How often to check for slow consumers on a
+particular queue. Measured in minutes. Default is 5. See ? for more
+information about slow consumer detection.

http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/queue-attributes.xml
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/queue-attributes.xml b/docs/user-manual/en/queue-attributes.xml
deleted file mode 100644
index b6245ed..0000000
--- a/docs/user-manual/en/queue-attributes.xml
+++ /dev/null
@@ -1,171 +0,0 @@
-<?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="queue-attributes">
-    <title>Queue Attributes</title>
-    <para>Queue attributes can be set in one of two ways. Either by configuring them using the
-        configuration file or by using the core API. This chapter will explain how to configure each
-        attribute and what effect the attribute has.</para>
-    <section id="predefined.queues">
-        <title>Predefined Queues</title>
-        <para>Queues can be predefined via configuration at a core level or at a JMS level. Firstly
-            let's look at a JMS level.</para>
-        <para>The following shows a queue predefined in the <literal>activemq-jms.xml</literal>
-            configuration file.</para>
-        <programlisting>
-&lt;queue name="selectorQueue">
-   &lt;entry name="/queue/selectorQueue"/>
-   &lt;selector string="color='red'"/>
-   &lt;durable>true&lt;/durable>
-&lt;/queue></programlisting>
-        <para>This name attribute of queue defines the name of the queue. When we do this at a jms
-            level we follow a naming convention so the actual name of the core queue will be
-                <literal>jms.queue.selectorQueue</literal>.</para>
-        <para>The entry element configures the name that will be used to bind the queue to JNDI.
-            This is a mandatory element and the queue can contain multiple of these to bind the same
-            queue to different names.</para>
-        <para>The selector element defines what JMS message selector the predefined queue will have.
-            Only messages that match the selector will be added to the queue. This is an optional
-            element with a default of null when omitted.</para>
-        <para>The durable element specifies whether the queue will be persisted. This again is
-            optional and defaults to true if omitted.</para>
-        <para>Secondly a queue can be predefined at a core level in the <literal
-                >activemq-configuration.xml</literal> file. The following is an example.</para>
-        <programlisting>
-&lt;queues>
-   &lt;queue name="jms.queue.selectorQueue">
-      &lt;address>jms.queue.selectorQueue&lt;/address>
-      &lt;filter string="color='red'"/>
-      &lt;durable>true&lt;/durable>
-    &lt;/queue>
-&lt;/queues></programlisting>
-        <para>This is very similar to the JMS configuration, with 3 real differences which
-            are.</para>
-        <orderedlist>
-            <listitem>
-                <para>The name attribute of queue is the actual name used for the queue with no
-                    naming convention as in JMS.</para>
-            </listitem>
-            <listitem>
-                <para>The address element defines what address is used for routing messages.</para>
-            </listitem>
-            <listitem>
-                <para>There is no entry element.</para>
-            </listitem>
-            <listitem>
-                <para>The filter uses the <emphasis>Core filter syntax</emphasis> (described in
-                        <xref linkend="filter-expressions"/>), <emphasis>not</emphasis> the JMS
-                    selector syntax.</para>
-            </listitem>
-        </orderedlist>
-    </section>
-    <section>
-        <title>Using the API</title>
-        <para>Queues can also be created using the core API or the management API.</para>
-        <para>For the core API, queues can be created via the <literal
-                >org.apache.activemq.api.core.client.ClientSession</literal> interface. There are multiple
-                <literal>createQueue</literal> methods that support setting all of the previously
-            mentioned attributes. There is one extra attribute that can be set via this API which is
-                <literal>temporary</literal>. setting this to true means that the queue will be
-            deleted once the session is disconnected.</para>
-        <para>Take a look at <xref linkend="management"/> for a description of the management API
-            for creating queues.</para>
-    </section>
-    <section id="queue-attributes.address-settings">
-        <title>Configuring Queues Via Address Settings</title>
-        <para>There are some attributes that are defined against an address wildcard rather than a
-            specific queue. Here an example of an <literal>address-setting</literal> entry that
-            would be found in the <literal>activemq-configuration.xml</literal> file.</para>
-        <programlisting>
-&lt;address-settings>
-   &lt;address-setting match="jms.queue.exampleQueue">
-      &lt;dead-letter-address>jms.queue.deadLetterQueue&lt;/dead-letter-address>
-      &lt;max-delivery-attempts>3&lt;/max-delivery-attempts>
-      &lt;redelivery-delay>5000&lt;/redelivery-delay>
-      &lt;expiry-address>jms.queue.expiryQueue&lt;/expiry-address>
-      &lt;last-value-queue>true&lt;/last-value-queue>
-      &lt;max-size-bytes>100000&lt;/max-size-bytes>
-      &lt;page-size-bytes>20000&lt;/page-size-bytes>
-      &lt;redistribution-delay>0&lt;/redistribution-delay>
-      &lt;send-to-dla-on-no-route>true&lt;/send-to-dla-on-no-route>
-      &lt;address-full-policy>PAGE&lt;/address-full-policy>
-      &lt;slow-consumer-threshold>-1&lt;/slow-consumer-threshold>
-      &lt;slow-consumer-policy>NOTIFY&lt;/slow-consumer-policy>
-      &lt;slow-consumer-check-period>5&lt;/slow-consumer-check-period>
-   &lt;/address-setting>
-&lt;/address-settings></programlisting>
-        <para>The idea with address settings, is you can provide a block of settings which will be
-            applied against any addresses that match the string in the <literal>match</literal> attribute. In the
-            above example the settings would only be applied to any addresses which exactly match
-            the address <literal>jms.queue.exampleQueue</literal>, but you can also use wildcards to apply sets of
-            configuration against many addresses. The wildcard syntax used is described <link linkend="wildcard-syntax">here</link>.</para>
-        <para>For example, if you used the <literal>match</literal> string <literal>jms.queue.#</literal> the settings would be applied
-        to all addresses which start with <literal>jms.queue.</literal> which would be all JMS queues.</para>
-        <para>The meaning of the specific settings are explained fully throughout the user manual, however here is a brief
-            description with a link to the appropriate chapter if available. </para>
-        <para><literal>max-delivery-attempts</literal> defines how many time a cancelled message can
-            be redelivered before sending to the <literal>dead-letter-address</literal>. A full
-            explanation can be found <link linkend="undelivered-messages.configuring"
-            >here</link>.</para>
-        <para><literal>redelivery-delay</literal> defines how long to wait before attempting
-            redelivery of a cancelled message. see <link linkend="undelivered-messages.delay"
-                >here</link>.</para>
-        <para><literal>expiry-address</literal> defines where to send a message that has expired.
-            see <link linkend="message-expiry.configuring">here</link>.</para>
-        <para><literal>expiry-delay</literal> defines the expiration time that will be used for messages which are using
-            the default expiration time (i.e. 0). For example, if <literal>expiry-delay</literal> is set to "10" and a
-            message which is using the default expiration time (i.e. 0) arrives then its expiration time of "0" will be
-            changed to "10." However, if a message which is using an expiration time of "20" arrives then its expiration
-            time will remain unchanged. Setting <literal>expiry-delay</literal> to "-1" will disable this feature. The
-            default is "-1".</para>
-        <para><literal>last-value-queue</literal> defines whether a queue only uses last values or
-            not. see <link linkend="last-value-queues">here</link>.</para>
-        <para><literal>max-size-bytes</literal> and <literal>page-size-bytes</literal> are used to
-            set paging on an address. This is explained <link linkend="paging">here</link>.</para>
-        <para><literal>redistribution-delay</literal> defines how long to wait when the last
-            consumer is closed on a queue before redistributing any messages. see <link
-                linkend="clusters">here</link>.</para>
-        <para><literal>send-to-dla-on-no-route</literal>. If a message is sent to an address, but the server does not route it to any queues,
-        for example, there might be no queues bound to that address, or none of the queues have filters that match, then normally that message
-        would be discarded. However if this parameter is set to true for that address, if the message is not routed to any queues it will instead
-        be sent to the dead letter address (DLA) for that address, if it exists.</para>
-        <para><literal>address-full-policy</literal>. This attribute can have one of the following values: PAGE, DROP, FAIL or BLOCK and determines what happens when
-            an address where <literal>max-size-bytes</literal> is specified becomes full. The default value is PAGE. If the value is PAGE then further messages will be paged to disk.
-            If the value is DROP then further messages will be silently dropped.
-            If the value is FAIL then further messages will be dropped and an exception will be thrown on the client-side.
-            If the value is BLOCK then client message producers will block when they try and send further messages.
-        
-        See the following chapters for more info <xref linkend="flow-control"/>, <xref linkend="paging"/>.
-        </para>
-       <para><literal>slow-consumer-threshold</literal>. The minimum rate of message consumption allowed before a
-          consumer is considered "slow." Measured in messages-per-second. Default is -1 (i.e. disabled); any other valid
-          value must be greater than 0.</para>
-       <para><literal>slow-consumer-policy</literal>. What should happen when a slow consumer is detected.
-          <literal>KILL</literal> will kill the consumer's connection (which will obviously impact any other client
-          threads using that same connection). <literal>NOTIFY</literal> will send a CONSUMER_SLOW management
-          notification which an application could receive and take action with. See
-          <xref linkend="notification.types.and.headers"/> for more details on this notification.</para>
-       <para><literal>slow-consumer-check-period</literal>. How often to check for slow consumers on a particular queue.
-          Measured in minutes. Default is 5. See <xref linkend="slow-consumers"/> for more information about slow
-          consumer detection.</para>
-    </section>
-</chapter>

http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/rest.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/rest.md b/docs/user-manual/en/rest.md
new file mode 100644
index 0000000..c48ffc1
--- /dev/null
+++ b/docs/user-manual/en/rest.md
@@ -0,0 +1,1570 @@
+REST Interface
+==============
+
+The ActiveMQ REST interface allows you to leverage the reliability and
+scalability features of ActiveMQ over a simple REST/HTTP interface.
+Messages are produced and consumed by sending and receiving simple HTTP
+messages that contain the content you want to push around. For instance,
+here's a simple example of posting an order to an order processing queue
+express as an HTTP message:
+
+    POST /queue/orders/create HTTP/1.1
+    Host: example.com
+    Content-Type: application/xml
+
+    <order>
+       <name>Bill</name>
+       <item>iPhone 4</item>
+       <cost>$199.99</cost>
+    </order>
+
+As you can see, we're just posting some arbitrary XML document to a URL.
+When the XML is received on the server is it processed within ActiveMQ
+as a JMS message and distributed through core ActiveMQ. Simple and easy.
+Consuming messages from a queue or topic looks very similar. We'll
+discuss the entire interface in detail later in this docbook.
+
+Goals of REST Interface
+=======================
+
+Why would you want to use ActiveMQ's REST interface? What are the goals
+of the REST interface?
+
+-   Easily usable by machine-based (code) clients.
+
+-   Zero client footprint. We want ActiveMQ to be usable by any
+    client/programming language that has an adequate HTTP client
+    library. You shouldn't have to download, install, and configure a
+    special library to interact with ActiveMQ.
+
+-   Lightweight interoperability. The HTTP protocol is strong enough to
+    be our message exchange protocol. Since interactions are RESTful the
+    HTTP uniform interface provides all the interoperability you need to
+    communicate between different languages, platforms, and even
+    messaging implementations that choose to implement the same RESTful
+    interface as ActiveMQ (i.e. the [REST-\*](http://rest-star.org)
+    effort.)
+
+-   No envelope (e.g. SOAP) or feed (e.g. Atom) format requirements. You
+    shouldn't have to learn, use, or parse a specific XML document
+    format in order to send and receive messages through ActiveMQ's REST
+    interface.
+
+-   Leverage the reliability, scalability, and clustering features of
+    ActiveMQ on the back end without sacrificing the simplicity of a
+    REST interface.
+
+Installation and Configuration
+==============================
+
+ActiveMQ's REST interface is installed as a Web archive (WAR). It
+depends on the [RESTEasy](http://jboss.org/resteasy) project and can
+currently only run within a servlet container. Installing the ActiveMQ
+REST interface is a little bit different depending whether ActiveMQ is
+already installed and configured for your environment (e.g. you're
+deploying within JBoss AS 7) or you want the ActiveMQ REST WAR to
+startup and manage the ActiveMQ server (e.g. you're deploying within
+something like Apache Tomcat).
+
+Installing Within Pre-configured Environment
+--------------------------------------------
+
+This section should be used when you want to use the ActiveMQ REST
+interface in an environment that already has ActiveMQ installed and
+running, e.g. JBoss AS 7. You must create a Web archive (.WAR) file with
+the following web.xml settings:
+
+    <web-app>
+       <listener>
+          <listener-class>
+             org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
+          </listener-class>
+       </listener>
+
+       <listener>
+          <listener-class>
+             org.apache.activemq.rest.integration.RestMessagingBootstrapListener
+          </listener-class>
+       </listener>
+
+       <filter>
+          <filter-name>Rest-Messaging</filter-name>
+          <filter-class>
+             org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
+          </filter-class>
+       </filter>
+
+       <filter-mapping>
+          <filter-name>Rest-Messaging</filter-name>
+          <url-pattern>/*</url-pattern>
+       </filter-mapping>
+    </web-app>
+
+Within your WEB-INF/lib directory you must have the activemq-rest.jar
+file. If RESTEasy is not installed within your environment, you must add
+the RESTEasy jar files within the lib directory as well. Here's a sample
+Maven pom.xml that can build your WAR for this case.
+
+    <project xmlns="http://maven.apache.org/POM/4.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.somebody</groupId>
+       <artifactId>myapp</artifactId>
+       <packaging>war</packaging>
+       <name>My App</name>
+       <version>0.1-SNAPSHOT</version>
+       <repositories>
+          <repository>
+             <id>jboss</id>
+             <url>http://repository.jboss.org/nexus/content/groups/public/</url>
+          </repository>
+       </repositories>
+
+       <build>
+          <plugins>
+             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                   <source>1.6</source>
+                   <target>1.6</target>
+                </configuration>
+             </plugin>
+          </plugins>
+       </build>
+
+       <dependencies>
+          <dependency>
+             <groupId>org.apache.activemq.rest</groupId>
+             <artifactId>activemq-rest</artifactId>
+             <version>2.3.0-SNAPSHOT</version>
+          </dependency>
+       </dependencies>
+    </project>
+
+> **Note**
+>
+> JBoss AS 7 loads classes differently than previous versions. To work
+> properly in AS 7 the WAR will need this in its MANIFEST.MF:
+>
+>     Dependencies: org.apache.activemq, org.jboss.netty
+>
+> You can add this to the`<plugins>` section of the pom.xml to create
+> this entry automatically:
+>
+>     <plugin>
+>        <groupId>org.apache.maven.plugins</groupId>
+>        <artifactId>maven-war-plugin</artifactId>
+>        <configuration>
+>           <archive>
+>              <manifestEntries>
+>                 <Dependencies>org.apache.activemq, org.jboss.netty</Dependencies>
+>              </manifestEntries>
+>           </archive>
+>        </configuration>
+>     </plugin>
+
+It is worth noting that when deploying a WAR in a Java EE application
+server like AS7 the URL for the resulting application will include the
+name of the WAR by default. For example, if you've constructed a WAR as
+described above named "activemq-rest.war" then clients will access it
+at, e.g. http://localhost:8080/activemq-rest/[queues|topics]. We'll see
+more about this later.
+
+> **Note**
+>
+> It is possible to put the WAR file at the "root context" of AS7, but
+> that is beyond the scope of this documentation.
+
+Bootstrapping ActiveMQ Along with REST
+--------------------------------------
+
+You can bootstrap ActiveMQ within your WAR as well. To do this, you must
+have the ActiveMQ core and JMS jars along with Netty, Resteasy, and the
+ActiveMQ REST jar within your WEB-INF/lib. You must also have a
+activemq-configuration.xml, activemq-jms.xml, and activemq-users.xml
+config files within WEB-INF/classes. The examples that come with the
+ActiveMQ REST distribution show how to do this. You must also add an
+additional listener to your web.xml file. Here's an example:
+
+    <web-app>
+       <listener>
+          <listener-class>
+             org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
+          </listener-class>
+       </listener>
+
+       <listener>
+          <listener-class>
+             org.apache.activemq.rest.integration.ActiveMQBootstrapListener
+          </listener-class>
+       </listener>
+
+       <listener>
+          <listener-class>
+             org.apache.activemq.rest.integration.RestMessagingBootstrapListener
+          </listener-class>
+       </listener>
+
+       <filter>
+          <filter-name>Rest-Messaging</filter-name>
+          <filter-class>
+             org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
+          </filter-class>
+       </filter>
+
+       <filter-mapping>
+          <filter-name>Rest-Messaging</filter-name>
+          <url-pattern>/*</url-pattern>
+       </filter-mapping>
+    </web-app>
+
+Here's a Maven pom.xml file for creating a WAR for this environment.
+Make sure your activemq configuration files are within the
+src/main/resources directory so that they are stuffed within the WAR's
+WEB-INF/classes directory!
+
+    <project xmlns="http://maven.apache.org/POM/4.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.somebody</groupId>
+       <artifactId>myapp</artifactId>
+       <packaging>war</packaging>
+       <name>My App</name>
+       <version>0.1-SNAPSHOT</version>
+       <repositories>
+          <repository>
+             <id>jboss</id>
+             <url>http://repository.jboss.org/nexus/content/groups/public/</url>
+          </repository>
+       </repositories>
+       <build>
+          <plugins>
+             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                   <source>1.6</source>
+                   <target>1.6</target>
+                </configuration>
+             </plugin>
+          </plugins>
+       </build>
+       <dependencies>
+          <dependency>
+             <groupId>org.apache.activemq</groupId>
+             <artifactId>activemq-core</artifactId>
+             <version>2.3.0-SNAPSHOT</version>
+          </dependency>
+          <dependency>
+             <groupId>io.netty</groupId>
+             <artifactId>netty</artifactId>
+             <version>3.4.5.Final</version>
+          </dependency>
+          <dependency>
+             <groupId>org.apache.activemq</groupId>
+             <artifactId>activemq-jms</artifactId>
+             <version>2.3.0-SNAPSHOT</version>
+          </dependency>
+          <dependency>
+             <groupId>org.jboss.spec.javax.jms</groupId>
+             <artifactId>jboss-jms-api_2.0_spec</artifactId>
+             <version>1.0.0.Final</version>
+          </dependency>
+          <dependency>
+             <groupId>org.apache.activemq.rest</groupId>
+             <artifactId>activemq-rest</artifactId>
+             <version>2.3.0-SNAPSHOT</version>
+          </dependency>
+          <dependency>
+             <groupId>org.jboss.resteasy</groupId>
+             <artifactId>resteasy-jaxrs</artifactId>
+             <version>2.3.4.Final</version>
+          </dependency>
+          <dependency>
+             <groupId>org.jboss.resteasy</groupId>
+             <artifactId>resteasy-jaxb-provider</artifactId>
+             <version>2.3.4.Final</version>
+          </dependency>
+       </dependencies>
+    </project>
+
+REST Configuration
+------------------
+
+The ActiveMQ REST implementation does have some configuration options.
+These are configured via XML configuration file that must be in your
+WEB-INF/classes directory. You must set the web.xml context-param
+`rest.messaging.config.file` to specify the name of the configuration
+file. Below is the format of the XML configuration file and the default
+values for each.
+
+    <rest-messaging>
+       <server-in-vm-id>0</server-in-vm-id>
+       <use-link-headers>false</use-link-headers>
+       <default-durable-send>false</default-durable-send>
+       <dups-ok>true</dups-ok>
+       <topic-push-store-dir>topic-push-store</topic-push-store-dir>
+       <queue-push-store-dir>queue-push-store</queue-push-store-dir>
+       <producer-time-to-live>0</producer-time-to-live>
+       <producer-session-pool-size>10</producer-session-pool-size>
+       <session-timeout-task-interval>1</session-timeout-task-interval>
+       <consumer-session-timeout-seconds>300</consumer-session-timeout-seconds>
+       <consumer-window-size>-1</consumer-window-size>
+    </rest-messaging>
+
+Let's give an explanation of each config option.
+
+-   `server-in-vm-id`. The ActiveMQ REST impl uses the IN-VM transport
+    to communicate with ActiveMQ. It uses the default server id, which
+    is "0".
+
+-   `use-link-headers`. By default, all links (URLs) are published using
+    custom headers. You can instead have the ActiveMQ REST
+    implementation publish links using the [Link Header
+    specification](http://tools.ietf.org/html/draft-nottingham-http-link-header-10)
+    instead if you desire.
+
+-   `default-durable-send`. Whether a posted message should be persisted
+    by default if the user does not specify a durable query parameter.
+
+-   `dups-ok`. If this is true, no duplicate detection protocol will be
+    enforced for message posting.
+
+-   `topic-push-store-dir`. This must be a relative or absolute file
+    system path. This is a directory where push registrations for topics
+    are stored. See [Pushing Messages](#message-push).
+
+-   `queue-push-store-dir`. This must be a relative or absolute file
+    system path. This is a directory where push registrations for queues
+    are stored. See [Pushing Messages](#message-push).
+
+-   `producer-session-pool-size`. The REST implementation pools ActiveMQ
+    sessions for sending messages. This is the size of the pool. That
+    number of sessions will be created at startup time.
+
+-   `producer-time-to-live`. Default time to live for posted messages.
+    Default is no ttl.
+
+-   `session-timeout-task-interval`. Pull consumers and pull
+    subscriptions can time out. This is the interval the thread that
+    checks for timed-out sessions will run at. A value of 1 means it
+    will run every 1 second.
+
+-   `consumer-session-timeout-seconds`. Timeout in seconds for pull
+    consumers/subscriptions that remain idle for that amount of time.
+
+-   `consumer-window-size`. For consumers, this config option is the
+    same as the ActiveMQ one of the same name. It will be used by
+    sessions created by the ActiveMQ REST implementation.
+
+ActiveMQ REST Interface Basics
+==============================
+
+The ActiveMQ REST interface publishes a variety of REST resources to
+perform various tasks on a queue or topic. Only the top-level queue and
+topic URI schemes are published to the outside world. You must discover
+all over resources to interact with by looking for and traversing links.
+You'll find published links within custom response headers and embedded
+in published XML representations. Let's look at how this works.
+
+Queue and Topic Resources
+-------------------------
+
+To interact with a queue or topic you do a HEAD or GET request on the
+following relative URI pattern:
+
+    /queues/{name}
+    /topics/{name}
+
+The base of the URI is the base URL of the WAR you deployed the ActiveMQ
+REST server within as defined in the [Installation and
+Configuration](#install) section of this document. Replace the `{name}`
+string within the above URI pattern with the name of the queue or topic
+you are interested in interacting with. For example if you have
+configured a JMS topic named "foo" within your `activemq-jms.xml` file,
+the URI name should be "jms.topic.foo". If you have configured a JMS
+queue name "bar" within your `activemq-jms.xml` file, the URI name
+should be "jms.queue.bar". Internally, ActiveMQ prepends the "jms.topic"
+or "jms.queue" strings to the name of the deployed destination. Next,
+perform your HEAD or GET request on this URI. Here's what a
+request/response would look like.
+
+    HEAD /queues/jms.queue.bar HTTP/1.1
+    Host: example.com
+
+    --- Response ---
+    HTTP/1.1 200 Ok
+    msg-create: http://example.com/queues/jms.queue.bar/create
+    msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}
+    msg-pull-consumers: http://example.com/queues/jms.queue.bar/pull-consumers
+    msg-push-consumers: http://example.com/queues/jms.queue.bar/push-consumers
+
+> **Note**
+>
+> You can use the "curl" utility to test this easily. Simply execute a
+> command like this:
+>
+>     curl --head http://example.com/queues/jms.queue.bar
+
+The HEAD or GET response contains a number of custom response headers
+that are URLs to additional REST resources that allow you to interact
+with the queue or topic in different ways. It is important not to rely
+on the scheme of the URLs returned within these headers as they are an
+implementation detail. Treat them as opaque and query for them each and
+every time you initially interact (at boot time) with the server. If you
+treat all URLs as opaque then you will be isolated from implementation
+changes as the ActiveMQ REST interface evolves over time.
+
+Queue Resource Response Headers
+-------------------------------
+
+Below is a list of response headers you should expect when interacting
+with a Queue resource.
+
+-   `msg-create`. This is a URL you POST messages to. The semantics of
+    this link are described in [Posting Messages](#posting-messages).
+
+-   `msg-create-with-id`. This is a URL *template* you can use to POST
+    messages. The semantics of this link are described in [Posting
+    Messages](#posting-messages).
+
+-   `msg-pull-consumers`. This is a URL for creating consumers that will
+    pull from a queue. The semantics of this link are described in
+    [Consuming Messages via Pull](#message-pull).
+
+-   `msg-push-consumers`. This is a URL for registering other URLs you
+    want the ActiveMQ REST server to push messages to. The semantics of
+    this link are described in [Pushing Messages](#message-push).
+
+Topic Resource Response Headers
+-------------------------------
+
+Below is a list of response headers you should expect when interacting
+with a Topic resource.
+
+-   `msg-create`. This is a URL you POST messages to. The semantics of
+    this link are described in [Posting Messages](#posting-messages).
+
+-   `msg-create-with-id`. This is a URL *template* you can use to POST
+    messages. The semantics of this link are described in [Posting
+    Messages](#posting-messages).
+
+-   `msg-pull-subscriptions`. This is a URL for creating subscribers
+    that will pull from a topic. The semantics of this link are
+    described in [Consuming Messages via Pull](#message-pull).
+
+-   `msg-push-subscriptions`. This is a URL for registering other URLs
+    you want the ActiveMQ REST server to push messages to. The semantics
+    of this link are described in [Pushing Messages](#message-push).
+
+Posting Messages
+================
+
+This chapter discusses the protocol for posting messages to a queue or a
+topic. In [ActiveMQ REST Interface Basics](#basics), you saw that a
+queue or topic resource publishes variable custom headers that are links
+to other RESTful resources. The `msg-create` header is a URL you can
+post a message to. Messages are published to a queue or topic by sending
+a simple HTTP message to the URL published by the `msg-create` header.
+The HTTP message contains whatever content you want to publish to the
+ActiveMQ destination. Here's an example scenario:
+
+> **Note**
+>
+> You can also post messages to the URL template found in
+> `msg-create-with-id`, but this is a more advanced use-case involving
+> duplicate detection that we will discuss later in this section.
+
+1.  Obtain the starting `msg-create` header from the queue or topic
+    resource.
+
+        HEAD /queues/jms.queue.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/queues/jms.queue.bar/create
+        msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}
+
+2.  Do a POST to the URL contained in the `msg-create` header.
+
+        POST /queues/jms.queue.bar/create
+        Host: example.com
+        Content-Type: application/xml
+
+        <order>
+           <name>Bill</name>
+           <item>iPhone4</name>
+           <cost>$199.99</cost>
+        </order>
+
+        --- Response ---
+        HTTP/1.1 201 Created
+        msg-create-next: http://example.com/queues/jms.queue.bar/create
+
+    > **Note**
+    >
+    > You can use the "curl" utility to test this easily. Simply execute
+    > a command like this:
+    >
+    >     curl --verbose --data "123" http://example.com/queues/jms.queue.bar/create
+
+    A successful response will return a 201 response code. Also notice
+    that a `msg-create-next` response header is sent as well. You must
+    use this URL to POST your next message.
+
+3.  POST your next message to the queue using the URL returned in the
+    `msg-create-next` header.
+
+        POST /queues/jms.queue.bar/create
+        Host: example.com
+        Content-Type: application/xml
+
+        <order>
+           <name>Monica</name>
+           <item>iPad</item>
+           <cost>$499.99</cost>
+        </order>
+
+        --- Response --
+        HTTP/1.1 201 Created
+        msg-create-next: http://example.com/queues/jms.queue.bar/create
+
+    Continue using the new `msg-create-next` header returned with each
+    response.
+
+> **Warning**
+>
+> It is *VERY IMPORTANT* that you never re-use returned
+> `msg-create-next` headers to post new messages. If the `dups-ok`
+> configuration property is set to `false` on the server then this URL
+> will be uniquely generated for each message and used for duplicate
+> detection. If you lose the URL within the `msg-create-next` header,
+> then just go back to the queue or topic resource to get the
+> `msg-create` URL again.
+
+Duplicate Detection
+-------------------
+
+Sometimes you might have network problems when posting new messages to a
+queue or topic. You may do a POST and never receive a response.
+Unfortunately, you don't know whether or not the server received the
+message and so a re-post of the message might cause duplicates to be
+posted to the queue or topic. By default, the ActiveMQ REST interface is
+configured to accept and post duplicate messages. You can change this by
+turning on duplicate message detection by setting the `dups-ok` config
+option to `false` as described in [ActiveMQ REST Interface
+Basics](#basics). When you do this, the initial POST to the `msg-create`
+URL will redirect you, using the standard HTTP 307 redirection mechanism
+to a unique URL to POST to. All other interactions remain the same as
+discussed earlier. Here's an example:
+
+1.  Obtain the starting `msg-create` header from the queue or topic
+    resource.
+
+        HEAD /queues/jms.queue.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/queues/jms.queue.bar/create
+        msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}
+
+2.  Do a POST to the URL contained in the `msg-create` header.
+
+        POST /queues/jms.queue.bar/create
+        Host: example.com
+        Content-Type: application/xml
+
+        <order>
+           <name>Bill</name>
+           <item>iPhone4</name>
+           <cost>$199.99</cost>
+        </order>
+
+        --- Response ---
+        HTTP/1.1 307 Redirect
+        Location: http://example.com/queues/jms.queue.bar/create/13582001787372
+
+    A successful response will return a 307 response code. This is
+    standard HTTP protocol. It is telling you that you must re-POST to
+    the URL contained within the `Location` header.
+
+3.  re-POST your message to the URL provided within the `Location`
+    header.
+
+        POST /queues/jms.queue.bar/create/13582001787372
+        Host: example.com
+        Content-Type: application/xml
+
+        <order>
+           <name>Bill</name>
+           <item>iPhone4</name>
+           <cost>$199.99</cost>
+        </order>
+
+        --- Response --
+        HTTP/1.1 201 Created
+        msg-create-next: http://example.com/queues/jms.queue.bar/create/13582001787373
+
+    You should receive a 201 Created response. If there is a network
+    failure, just re-POST to the Location header. For new messages, use
+    the returned `msg-create-next` header returned with each response.
+
+4.  POST any new message to the returned `msg-create-next` header.
+
+        POST /queues/jms.queue.bar/create/13582001787373
+        Host: example.com
+        Content-Type: application/xml
+
+        <order>
+           <name>Monica</name>
+           <item>iPad</name>
+           <cost>$499.99</cost>
+        </order>
+
+        --- Response --
+        HTTP/1.1 201 Created
+        msg-create-next: http://example.com/queues/jms.queue.bar/create/13582001787374
+
+    If there ever is a network problem, just repost to the URL provided
+    in the `msg-create-next` header.
+
+How can this work? As you can see, with each successful response, the
+ActiveMQ REST server returns a uniquely generated URL within the
+msg-create-next header. This URL is dedicated to the next new message
+you want to post. Behind the scenes, the code extracts an identify from
+the URL and uses ActiveMQ's duplicate detection mechanism by setting the
+`DUPLICATE_DETECTION_ID` property of the JMS message that is actually
+posted to the system.
+
+If you happen to use the same ID more than once you'll see a message
+like this on the server:
+
+    WARN  [org.apache.activemq.core.server] (Thread-3 (ActiveMQ-remoting-threads-ActiveMQServerImpl::serverUUID=8d6be6f8-5e8b-11e2-80db-51bbde66f473-26319292-267207)) HQ112098: Duplicate message detected - message will not be routed. Message information:
+    ServerMessage[messageID=20,priority=4, bodySize=1500,expiration=0, durable=true, address=jms.queue.bar,properties=TypedProperties[{http_content$type=application/x-www-form-urlencoded, http_content$length=3, postedAsHttpMessage=true, _HQ_DUPL_ID=42}]]@12835058
+
+An alternative to this approach is to use the `msg-create-with-id`
+header. This is not an invokable URL, but a URL template. The idea is
+that the client provides the `DUPLICATE_DETECTION_ID` and creates its
+own `create-next` URL. The `msg-create-with-id` header looks like this
+(you've see it in previous examples, but we haven't used it):
+
+    msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}
+
+You see that it is a regular URL appended with a `{id}`. This `{id}` is
+a pattern matching substring. A client would generate its
+`DUPLICATE_DETECTION_ID` and replace `{id}` with that generated id, then
+POST to the new URL. The URL the client creates works exactly like a
+`create-next` URL described earlier. The response of this POST would
+also return a new `msg-create-next` header. The client can continue to
+generate its own DUPLICATE\_DETECTION\_ID, or use the new URL returned
+via the `msg-create-nex`t header.
+
+The advantage of this approach is that the client does not have to
+repost the message. It also only has to come up with a unique
+`DUPLICATE_DETECTION_ID` once.
+
+Persistent Messages
+-------------------
+
+By default, posted messages are not durable and will not be persisted in
+ActiveMQ's journal. You can create durable messages by modifying the
+default configuration as expressed in Chapter 2 so that all messages are
+persisted when sent. Alternatively, you can set a URL query parameter
+called `durable` to true when you post your messages to the URLs
+returned in the `msg-create`, `msg-create-with-id`, or `msg-create-next`
+headers. here's an example of that.
+
+    POST /queues/jms.queue.bar/create?durable=true
+    Host: example.com
+    Content-Type: application/xml
+
+    <order>
+       <name>Bill</name>
+       <item>iPhone4</item>
+       <cost>$199.99</cost>
+    </order>
+
+TTL, Expiration and Priority
+----------------------------
+
+You can set the time to live, expiration, and/or the priority of the
+message in the queue or topic by setting an additional query parameter.
+The `expiration` query parameter is an long specify the time in
+milliseconds since epoch (a long date). The `ttl` query parameter is a
+time in milliseconds you want the message active. The `priority` is
+another query parameter with an integer value between 0 and 9 expressing
+the priority of the message. i.e.:
+
+    POST /queues/jms.queue.bar/create?expiration=30000&priority=3
+    Host: example.com
+    Content-Type: application/xml
+
+    <order>
+       <name>Bill</name>
+       <item>iPhone4</item>
+       <cost>$199.99</cost>
+    </order>
+
+Consuming Messages via Pull
+===========================
+
+There are two different ways to consume messages from a topic or queue.
+You can wait and have the messaging server push them to you, or you can
+continuously poll the server yourself to see if messages are available.
+This chapter discusses the latter. Consuming messages via a pull works
+almost identically for queues and topics with some minor, but important
+caveats. To start consuming you must create a consumer resource on the
+server that is dedicated to your client. Now, this pretty much breaks
+the stateless principle of REST, but after much prototyping, this is the
+best way to work most effectively with ActiveMQ through a REST
+interface.
+
+You create consumer resources by doing a simple POST to the URL
+published by the `msg-pull-consumers` response header if you are
+interacting with a queue, the `msg-pull-subscribers` response header if
+you're interacting with a topic. These headers are provided by the main
+queue or topic resource discussed in [ActiveMQ REST Interface
+Basics](#basics). Doing an empty POST to one of these URLs will create a
+consumer resource that follows an auto-acknowledge protocol and, if you
+are interacting with a topic, creates a temporarily subscription to the
+topic. If you want to use the acknowledgement protocol and/or create a
+durable subscription (topics only), then you must use the form
+parameters (`application/x-www-form-urlencoded`) described below.
+
+-   `autoAck`. A value of `true` or `false` can be given. This defaults
+    to `true` if you do not pass this parameter.
+
+-   `durable`. A value of `true` or `false` can be given. This defaults
+    to `false` if you do not pass this parameter. Only available on
+    topics. This specifies whether you want a durable subscription or
+    not. A durable subscription persists through server restart.
+
+-   `name`. This is the name of the durable subscription. If you do not
+    provide this parameter, the name will be automatically generated by
+    the server. Only usable on topics.
+
+-   `selector`. This is an optional JMS selector string. The ActiveMQ
+    REST interface adds HTTP headers to the JMS message for REST
+    produced messages. HTTP headers are prefixed with "http\_" and every
+    '-' character is converted to a '\$'.
+
+-   `idle-timeout`. For a topic subscription, idle time in milliseconds
+    in which the consumer connections will be closed if idle.
+
+-   `delete-when-idle`. Boolean value, If true, a topic subscription
+    will be deleted (even if it is durable) when an the idle timeout is
+    reached.
+
+> **Note**
+>
+> If you have multiple pull-consumers active at the same time on the
+> same destination be aware that unless the `consumer-window-size` is 0
+> then one consumer might buffer messages while the other consumer gets
+> none.
+
+Auto-Acknowledge
+----------------
+
+This section focuses on the auto-acknowledge protocol for consuming
+messages via a pull. Here's a list of the response headers and URLs
+you'll be interested in.
+
+-   `msg-pull-consumers`. The URL of a factory resource for creating
+    queue consumer resources. You will pull from these created
+    resources.
+
+-   `msg-pull-subscriptions`. The URL of a factory resource for creating
+    topic subscription resources. You will pull from the created
+    resources.
+
+-   `msg-consume-next`. The URL you will pull the next message from.
+    This is returned with every response.
+
+-   `msg-consumer`. This is a URL pointing back to the consumer or
+    subscription resource created for the client.
+
+### Creating an Auto-Ack Consumer or Subscription
+
+Here is an example of creating an auto-acknowledged queue pull consumer.
+
+1.  Find the pull-consumers URL by doing a HEAD or GET request to the
+    base queue resource.
+
+        HEAD /queues/jms.queue.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/queues/jms.queue.bar/create
+        msg-pull-consumers: http://example.com/queues/jms.queue.bar/pull-consumers
+        msg-push-consumers: http://example.com/queues/jms.queue.bar/push-consumers
+
+2.  Next do an empty POST to the URL returned in the
+    `msg-pull-consumers` header.
+
+        POST /queues/jms.queue.bar/pull-consumers HTTP/1.1
+        Host: example.com
+
+        --- response ---
+        HTTP/1.1 201 Created
+        Location: http://example.com/queues/jms.queue.bar/pull-consumers/auto-ack/333
+        msg-consume-next: http://example.com/queues/jms.queue.bar/pull-consumers/auto-ack/333/consume-next-1
+
+    The `Location` header points to the JMS consumer resource that was
+    created on the server. It is good to remember this URL, although, as
+    you'll see later, it is transmitted with each response just to
+    remind you.
+
+Creating an auto-acknowledged consumer for a topic is pretty much the
+same. Here's an example of creating a durable auto-acknowledged topic
+pull subscription.
+
+1.  Find the `pull-subscriptions` URL by doing a HEAD or GET request to
+    the base topic resource
+
+        HEAD /topics/jms.topic.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/topics/jms.topic.foo/create
+        msg-pull-subscriptions: http://example.com/topics/jms.topic.foo/pull-subscriptions
+        msg-push-subscriptions: http://example.com/topics/jms.topic.foo/push-subscriptions
+
+2.  Next do a POST to the URL returned in the `msg-pull-subscriptions`
+    header passing in a `true` value for the `durable` form parameter.
+
+        POST /topics/jms.topic.foo/pull-subscriptions HTTP/1.1
+        Host: example.com
+        Content-Type: application/x-www-form-urlencoded
+
+        durable=true
+
+        --- Response ---
+        HTTP/1.1 201 Created
+        Location: http://example.com/topics/jms.topic.foo/pull-subscriptions/auto-ack/222
+        msg-consume-next:
+        http://example.com/topics/jms.topic.foo/pull-subscriptions/auto-ack/222/consume-next-1
+
+    The `Location` header points to the JMS subscription resource that
+    was created on the server. It is good to remember this URL,
+    although, as you'll see later, it is transmitted with each response
+    just to remind you.
+
+### Consuming Messages
+
+After you have created a consumer resource, you are ready to start
+pulling messages from the server. Notice that when you created the
+consumer for either the queue or topic, the response contained a
+`msg-consume-next` response header. POST to the URL contained within
+this header to consume the next message in the queue or topic
+subscription. A successful POST causes the server to extract a message
+from the queue or topic subscription, acknowledge it, and return it to
+the consuming client. If there are no messages in the queue or topic
+subscription, a 503 (Service Unavailable) HTTP code is returned.
+
+> **Warning**
+>
+> For both successful and unsuccessful posts to the msg-consume-next
+> URL, the response will contain a new msg-consume-next header. You must
+> ALWAYS use this new URL returned within the new msg-consume-next
+> header to consume new messages.
+
+Here's an example of pulling multiple messages from the consumer
+resource.
+
+1.  Do a POST on the msg-consume-next URL that was returned with the
+    consumer or subscription resource discussed earlier.
+
+        POST /queues/jms.queue.bar/pull-consumers/consume-next-1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        Content-Type: application/xml
+        msg-consume-next: http://example.com/queues/jms.queue.bar/pull-consumers/333/consume-next-2
+        msg-consumer: http://example.com/queues/jms.queue.bar/pull-consumers/333
+
+        <order>...</order>
+
+    The POST returns the message consumed from the queue. It also
+    returns a new msg-consume-next link. Use this new link to get the
+    next message. Notice also a msg-consumer response header is
+    returned. This is a URL that points back to the consumer or
+    subscription resource. You will need that to clean up your
+    connection after you are finished using the queue or topic.
+
+2.  The POST returns the message consumed from the queue. It also
+    returns a new msg-consume-next link. Use this new link to get the
+    next message.
+
+        POST /queues/jms.queue.bar/pull-consumers/consume-next-2
+        Host: example.com
+
+        --- Response ---
+        Http/1.1 503 Service Unavailable
+        Retry-After: 5
+        msg-consume-next: http://example.com/queues/jms.queue.bar/pull-consumers/333/consume-next-2
+
+    In this case, there are no messages in the queue, so we get a 503
+    response back. As per the HTTP 1.1 spec, a 503 response may return a
+    Retry-After head specifying the time in seconds that you should
+    retry a post. Also notice, that another new msg-consume-next URL is
+    present. Although it probably is the same URL you used last post,
+    get in the habit of using URLs returned in response headers as
+    future versions of ActiveMQ REST might be redirecting you or adding
+    additional data to the URL after timeouts like this.
+
+3.  POST to the URL within the last `msg-consume-next` to get the next
+    message.
+
+        POST /queues/jms.queue.bar/pull-consumers/consume-next-2
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        Content-Type: application/xml
+        msg-consume-next: http://example.com/queues/jms.queue.bar/pull-consumers/333/consume-next-3
+
+        <order>...</order>
+
+### Recovering From Network Failures
+
+If you experience a network failure and do not know if your post to a
+msg-consume-next URL was successful or not, just re-do your POST. A POST
+to a msg-consume-next URL is idempotent, meaning that it will return the
+same result if you execute on any one msg-consume-next URL more than
+once. Behind the scenes, the consumer resource caches the last consumed
+message so that if there is a message failure and you do a re-post, the
+cached last message will be returned (along with a new msg-consume-next
+URL). This is the reason why the protocol always requires you to use the
+next new msg-consume-next URL returned with each response. Information
+about what state the client is in is embedded within the actual URL.
+
+### Recovering From Client or Server Crashes
+
+If the server crashes and you do a POST to the msg-consume-next URL, the
+server will return a 412 (Preconditions Failed) response code. This is
+telling you that the URL you are using is out of sync with the server.
+The response will contain a new msg-consume-next header to invoke on.
+
+If the client crashes there are multiple ways you can recover. If you
+have remembered the last msg-consume-next link, you can just re-POST to
+it. If you have remembered the consumer resource URL, you can do a GET
+or HEAD request to obtain a new msg-consume-next URL. If you have
+created a topic subscription using the name parameter discussed earlier,
+you can re-create the consumer. Re-creation will return a
+msg-consume-next URL you can use. If you cannot do any of these things,
+you will have to create a new consumer.
+
+The problem with the auto-acknowledge protocol is that if the client or
+server crashes, it is possible for you to skip messages. The scenario
+would happen if the server crashes after auto-acknowledging a message
+and before the client receives the message. If you want more reliable
+messaging, then you must use the acknowledgement protocol.
+
+Manual Acknowledgement
+----------------------
+
+The manual acknowledgement protocol is similar to the auto-ack protocol
+except there is an additional round trip to the server to tell it that
+you have received the message and that the server can internally ack the
+message. Here is a list of the response headers you will be interested
+in.
+
+-   `msg-pull-consumers`. The URL of a factory resource for creating
+    queue consumer resources. You will pull from these created resources
+
+-   `msg-pull-subscriptions`. The URL of a factory resource for creating
+    topic subscription resources. You will pull from the created
+    resources.
+
+-   `msg-acknowledge-next`. URL used to obtain the next message in the
+    queue or topic subscription. It does not acknowledge the message
+    though.
+
+-   `msg-acknowledgement`. URL used to acknowledge a message.
+
+-   `msg-consumer`. This is a URL pointing back to the consumer or
+    subscription resource created for the client.
+
+### Creating manually-acknowledged consumers or subscriptions
+
+Here is an example of creating an auto-acknowledged queue pull consumer.
+
+1.  Find the pull-consumers URL by doing a HEAD or GET request to the
+    base queue resource.
+
+        HEAD /queues/jms.queue.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/queues/jms.queue.bar/create
+        msg-pull-consumers: http://example.com/queues/jms.queue.bar/pull-consumers
+        msg-push-consumers: http://example.com/queues/jms.queue.bar/push-consumers
+
+2.  Next do a POST to the URL returned in the `msg-pull-consumers`
+    header passing in a `false` value to the `autoAck` form parameter .
+
+        POST /queues/jms.queue.bar/pull-consumers HTTP/1.1
+        Host: example.com
+        Content-Type: application/x-www-form-urlencoded
+
+        autoAck=false
+
+        --- response ---
+        HTTP/1.1 201 Created
+        Location: http://example.com/queues/jms.queue.bar/pull-consumers/acknowledged/333
+        msg-acknowledge-next: http://example.com/queues/jms.queue.bar/pull-consumers/acknowledged/333/acknowledge-next-1
+
+    The `Location` header points to the JMS consumer resource that was
+    created on the server. It is good to remember this URL, although, as
+    you'll see later, it is transmitted with each response just to
+    remind you.
+
+Creating an manually-acknowledged consumer for a topic is pretty much
+the same. Here's an example of creating a durable manually-acknowledged
+topic pull subscription.
+
+1.  Find the `pull-subscriptions` URL by doing a HEAD or GET request to
+    the base topic resource
+
+        HEAD /topics/jms.topic.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/topics/jms.topic.foo/create
+        msg-pull-subscriptions: http://example.com/topics/jms.topic.foo/pull-subscriptions
+        msg-push-subscriptions: http://example.com/topics/jms.topic.foo/push-subscriptions
+
+2.  Next do a POST to the URL returned in the `msg-pull-subscriptions`
+    header passing in a `true` value for the `durable` form parameter
+    and a `false` value to the `autoAck` form parameter.
+
+        POST /topics/jms.topic.foo/pull-subscriptions HTTP/1.1
+        Host: example.com
+        Content-Type: application/x-www-form-urlencoded
+
+        durable=true&autoAck=false
+
+        --- Response ---
+        HTTP/1.1 201 Created
+        Location: http://example.com/topics/jms.topic.foo/pull-subscriptions/acknowledged/222
+        msg-acknowledge-next:
+        http://example.com/topics/jms.topic.foo/pull-subscriptions/acknowledged/222/consume-next-1
+
+    The `Location` header points to the JMS subscription resource that
+    was created on the server. It is good to remember this URL,
+    although, as you'll see later, it is transmitted with each response
+    just to remind you.
+
+### Consuming and Acknowledging a Message
+
+After you have created a consumer resource, you are ready to start
+pulling messages from the server. Notice that when you created the
+consumer for either the queue or topic, the response contained a
+`msg-acknowledge-next` response header. POST to the URL contained within
+this header to consume the next message in the queue or topic
+subscription. If there are no messages in the queue or topic
+subscription, a 503 (Service Unavailable) HTTP code is returned. A
+successful POST causes the server to extract a message from the queue or
+topic subscription and return it to the consuming client. It does not
+acknowledge the message though. The response will contain the
+`acknowledgement` header which you will use to acknowledge the message.
+
+Here's an example of pulling multiple messages from the consumer
+resource.
+
+1.  Do a POST on the msg-acknowledge-next URL that was returned with the
+    consumer or subscription resource discussed earlier.
+
+        POST /queues/jms.queue.bar/pull-consumers/consume-next-1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        Content-Type: application/xml
+        msg-acknowledgement:
+        http://example.com/queues/jms.queue.bar/pull-consumers/333/acknowledgement/2
+        msg-consumer: http://example.com/queues/jms.queue.bar/pull-consumers/333
+
+        <order>...</order>
+
+    The POST returns the message consumed from the queue. It also
+    returns a`msg-acknowledgemen`t link. You will use this new link to
+    acknowledge the message. Notice also a `msg-consumer` response
+    header is returned. This is a URL that points back to the consumer
+    or subscription resource. You will need that to clean up your
+    connection after you are finished using the queue or topic.
+
+2.  Acknowledge or unacknowledge the message by doing a POST to the URL
+    contained in the `msg-acknowledgement` header. You must pass an
+    `acknowledge` form parameter set to `true` or `false` depending on
+    whether you want to acknowledge or unacknowledge the message on the
+    server.
+
+        POST /queues/jms.queue.bar/pull-consumers/acknowledgement/2
+        Host: example.com
+        Content-Type: application/x-www-form-urlencoded
+
+        acknowledge=true
+
+        --- Response ---
+        Http/1.1 200 Ok
+        msg-acknowledge-next:
+        http://example.com/queues/jms.queue.bar/pull-consumers/333/acknowledge-next-2
+
+    Whether you acknowledge or unacknowledge the message, the response
+    will contain a new msg-acknowledge-next header that you must use to
+    obtain the next message.
+
+### Recovering From Network Failures
+
+If you experience a network failure and do not know if your post to a
+`msg-acknowledge-next` or `msg-acknowledgement` URL was successful or
+not, just re-do your POST. A POST to one of these URLs is idempotent,
+meaning that it will return the same result if you re-post. Behind the
+scenes, the consumer resource keeps track of its current state. If the
+last action was a call to`msg-acknowledge-next`, it will have the last
+message cached, so that if a re-post is done, it will return the message
+again. Same goes with re-posting to `msg-acknowledgement`. The server
+remembers its last state and will return the same results. If you look
+at the URLs you'll see that they contain information about the expected
+current state of the server. This is how the server knows what the
+client is expecting.
+
+### Recovering From Client or Server Crashes
+
+If the server crashes and while you are doing a POST to the
+`msg-acknowledge-next` URL, just re-post. Everything should reconnect
+all right. On the other hand, if the server crashes while you are doing
+a POST to`msg-acknowledgement`, the server will return a 412
+(Preconditions Failed) response code. This is telling you that the URL
+you are using is out of sync with the server and the message you are
+acknowledging was probably re-enqueued. The response will contain a new
+`msg-acknowledge-next` header to invoke on.
+
+As long as you have "bookmarked" the consumer resource URL (returned
+from `Location` header on a create, or the `msg-consumer` header), you
+can recover from client crashes by doing a GET or HEAD request on the
+consumer resource to obtain what state you are in. If the consumer
+resource is expecting you to acknowledge a message, it will return a
+`msg-acknowledgement` header in the response. If the consumer resource
+is expecting you to pull for the next message, the
+`msg-acknowledge-next` header will be in the response. With manual
+acknowledgement you are pretty much guaranteed to avoid skipped
+messages. For topic subscriptions that were created with a name
+parameter, you do not have to "bookmark" the returned URL. Instead, you
+can re-create the consumer resource with the same exact name. The
+response will contain the same information as if you did a GET or HEAD
+request on the consumer resource.
+
+Blocking Pulls with Accept-Wait
+-------------------------------
+
+Unless your queue or topic has a high rate of message flowing though it,
+if you use the pull protocol, you're going to be receiving a lot of 503
+responses as you continuously pull the server for new messages. To
+alleviate this problem, the ActiveMQ REST interface provides the
+`Accept-Wait` header. This is a generic HTTP request header that is a
+hint to the server for how long the client is willing to wait for a
+response from the server. The value of this header is the time in
+seconds the client is willing to block for. You would send this request
+header with your pull requests. Here's an example:
+
+    POST /queues/jms.queue.bar/pull-consumers/consume-next-2
+    Host: example.com
+    Accept-Wait: 30
+
+    --- Response ---
+    HTTP/1.1 200 Ok
+    Content-Type: application/xml
+    msg-consume-next: http://example.com/queues/jms.queue.bar/pull-consumers/333/consume-next-3
+
+    <order>...</order>
+
+In this example, we're posting to a msg-consume-next URL and telling the
+server that we would be willing to block for 30 seconds.
+
+Clean Up Your Consumers!
+------------------------
+
+When the client is done with its consumer or topic subscription it
+should do an HTTP DELETE call on the consumer URL passed back from the
+Location header or the msg-consumer response header. The server will
+time out a consumer with the value of `consumer-session-timeout-seconds`
+configured from [REST configuration](#configuration), so you don't have
+to clean up if you don't want to, but if you are a good kid, you will
+clean up your messes. A consumer timeout for durable subscriptions will
+not delete the underlying durable JMS subscription though, only the
+server-side consumer resource (and underlying JMS session).
+
+Pushing Messages
+================
+
+You can configure the ActiveMQ REST server to push messages to a
+registered URL either remotely through the REST interface, or by
+creating a pre-configured XML file for the ActiveMQ REST server to load
+at boot time.
+
+The Queue Push Subscription XML
+-------------------------------
+
+Creating a push consumer for a queue first involves creating a very
+simple XML document. This document tells the server if the push
+subscription should survive server reboots (is it durable). It must
+provide a URL to ship the forwarded message to. Finally, you have to
+provide authentication information if the final endpoint requires
+authentication. Here's a simple example:
+
+    <push-registration>
+       <durable>false</durable>
+       <selector><![CDATA[
+       SomeAttribute > 1
+       ]]>
+       </selector>
+       <link rel="push" href="http://somewhere.com" type="application/json" method="PUT"/>
+       <maxRetries>5</maxRetries>
+       <retryWaitMillis>1000</retryWaitMillis>
+       <disableOnFailure>true</disableOnFailure>
+    </push-registration>
+
+The `durable` element specifies whether the registration should be saved
+to disk so that if there is a server restart, the push subscription will
+still work. This element is not required. If left out it defaults
+to`false`. If durable is set to true, an XML file for the push
+subscription will be created within the directory specified by the
+`queue-push-store-dir` config variable defined in Chapter 2
+(`topic-push-store-dir` for topics).
+
+The `selector` element is optional and defines a JMS message selector.
+You should enclose it within CDATA blocks as some of the selector
+characters are illegal XML.
+
+The `maxRetries` element specifies how many times a the server will try
+to push a message to a URL if there is a connection failure.
+
+The `retryWaitMillis` element specifies how long to wait before
+performing a retry.
+
+The `disableOnFailure` element, if set to true, will disable the
+registration if all retries have failed. It will not disable the
+connection on non-connection-failure issues (like a bad request for
+instance). In these cases, the dead letter queue logic of ActiveMQ will
+take over.
+
+The `link` element specifies the basis of the interaction. The `href`
+attribute contains the URL you want to interact with. It is the only
+required attribute. The `type` attribute specifies the content-type of
+what the push URL is expecting. The `method` attribute defines what HTTP
+method the server will use when it sends the message to the server. If
+it is not provided it defaults to POST. The `rel` attribute is very
+important and the value of it triggers different behavior. Here's the
+values a rel attribute can have:
+
+-   `destination`. The href URL is assumed to be a queue or topic
+    resource of another ActiveMQ REST server. The push registration will
+    initially do a HEAD request to this URL to obtain a
+    msg-create-with-id header. It will use this header to push new
+    messages to the ActiveMQ REST endpoint reliably. Here's an example:
+
+        <push-registration>
+           <link rel="destination" href="http://somewhere.com/queues/jms.queue.foo"/>
+        </push-registration>
+
+-   `template`. In this case, the server is expecting the link element's
+    href attribute to be a URL expression. The URL expression must have
+    one and only one URL parameter within it. The server will use a
+    unique value to create the endpoint URL. Here's an example:
+
+        <push-registration>
+           <link rel="template" href="http://somewhere.com/resources/{id}/messages" method="PUT"/>
+        </push-registration>
+
+    In this example, the {id} sub-string is the one and only one URL
+    parameter.
+
+-   `user defined`. If the rel attributes is not destination or template
+    (or is empty or missing), then the server will send an HTTP message
+    to the href URL using the HTTP method defined in the method
+    attribute. Here's an example:
+
+        <push-registration>
+           <link href="http://somewhere.com" type="application/json" method="PUT"/>
+        </push-registration>
+
+The Topic Push Subscription XML
+-------------------------------
+
+The push XML for a topic is the same except the root element is
+push-topic-registration. (Also remember the `selector` element is
+optional). The rest of the document is the same. Here's an example of a
+template registration:
+
+    <push-topic-registration>
+       <durable>true</durable>
+       <selector><![CDATA[
+       SomeAttribute > 1
+       ]]>
+       </selector>
+       <link rel="template" href="http://somewhere.com/resources/{id}/messages" method="POST"/>
+    </push-topic registration>
+
+Creating a Push Subscription at Runtime
+---------------------------------------
+
+Creating a push subscription at runtime involves getting the factory
+resource URL from the msg-push-consumers header, if the destination is a
+queue, or msg-push-subscriptions header, if the destination is a topic.
+Here's an example of creating a push registration for a queue:
+
+1.  First do a HEAD request to the queue resource:
+
+        HEAD /queues/jms.queue.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/queues/jms.queue.bar/create
+        msg-pull-consumers: http://example.com/queues/jms.queue.bar/pull-consumers
+        msg-push-consumers: http://example.com/queues/jms.queue.bar/push-consumers
+
+2.  Next POST your subscription XML to the URL returned from
+    msg-push-consumers header
+
+        POST /queues/jms.queue.bar/push-consumers
+        Host: example.com
+        Content-Type: application/xml
+
+        <push-registration>
+           <link rel="destination" href="http://somewhere.com/queues/jms.queue.foo"/>
+        </push-registration>
+
+        --- Response ---
+        HTTP/1.1 201 Created
+        Location: http://example.com/queues/jms.queue.bar/push-consumers/1-333-1212
+
+    The Location header contains the URL for the created resource. If
+    you want to unregister this, then do a HTTP DELETE on this URL.
+
+Here's an example of creating a push registration for a topic:
+
+1.  First do a HEAD request to the topic resource:
+
+        HEAD /topics/jms.topic.bar HTTP/1.1
+        Host: example.com
+
+        --- Response ---
+        HTTP/1.1 200 Ok
+        msg-create: http://example.com/topics/jms.topic.bar/create
+        msg-pull-subscriptions: http://example.com/topics/jms.topic.bar/pull-subscriptions
+        msg-push-subscriptions: http://example.com/topics/jms.topic.bar/push-subscriptions
+
+2.  Next POST your subscription XML to the URL returned from
+    msg-push-subscriptions header
+
+        POST /topics/jms.topic.bar/push-subscriptions
+        Host: example.com
+        Content-Type: application/xml
+
+        <push-registration>
+           <link rel="template" href="http://somewhere.com/resources/{id}"/>
+        </push-registration>
+
+        --- Response ---
+        HTTP/1.1 201 Created
+        Location: http://example.com/topics/jms.topic.bar/push-subscriptions/1-333-1212
+
+    The Location header contains the URL for the created resource. If
+    you want to unregister this, then do a HTTP DELETE on this URL.
+
+Creating a Push Subscription by Hand
+------------------------------------
+
+You can create a push XML file yourself if you do not want to go through
+the REST interface to create a push subscription. There is some
+additional information you need to provide though. First, in the root
+element, you must define a unique id attribute. You must also define a
+destination element to specify the queue you should register a consumer
+with. For a topic, the destination element is the name of the
+subscription that will be created. For a topic, you must also specify
+the topic name within the topic element.
+
+Here's an example of a hand-created queue registration. This file must
+go in the directory specified by the queue-push-store-dir config
+variable defined in Chapter 2:
+
+    <push-registration id="111">
+       <destination>jms.queue.bar</destination>
+       <durable>true</durable>
+       <link rel="template" href="http://somewhere.com/resources/{id}/messages" method="PUT"/>
+    </push-registration>
+
+Here's an example of a hand-created topic registration. This file must
+go in the directory specified by the topic-push-store-dir config
+variable defined in Chapter 2:
+
+    <push-topic-registration id="112">
+       <destination>my-subscription-1</destination
+       <durable>true</durable>
+       <link rel="template" href="http://somewhere.com/resources/{id}/messages" method="PUT"/>
+       <topic>jms.topic.foo</topic>
+    </push-topic-registration>
+
+Pushing to Authenticated Servers
+--------------------------------
+
+Push subscriptions only support BASIC and DIGEST authentication out of
+the box. Here is an example of adding BASIC authentication:
+
+    <push-topic-registration>
+       <durable>true</durable>
+       <link rel="template" href="http://somewhere.com/resources/{id}/messages" method="POST"/>
+       <authentication>
+          <basic-auth>
+             <username>guest</username>
+             <password>geheim</password>
+          </basic-auth>
+       </authentication>
+    </push-topic registration>
+
+For DIGEST, just replace basic-auth with digest-auth.
+
+For other authentication mechanisms, you can register headers you want
+transmitted with each request. Use the header element with the name
+attribute representing the name of the header. Here's what custom
+headers might look like:
+
+    <push-topic-registration>
+       <durable>true</durable>
+       <link rel="template" href="http://somewhere.com/resources/{id}/messages" method="POST"/>
+       <header name="secret-header">jfdiwe3321</header>
+    </push-topic registration>
+
+Creating Destinations
+=====================
+
+You can create a durable queue or topic through the REST interface.
+Currently you cannot create a temporary queue or topic. To create a
+queue you do a POST to the relative URL /queues with an XML
+representation of the queue. The XML syntax is the same queue syntax
+that you would specify in activemq-jms.xml if you were creating a queue
+there. For example:
+
+    POST /queues
+    Host: example.com
+    Content-Type: application/activemq.jms.queue+xml
+
+    <queue name="testQueue">
+       <durable>true</durable>
+    </queue>
+
+    --- Response ---
+    HTTP/1.1 201 Created
+    Location: http://example.com/queues/jms.queue.testQueue
+
+Notice that the Content-Type is application/activemq.jms.queue+xml.
+
+Here's what creating a topic would look like:
+
+    POST /topics
+    Host: example.com
+    Content-Type: application/activemq.jms.topic+xml
+
+    <topic name="testTopic">
+    </topic>
+
+    --- Response ---
+    HTTP/1.1 201 Created
+    Location: http://example.com/topics/jms.topic.testTopic
+
+Securing the ActiveMQ REST Interface
+====================================
+
+Within JBoss Application server
+-------------------------------
+
+Securing the ActiveMQ REST interface is very simple with the JBoss
+Application Server. You turn on authentication for all URLs within your
+WAR's web.xml, and let the user Principal to propagate to ActiveMQ. This
+only works if you are using the JBossSecurityManager with ActiveMQ. See
+the ActiveMQ documentation for more details.
+
+Security in other environments
+------------------------------
+
+To secure the ActiveMQ REST interface in other environments you must
+role your own security by specifying security constraints with your
+web.xml for every path of every queue and topic you have deployed. Here
+is a list of URI patterns:
+
+  -------------------------------------------- -----------------------------------------------------------------------
+  /queues                                      secure the POST operation to secure queue creation
+  /queues/{queue-name}                         secure the GET HEAD operation to getting information about the queue.
+  /queues/{queue-name}/create/\*               secure this URL pattern for producing messages.
+  /queues/{queue-name}/pull-consumers/\*       secure this URL pattern for pulling messages.
+  /queues/{queue-name}/push-consumers/\*       secure this URL pattern for pushing messages.
+  /topics                                      secure the POST operation to secure topic creation
+  /topics/{topic-name}                         secure the GET HEAD operation to getting information about the topic.
+  /topics/{topic-name}/create/\*               secure this URL pattern for producing messages.
+  /topics/{topic-name}/pull-subscriptions/\*   secure this URL pattern for pulling messages.
+  /topics/{topic-name}/push-subscriptions/\*   secure this URL pattern for pushing messages.
+  -------------------------------------------- -----------------------------------------------------------------------
+
+Mixing JMS and REST
+===================
+
+The ActiveMQ REST interface supports mixing JMS and REST producers and
+consumers. You can send an ObjectMessage through a JMS Producer, and
+have a REST client consume it. You can have a REST client POST a message
+to a topic and have a JMS Consumer receive it. Some simple
+transformations are supported if you have the correct RESTEasy providers
+installed.
+
+JMS Producers - REST Consumers
+------------------------------
+
+If you have a JMS producer, the ActiveMQ REST interface only supports
+ObjectMessage type. If the JMS producer is aware that there may be REST
+consumers, it should set a JMS property to specify what Content-Type the
+Java object should be translated into by REST clients. The ActiveMQ REST
+server will use RESTEasy content handlers (MessageBodyReader/Writers) to
+transform the Java object to the type desired. Here's an example of a
+JMS producer setting the content type of the message.
+
+    ObjectMessage message = session.createObjectMessage();
+    message.setStringProperty(org.apache.activemq.rest.HttpHeaderProperty.CONTENT_TYPE, "application/xml");
+
+If the JMS producer does not set the content-type, then this information
+must be obtained from the REST consumer. If it is a pull consumer, then
+the REST client should send an Accept header with the desired media
+types it wants to convert the Java object into. If the REST client is a
+push registration, then the type attribute of the link element of the
+push registration should be set to the desired type.
+
+REST Producers - JMS Consumers
+------------------------------
+
+If you have a REST client producing messages and a JMS consumer,
+ActiveMQ REST has a simple helper class for you to transform the HTTP
+body to a Java object. Here's some example code:
+
+    public void onMessage(Message message)
+    {
+       MyType obj = org.apache.activemq.rest.Jms.getEntity(message, MyType.class);
+    }
+
+The way the `getEntity()` method works is that if the message is an
+ObjectMessage, it will try to extract the desired type from it like any
+other JMS message. If a REST producer sent the message, then the method
+uses RESTEasy to convert the HTTP body to the Java object you want. See
+the Javadoc of this class for more helper methods.


Mime
View raw message