You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2014/12/08 16:49:36 UTC

[05/25] activemq-6 git commit: ACTIVEMQ6-9 - port to markdown

http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/rest.xml
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/rest.xml b/docs/user-manual/en/rest.xml
deleted file mode 100644
index 10165e4..0000000
--- a/docs/user-manual/en/rest.xml
+++ /dev/null
@@ -1,2150 +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.                                                -->
-<!-- ============================================================================= -->
-<chapter id="rest">
-    <title>REST Interface</title>
-
-    <para>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:
-    </para>
-
-    <programlisting>
-POST /queue/orders/create HTTP/1.1
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Bill&lt;/name>
-   &lt;item>iPhone 4&lt;/item>
-   &lt;cost>$199.99&lt;/cost>
-&lt;/order></programlisting>
-
-    <para>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.
-    </para>
-
-    <section>
-        <title>Goals of REST Interface</title>
-
-        <para>Why would you want to use ActiveMQ's REST interface? What are the
-            goals of the REST interface?
-        </para>
-
-        <itemizedlist>
-            <listitem>
-                <para>Easily usable by machine-based (code) clients.</para>
-            </listitem>
-
-            <listitem>
-                <para>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.
-                </para>
-            </listitem>
-
-            <listitem>
-                <para>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
-                    <ulink url="http://rest-star.org">REST-*</ulink> effort.)
-                </para>
-            </listitem>
-
-            <listitem>
-                <para>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.
-                </para>
-            </listitem>
-
-            <listitem>
-                <para>Leverage the reliability, scalability, and clustering features
-                    of ActiveMQ on the back end without sacrificing the simplicity of a
-                    REST interface.
-                </para>
-            </listitem>
-        </itemizedlist>
-    </section>
-
-
-    <section id="install">
-        <title>Installation and Configuration</title>
-
-        <para>ActiveMQ's REST interface is installed as a Web archive (WAR). It
-            depends on the
-            <ulink url="http://jboss.org/resteasy">RESTEasy</ulink>
-            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).
-        </para>
-
-        <section>
-            <title>Installing Within Pre-configured Environment</title>
-
-            <para>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:
-            </para>
-
-            <programlisting>
-&lt;web-app>
-   &lt;listener>
-      &lt;listener-class>
-         org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
-      &lt;/listener-class>
-   &lt;/listener>
-
-   &lt;listener>
-      &lt;listener-class>
-         org.apache.activemq.rest.integration.RestMessagingBootstrapListener
-      &lt;/listener-class>
-   &lt;/listener>
-
-   &lt;filter>
-      &lt;filter-name>Rest-Messaging&lt;/filter-name>
-      &lt;filter-class>
-         org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
-      &lt;/filter-class>
-   &lt;/filter>
-
-   &lt;filter-mapping>
-      &lt;filter-name>Rest-Messaging&lt;/filter-name>
-      &lt;url-pattern>/*&lt;/url-pattern>
-   &lt;/filter-mapping>
-&lt;/web-app></programlisting>
-
-            <para>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.
-            </para>
-
-            <programlisting>
-&lt;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">
-
-   &lt;modelVersion>4.0.0&lt;/modelVersion>
-   &lt;groupId>org.somebody&lt;/groupId>
-   &lt;artifactId>myapp&lt;/artifactId>
-   &lt;packaging>war&lt;/packaging>
-   &lt;name>My App&lt;/name>
-   &lt;version>0.1-SNAPSHOT&lt;/version>
-   &lt;repositories>
-      &lt;repository>
-         &lt;id>jboss&lt;/id>
-         &lt;url>http://repository.jboss.org/nexus/content/groups/public/&lt;/url>
-      &lt;/repository>
-   &lt;/repositories>
-
-   &lt;build>
-      &lt;plugins>
-         &lt;plugin>
-            &lt;groupId>org.apache.maven.plugins&lt;/groupId>
-            &lt;artifactId>maven-compiler-plugin&lt;/artifactId>
-            &lt;configuration>
-               &lt;source>1.6&lt;/source>
-               &lt;target>1.6&lt;/target>
-            &lt;/configuration>
-         &lt;/plugin>
-      &lt;/plugins>
-   &lt;/build>
-
-   &lt;dependencies>
-      &lt;dependency>
-         &lt;groupId>org.apache.activemq.rest&lt;/groupId>
-         &lt;artifactId>activemq-rest&lt;/artifactId>
-         &lt;version>2.3.0-SNAPSHOT&lt;/version>
-      &lt;/dependency>
-   &lt;/dependencies>
-&lt;/project></programlisting>
-
-            <note>
-                <para>JBoss AS 7 loads classes differently than previous versions.
-                    To work properly in AS 7 the WAR will need this in its MANIFEST.MF:
-                </para>
-                <programlisting>Dependencies: org.apache.activemq, org.jboss.netty</programlisting>
-                <para>You can add this to the<literal>&lt;plugins></literal>
-                    section of the pom.xml to create this entry automatically:
-                </para>
-                <programlisting>
-&lt;plugin>
-   &lt;groupId>org.apache.maven.plugins&lt;/groupId>
-   &lt;artifactId>maven-war-plugin&lt;/artifactId>
-   &lt;configuration>
-      &lt;archive>
-         &lt;manifestEntries>
-            &lt;Dependencies>org.apache.activemq, org.jboss.netty&lt;/Dependencies>
-         &lt;/manifestEntries>
-      &lt;/archive>
-   &lt;/configuration>
-&lt;/plugin></programlisting>
-            </note>
-
-            <para>
-                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.
-            </para>
-            <note>
-                <para>
-                    It is possible to put the WAR file at the "root context" of AS7, but
-                    that is beyond the scope of this documentation.
-                </para>
-            </note>
-        </section>
-
-        <section>
-            <title>Bootstrapping ActiveMQ Along with REST</title>
-
-            <para>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:
-            </para>
-
-            <programlisting>
-&lt;web-app>
-   &lt;listener>
-      &lt;listener-class>
-         org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
-      &lt;/listener-class>
-   &lt;/listener>
-
-   &lt;listener>
-      &lt;listener-class>
-         org.apache.activemq.rest.integration.ActiveMQBootstrapListener
-      &lt;/listener-class>
-   &lt;/listener>
-
-   &lt;listener>
-      &lt;listener-class>
-         org.apache.activemq.rest.integration.RestMessagingBootstrapListener
-      &lt;/listener-class>
-   &lt;/listener>
-
-   &lt;filter>
-      &lt;filter-name>Rest-Messaging&lt;/filter-name>
-      &lt;filter-class>
-         org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
-      &lt;/filter-class>
-   &lt;/filter>
-
-   &lt;filter-mapping>
-      &lt;filter-name>Rest-Messaging&lt;/filter-name>
-      &lt;url-pattern>/*&lt;/url-pattern>
-   &lt;/filter-mapping>
-&lt;/web-app></programlisting>
-
-            <para>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!
-            </para>
-
-            <programlisting>
-&lt;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">
-
-   &lt;modelVersion>4.0.0&lt;/modelVersion>
-   &lt;groupId>org.somebody&lt;/groupId>
-   &lt;artifactId>myapp&lt;/artifactId>
-   &lt;packaging>war&lt;/packaging>
-   &lt;name>My App&lt;/name>
-   &lt;version>0.1-SNAPSHOT&lt;/version>
-   &lt;repositories>
-      &lt;repository>
-         &lt;id>jboss&lt;/id>
-         &lt;url>http://repository.jboss.org/nexus/content/groups/public/&lt;/url>
-      &lt;/repository>
-   &lt;/repositories>
-   &lt;build>
-      &lt;plugins>
-         &lt;plugin>
-            &lt;groupId>org.apache.maven.plugins&lt;/groupId>
-            &lt;artifactId>maven-compiler-plugin&lt;/artifactId>
-            &lt;configuration>
-               &lt;source>1.6&lt;/source>
-               &lt;target>1.6&lt;/target>
-            &lt;/configuration>
-         &lt;/plugin>
-      &lt;/plugins>
-   &lt;/build>
-   &lt;dependencies>
-      &lt;dependency>
-         &lt;groupId>org.apache.activemq&lt;/groupId>
-         &lt;artifactId>activemq-core&lt;/artifactId>
-         &lt;version>2.3.0-SNAPSHOT&lt;/version>
-      &lt;/dependency>
-      &lt;dependency>
-         &lt;groupId>io.netty&lt;/groupId>
-         &lt;artifactId>netty&lt;/artifactId>
-         &lt;version>3.4.5.Final&lt;/version>
-      &lt;/dependency>
-      &lt;dependency>
-         &lt;groupId>org.apache.activemq&lt;/groupId>
-         &lt;artifactId>activemq-jms&lt;/artifactId>
-         &lt;version>2.3.0-SNAPSHOT&lt;/version>
-      &lt;/dependency>
-      &lt;dependency>
-         &lt;groupId>org.jboss.spec.javax.jms&lt;/groupId>
-         &lt;artifactId>jboss-jms-api_2.0_spec&lt;/artifactId>
-         &lt;version>1.0.0.Final&lt;/version>
-      &lt;/dependency>
-      &lt;dependency>
-         &lt;groupId>org.apache.activemq.rest&lt;/groupId>
-         &lt;artifactId>activemq-rest&lt;/artifactId>
-         &lt;version>2.3.0-SNAPSHOT&lt;/version>
-      &lt;/dependency>
-      &lt;dependency>
-         &lt;groupId>org.jboss.resteasy&lt;/groupId>
-         &lt;artifactId>resteasy-jaxrs&lt;/artifactId>
-         &lt;version>2.3.4.Final&lt;/version>
-      &lt;/dependency>
-      &lt;dependency>
-         &lt;groupId>org.jboss.resteasy&lt;/groupId>
-         &lt;artifactId>resteasy-jaxb-provider&lt;/artifactId>
-         &lt;version>2.3.4.Final&lt;/version>
-      &lt;/dependency>
-   &lt;/dependencies>
-&lt;/project></programlisting>
-        </section>
-
-        <section id="configuration">
-            <title>REST Configuration</title>
-
-            <para>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
-                <literal>rest.messaging.config.file</literal> to specify the name of the
-                configuration file. Below is the format of the XML configuration file
-                and the default values for each.
-            </para>
-
-            <programlisting>
-&lt;rest-messaging>
-   &lt;server-in-vm-id>0&lt;/server-in-vm-id>
-   &lt;use-link-headers>false&lt;/use-link-headers>
-   &lt;default-durable-send>false&lt;/default-durable-send>
-   &lt;dups-ok>true&lt;/dups-ok>
-   &lt;topic-push-store-dir>topic-push-store&lt;/topic-push-store-dir>
-   &lt;queue-push-store-dir>queue-push-store&lt;/queue-push-store-dir>
-   &lt;producer-time-to-live>0&lt;/producer-time-to-live>
-   &lt;producer-session-pool-size>10&lt;/producer-session-pool-size>
-   &lt;session-timeout-task-interval>1&lt;/session-timeout-task-interval>
-   &lt;consumer-session-timeout-seconds>300&lt;/consumer-session-timeout-seconds>
-   &lt;consumer-window-size>-1&lt;/consumer-window-size>
-&lt;/rest-messaging></programlisting>
-
-            <para>Let's give an explanation of each config option.</para>
-
-            <itemizedlist>
-                <listitem>
-                    <para><literal>server-in-vm-id</literal>. The ActiveMQ REST
-                        impl uses the IN-VM transport to communicate with ActiveMQ.
-                        It uses the default server id, which is "0".
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>use-link-headers</literal>. By default, all
-                        links (URLs) are published using custom headers. You can
-                        instead have the ActiveMQ REST implementation publish links
-                        using the <ulink url="http://tools.ietf.org/html/draft-nottingham-http-link-header-10">
-                            Link Header specification
-                        </ulink> instead if you desire.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>default-durable-send</literal>. Whether a posted
-                        message should be persisted by default if the user does not
-                        specify a durable query parameter.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>dups-ok</literal>. If this is true, no duplicate
-                        detection protocol will be enforced for message posting.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>topic-push-store-dir</literal>. This must be
-                        a relative or absolute file system path. This is a directory
-                        where push registrations for topics are stored. See
-                        <link linkend="message-push">Pushing Messages</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>queue-push-store-dir</literal>. This must be
-                        a relative or absolute file system path. This is a
-                        directory where push registrations for queues are stored.
-                        See <link linkend="message-push">Pushing Messages</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>producer-session-pool-size</literal>. 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.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>producer-time-to-live</literal>. Default time
-                        to live for posted messages. Default is no ttl.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>session-timeout-task-interval</literal>. 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.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>consumer-session-timeout-seconds</literal>.
-                        Timeout in seconds for pull consumers/subscriptions that
-                        remain idle for that amount of time.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>consumer-window-size</literal>. 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.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </section>
-    </section>
-
-
-    <section id="basics">
-        <title>ActiveMQ REST Interface Basics</title>
-
-        <para>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.
-        </para>
-
-        <section>
-            <title>Queue and Topic Resources</title>
-
-            <para>To interact with a queue or topic you do a HEAD or GET request on
-                the following relative URI pattern:
-            </para>
-
-            <programlisting>
-/queues/{name}
-/topics/{name}</programlisting>
-
-            <para>The base of the URI is the base URL of the WAR you deployed the
-                ActiveMQ REST server within as defined in the
-                <link linkend="install">Installation and Configuration</link>
-                section of this document. Replace the <literal>{name}</literal>
-                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
-                <literal>activemq-jms.xml</literal> file, the URI name should be
-                "jms.topic.foo". If you have configured a JMS queue name "bar" within
-                your <literal>activemq-jms.xml</literal> 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.
-            </para>
-
-            <programlisting>
-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</programlisting>
-
-            <note>
-                <para>
-                    You can use the "curl" utility to test this easily. Simply execute
-                    a command like this:
-                </para>
-
-                <programlisting>
-curl --head http://example.com/queues/jms.queue.bar</programlisting>
-            </note>
-
-            <para>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.
-            </para>
-        </section>
-
-        <section>
-            <title>Queue Resource Response Headers</title>
-
-            <para>Below is a list of response headers you should expect when
-                interacting with a Queue resource.
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para><literal>msg-create</literal>. This is a URL you POST messages
-                        to. The semantics of this link are described in
-                        <link linkend="posting-messages">Posting Messages</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-create-with-id</literal>. This is a URL
-                        <emphasis>template</emphasis> you can use to POST messages.
-                        The semantics of this link are described in
-                        <link linkend="posting-messages">Posting Messages</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-pull-consumers</literal>. This is a URL for
-                        creating consumers that will pull from a queue. The semantics
-                        of this link are described in
-                        <link linkend="message-pull">Consuming Messages via Pull</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-push-consumers</literal>. 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 <link linkend="message-push">Pushing Messages</link>.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </section>
-
-        <section>
-            <title>Topic Resource Response Headers</title>
-
-            <para>Below is a list of response headers you should expect when
-                interacting with a Topic resource.
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para><literal>msg-create</literal>. This is a URL you POST
-                        messages to. The semantics of this link are described in
-                        <link linkend="posting-messages">Posting Messages</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-create-with-id</literal>. This is a URL
-                        <emphasis>template</emphasis> you can use to POST messages.
-                        The semantics of this link are described in
-                        <link linkend="posting-messages">Posting Messages</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-pull-subscriptions</literal>. This is a
-                        URL for creating subscribers that will pull from a topic.
-                        The semantics of this link are described in
-                        <link linkend="message-pull">Consuming Messages via Pull</link>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-push-subscriptions</literal>. 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 <link linkend="message-push">Pushing
-                        Messages</link>.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </section>
-    </section>
-
-
-    <section id="posting-messages">
-        <title>Posting Messages</title>
-
-        <para>This chapter discusses the protocol for posting messages to a queue
-            or a topic. In <link linkend="basics">ActiveMQ REST Interface Basics</link>,
-            you saw that a queue or topic resource publishes variable custom headers
-            that are links to other RESTful resources. The <literal>msg-create</literal>
-            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
-            <literal>msg-create</literal> header. The HTTP message contains whatever
-            content you want to publish to the ActiveMQ destination. Here's an example
-            scenario:
-        </para>
-
-        <note>
-            <para>You can also post messages to the URL template found in
-                <literal>msg-create-with-id</literal>, but this is a more advanced
-                use-case involving duplicate detection that we will discuss later in
-                this section.
-            </para>
-        </note>
-
-        <orderedlist>
-            <listitem>
-                <para>Obtain the starting <literal>msg-create</literal> header from
-                    the queue or topic resource.
-                </para>
-
-                <para>
-                    <programlisting>
-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}</programlisting>
-                </para>
-            </listitem>
-
-            <listitem>
-                <para>Do a POST to the URL contained in the <literal>msg-create</literal>
-                    header.
-                </para>
-
-                <programlisting>
-POST /queues/jms.queue.bar/create
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Bill&lt;/name>
-   &lt;item>iPhone4&lt;/name>
-   &lt;cost>$199.99&lt;/cost>
-&lt;/order>
-
---- Response ---
-HTTP/1.1 201 Created
-msg-create-next: http://example.com/queues/jms.queue.bar/create</programlisting>
-
-                <note>
-                    <para>You can use the "curl" utility to test this easily. Simply execute
-                        a command like this:
-                    </para>
-                    <programlisting>
-curl --verbose --data "123" http://example.com/queues/jms.queue.bar/create</programlisting>
-                </note>
-
-                <para>A successful response will return a 201 response code. Also
-                    notice that a <literal>msg-create-next</literal> response header
-                    is sent as well. You must use this URL to POST your next message.
-                </para>
-            </listitem>
-
-            <listitem>
-                <para>POST your next message to the queue using the URL returned in
-                    the <literal>msg-create-next</literal> header.
-                </para>
-
-                <programlisting>
-POST /queues/jms.queue.bar/create
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Monica&lt;/name>
-   &lt;item>iPad&lt;/item>
-   &lt;cost>$499.99&lt;/cost>
-&lt;/order>
-
---- Response --
-HTTP/1.1 201 Created
-msg-create-next: http://example.com/queues/jms.queue.bar/create</programlisting>
-                <para>Continue using the new <literal>msg-create-next</literal>
-                    header returned with each response.
-                </para>
-            </listitem>
-        </orderedlist>
-
-        <warning>
-            <para>It is <emphasis>VERY IMPORTANT</emphasis> that you never re-use returned
-                <literal>msg-create-next</literal> headers to post new messages. If the
-                <literal>dups-ok</literal> configuration property is set to
-                <literal>false</literal> 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 <literal>msg-create-next</literal> header, then just
-                go back to the queue or topic resource to get the
-                <literal>msg-create</literal> URL again.
-            </para>
-        </warning>
-
-        <section>
-            <title>Duplicate Detection</title>
-
-            <para>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
-                <literal>dups-ok</literal> config option to <literal>false</literal>
-                as described in <link linkend="basics">ActiveMQ REST Interface Basics</link>.
-                When you do this, the initial POST to the <literal>msg-create</literal>
-                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:
-            </para>
-
-            <orderedlist>
-                <listitem>
-                    <para>Obtain the starting <literal>msg-create</literal> header from
-                        the queue or topic resource.
-                    </para>
-
-                    <para>
-                        <programlisting>
-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}</programlisting>
-                    </para>
-                </listitem>
-
-                <listitem>
-                    <para>Do a POST to the URL contained in the <literal>msg-create</literal>
-                        header.
-                    </para>
-
-                    <programlisting>
-POST /queues/jms.queue.bar/create
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Bill&lt;/name>
-   &lt;item>iPhone4&lt;/name>
-   &lt;cost>$199.99&lt;/cost>
-&lt;/order>
-
---- Response ---
-HTTP/1.1 307 Redirect
-Location: http://example.com/queues/jms.queue.bar/create/13582001787372</programlisting>
-
-                    <para>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 <literal>Location</literal>
-                        header.
-                    </para>
-                </listitem>
-
-                <listitem>
-                    <para>re-POST your message to the URL provided within the
-                        <literal>Location</literal> header.
-                    </para>
-
-                    <programlisting>
-POST /queues/jms.queue.bar/create/13582001787372
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Bill&lt;/name>
-   &lt;item>iPhone4&lt;/name>
-   &lt;cost>$199.99&lt;/cost>
-&lt;/order>
-
---- Response --
-HTTP/1.1 201 Created
-msg-create-next: http://example.com/queues/jms.queue.bar/create/13582001787373</programlisting>
-                    <para>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 <literal>msg-create-next</literal>
-                        header returned with each response.
-                    </para>
-                </listitem>
-
-                <listitem>
-                    <para>POST any new message to the returned
-                        <literal>msg-create-next</literal> header.
-                    </para>
-
-                    <programlisting>
-POST /queues/jms.queue.bar/create/13582001787373
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Monica&lt;/name>
-   &lt;item>iPad&lt;/name>
-   &lt;cost>$499.99&lt;/cost>
-&lt;/order>
-
---- Response --
-HTTP/1.1 201 Created
-msg-create-next: http://example.com/queues/jms.queue.bar/create/13582001787374</programlisting>
-                    <para>If there ever is a network problem, just repost to the URL
-                        provided in the <literal>msg-create-next</literal> header.
-                    </para>
-                </listitem>
-            </orderedlist>
-
-            <para>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
-                <literal>DUPLICATE_DETECTION_ID</literal> property of the JMS message
-                that is actually posted to the system.
-            </para>
-
-            <para>If you happen to use the same ID more than once you'll see a message
-                like this on the server:
-            </para>
-            <programlisting>
-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</programlisting>
-
-            <para>An alternative to this approach is to use the <literal>msg-create-with-id</literal>
-                header. This is not an invokable URL, but a URL template. The idea is that
-                the client provides the <literal>DUPLICATE_DETECTION_ID</literal> and creates
-                its own <literal>create-next</literal> URL. The <literal>msg-create-with-id</literal>
-                header looks like this (you've see it in previous examples, but we haven't used it):
-            </para>
-
-            <programlisting>
-msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}</programlisting>
-
-            <para>You see that it is a regular URL appended with a <literal>{id}</literal>. This
-                <literal>{id}</literal> is a pattern matching substring. A client would generate its
-                <literal>DUPLICATE_DETECTION_ID</literal> and replace <literal>{id}</literal>
-                with that generated id, then POST to the new URL. The URL the client creates
-                works exactly like a <literal>create-next</literal> URL described earlier. The 
-                response of this POST would also return a new <literal>msg-create-next</literal>
-                header. The client can continue to generate its own DUPLICATE_DETECTION_ID, or 
-                use the new URL returned via the <literal>msg-create-nex</literal>t header.
-            </para>
-
-            <para>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
-                <literal>DUPLICATE_DETECTION_ID</literal> once.
-            </para>
-        </section>
-
-        <section>
-            <title>Persistent Messages</title>
-
-            <para>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 <literal>durable</literal> to true when you post
-                your messages to the URLs returned in the <literal>msg-create</literal>,
-                <literal>msg-create-with-id</literal>, or <literal>msg-create-next</literal>
-                headers. here's an example of that.
-            </para>
-
-            <programlisting>
-POST /queues/jms.queue.bar/create?durable=true
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Bill&lt;/name>
-   &lt;item>iPhone4&lt;/item>
-   &lt;cost>$199.99&lt;/cost>
-&lt;/order></programlisting>
-        </section>
-
-        <section>
-            <title>TTL, Expiration and Priority</title>
-
-            <para>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 <literal>expiration</literal> query parameter is an long
-                specify the time in milliseconds since epoch (a long date). The
-                <literal>ttl</literal> query parameter is a time in milliseconds you
-                want the message active. The <literal>priority</literal> is another
-                query parameter with an integer value between 0 and 9 expressing the
-                priority of the message. i.e.:
-            </para>
-
-            <programlisting>
-POST /queues/jms.queue.bar/create?expiration=30000&amp;priority=3
-Host: example.com
-Content-Type: application/xml
-
-&lt;order>
-   &lt;name>Bill&lt;/name>
-   &lt;item>iPhone4&lt;/item>
-   &lt;cost>$199.99&lt;/cost>
-&lt;/order></programlisting>
-        </section>
-    </section>
-
-    <section id="message-pull">
-        <title>Consuming Messages via Pull</title>
-
-        <para>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.
-        </para>
-
-        <para>You create consumer resources by doing a simple POST to the URL
-            published by the <literal>msg-pull-consumers</literal>
-            response header if you are interacting with a queue, the
-            <literal>msg-pull-subscribers</literal> response header if you're
-            interacting with a topic. These headers are provided by the main queue or
-            topic resource discussed in <link linkend="basics">ActiveMQ REST Interface
-            Basics</link>. 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 (<literal>application/x-www-form-urlencoded</literal>)
-            described below.
-        </para>
-
-        <itemizedlist>
-            <listitem>
-                <para><literal>autoAck</literal>. A value of <literal>true</literal>
-                    or <literal>false</literal> can be given. This defaults to
-                    <literal>true</literal> if you do not pass this parameter.
-                </para>
-            </listitem>
-            <listitem>
-                <para><literal>durable</literal>. A value of <literal>true</literal>
-                    or <literal>false</literal> can be given. This defaults to
-                    <literal>false</literal> 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.
-                </para>
-            </listitem>
-            <listitem>
-                <para><literal>name</literal>. 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.
-                </para>
-            </listitem>
-            <listitem>
-                <para><literal>selector</literal>. 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 '$'.
-                </para>
-            </listitem>
-            <listitem>
-                <para><literal>idle-timeout</literal>. For a topic subscription,
-                    idle time in milliseconds in which the consumer connections
-                    will be closed if idle.
-                </para>
-            </listitem>
-            <listitem>
-                <para><literal>delete-when-idle</literal>. Boolean value, If
-                    true, a topic subscription will be deleted (even if it is
-                    durable) when an the idle timeout is reached.
-                </para>
-            </listitem>
-        </itemizedlist>
-
-        <note>
-            <para>If you have multiple pull-consumers active at the same time
-                on the same destination be aware that unless the
-                <literal>consumer-window-size</literal> is 0 then one consumer
-                might buffer messages while the other consumer gets none.
-            </para>
-        </note>
-
-        <section>
-            <title>Auto-Acknowledge</title>
-
-            <para>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.
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para><literal>msg-pull-consumers</literal>. The URL of
-                        a factory resource for creating queue consumer
-                        resources. You will pull from these created resources.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-pull-subscriptions</literal>. The URL
-                        of a factory resource for creating topic subscription
-                        resources. You will pull from the created resources.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-consume-next</literal>. The URL you
-                        will pull the next message from. This is returned
-                        with every response.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-consumer</literal>. This is a URL
-                        pointing back to the consumer or subscription
-                        resource created for the client.
-                    </para>
-                </listitem>
-            </itemizedlist>
-
-            <section>
-                <title>Creating an Auto-Ack Consumer or Subscription</title>
-
-                <para>Here is an example of creating an auto-acknowledged
-                    queue pull consumer.
-                </para>
-
-                <orderedlist>
-                    <listitem>
-                        <para>Find the pull-consumers URL by doing a HEAD or
-                            GET request to the base queue resource.
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-                    </listitem>
-
-                    <listitem>
-                        <para>Next do an empty POST to the URL returned in the
-                            <literal>msg-pull-consumers</literal>
-                            header.
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-
-                        <para>The
-                            <literal>Location</literal>
-                            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.
-                        </para>
-                    </listitem>
-                </orderedlist>
-
-                <para>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.
-                </para>
-
-                <orderedlist>
-                    <listitem>
-                        <para>Find the
-                            <literal>pull-subscriptions</literal>
-                            URL by doing
-                            a HEAD or GET request to the base topic resource
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-                    </listitem>
-
-                    <listitem>
-                        <para>Next do a POST to the URL returned in the
-                            <literal>msg-pull-subscriptions</literal>
-                            header passing in a <literal>true</literal>
-                            value for the <literal>durable</literal>
-                            form parameter.
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-
-                        <para>The
-                            <literal>Location</literal>
-                            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.
-                        </para>
-                    </listitem>
-                </orderedlist>
-            </section>
-
-            <section>
-                <title>Consuming Messages</title>
-
-                <para>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
-                    <literal>msg-consume-next</literal> 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.
-                </para>
-
-                <warning>
-                    <para>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.
-                    </para>
-                </warning>
-
-                <para>Here's an example of pulling multiple messages from the consumer
-                    resource.
-                </para>
-
-                <orderedlist>
-                    <listitem>
-                        <para>Do a POST on the msg-consume-next URL that was returned with
-                            the consumer or subscription resource discussed earlier.
-                        </para>
-
-                        <programlisting>
-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
-
-&lt;order>...&lt;/order></programlisting>
-
-                        <para>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.
-                        </para>
-                    </listitem>
-
-                    <listitem>
-                        <para>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.
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-
-                        <para>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.
-                        </para>
-                    </listitem>
-
-                    <listitem>
-                        <para>POST to the URL within the last
-                            <literal>msg-consume-next</literal>
-                            to get the next
-                            message.
-                        </para>
-
-                        <programlisting>
-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
-
-&lt;order>...&lt;/order></programlisting>
-                    </listitem>
-                </orderedlist>
-            </section>
-
-            <section>
-                <title>Recovering From Network Failures</title>
-
-                <para>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.
-                </para>
-            </section>
-
-            <section>
-                <title>Recovering From Client or Server Crashes</title>
-
-                <para>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.
-                </para>
-
-                <para>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.
-                </para>
-
-                <para>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.
-                </para>
-            </section>
-        </section>
-
-        <section>
-            <title>Manual Acknowledgement</title>
-
-            <para>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.
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para><literal>msg-pull-consumers</literal>. The URL of a factory resource for creating queue
-                        consumer
-                        resources. You will pull from these created resources
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-pull-subscriptions</literal>. The URL of a factory resource for creating topic
-                        subscription resources. You will pull from the created
-                        resources.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-acknowledge-next</literal>. URL used to obtain the next message in the queue or
-                        topic
-                        subscription. It does not acknowledge the message though.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-acknowledgement</literal>. URL used to acknowledge a message.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>msg-consumer</literal>. This is a URL pointing back to the consumer or subscription
-                        resource created for the client.
-                    </para>
-                </listitem>
-            </itemizedlist>
-
-            <section>
-                <title>Creating manually-acknowledged consumers or
-                    subscriptions
-                </title>
-
-                <para>Here is an example of creating an auto-acknowledged queue pull
-                    consumer.
-                </para>
-
-                <orderedlist>
-                    <listitem>
-                        <para>Find the pull-consumers URL by doing a HEAD or GET request
-                            to the base queue resource.
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-                    </listitem>
-
-                    <listitem>
-                        <para>Next do a POST to the URL returned in the
-                            <literal>msg-pull-consumers</literal>
-                            header passing in a
-                            <literal>false</literal>
-                            value to the
-                            <literal>autoAck</literal>
-                            form parameter .
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-
-                        <para>The
-                            <literal>Location</literal>
-                            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.
-                        </para>
-                    </listitem>
-                </orderedlist>
-
-                <para>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.
-                </para>
-
-                <orderedlist>
-                    <listitem>
-                        <para>Find the
-                            <literal>pull-subscriptions</literal>
-                            URL by doing
-                            a HEAD or GET request to the base topic resource
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-                    </listitem>
-
-                    <listitem>
-                        <para>Next do a POST to the URL returned in the
-                            <literal>msg-pull-subscriptions</literal>
-                            header passing in a <literal>true</literal>
-                            value for the <literal>durable</literal>
-                            form parameter and a <literal>false</literal>
-                            value to the <literal>autoAck</literal>
-                            form parameter.
-                        </para>
-
-                        <programlisting>
-POST /topics/jms.topic.foo/pull-subscriptions HTTP/1.1
-Host: example.com
-Content-Type: application/x-www-form-urlencoded
-
-durable=true&amp;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</programlisting>
-
-                        <para>The
-                            <literal>Location</literal> 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.
-                        </para>
-                    </listitem>
-                </orderedlist>
-            </section>
-
-            <section>
-                <title>Consuming and Acknowledging a Message</title>
-
-                <para>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
-                    <literal>msg-acknowledge-next</literal> 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
-                    <literal>acknowledgement</literal>
-                    header which you will use to
-                    acknowledge the message.
-                </para>
-
-                <para>Here's an example of pulling multiple messages from the consumer
-                    resource.
-                </para>
-
-                <orderedlist>
-                    <listitem>
-                        <para>Do a POST on the msg-acknowledge-next URL that was returned
-                            with the consumer or subscription resource discussed
-                            earlier.
-                        </para>
-
-                        <programlisting>
-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
-
-&lt;order>...&lt;/order></programlisting>
-
-                        <para>The POST returns the message consumed from the queue. It
-                            also returns a<literal>msg-acknowledgemen</literal>t link. You
-                            will use this new link to acknowledge the message. Notice also a
-                            <literal>msg-consumer</literal> 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.
-                        </para>
-                    </listitem>
-
-                    <listitem>
-                        <para>Acknowledge or unacknowledge the message by doing a POST to
-                            the URL contained in the <literal>msg-acknowledgement</literal>
-                            header. You must pass an <literal>acknowledge</literal>
-                            form parameter set to <literal>true</literal>
-                            or <literal>false</literal> depending on whether you want to
-                            acknowledge or unacknowledge the message on the server.
-                        </para>
-
-                        <programlisting>
-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</programlisting>
-
-                        <para>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.
-                        </para>
-                    </listitem>
-                </orderedlist>
-            </section>
-
-            <section>
-                <title>Recovering From Network Failures</title>
-
-                <para>If you experience a network failure and do not know if your post
-                    to a
-                    <literal>msg-acknowledge-next</literal>
-                    or
-                    <literal>msg-acknowledgement</literal> 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<literal>msg-acknowledge-next</literal>, 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
-                    <literal>msg-acknowledgement</literal>. 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.
-                </para>
-            </section>
-
-            <section>
-                <title>Recovering From Client or Server Crashes</title>
-
-                <para>If the server crashes and while you are doing a POST to the
-                    <literal>msg-acknowledge-next</literal> URL, just re-post. Everything
-                    should reconnect all right. On the other hand, if the server crashes
-                    while you are doing a POST to<literal>msg-acknowledgement</literal>,
-                    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 <literal>msg-acknowledge-next</literal>
-                    header to invoke on.
-                </para>
-
-                <para>As long as you have "bookmarked" the consumer resource URL
-                    (returned from <literal>Location</literal> header on a create, or the
-                    <literal>msg-consumer</literal> 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
-                    <literal>msg-acknowledgement</literal> header in the response. If the
-                    consumer resource is expecting you to pull for the next message, the
-                    <literal>msg-acknowledge-next</literal> 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.
-                </para>
-            </section>
-        </section>
-
-        <section>
-            <title>Blocking Pulls with Accept-Wait</title>
-
-            <para>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 <literal>Accept-Wait</literal> 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:
-            </para>
-
-            <programlisting>
-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
-
-&lt;order>...&lt;/order></programlisting>
-
-            <para>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.
-            </para>
-        </section>
-
-        <section>
-            <title>Clean Up Your Consumers!</title>
-
-            <para>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
-                <literal>consumer-session-timeout-seconds</literal> configured from
-                <link linkend="configuration">REST configuration</link>, 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).
-            </para>
-        </section>
-    </section>
-
-
-    <section id="message-push">
-        <title>Pushing Messages</title>
-
-        <para>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.
-        </para>
-
-        <section>
-            <title>The Queue Push Subscription XML</title>
-
-            <para>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:
-            </para>
-
-            <programlisting>
-&lt;push-registration>
-   &lt;durable>false&lt;/durable>
-   &lt;selector>&lt;![CDATA[
-   SomeAttribute > 1
-   ]]&gt;
-   &lt;/selector>
-   &lt;link rel="push" href="http://somewhere.com" type="application/json" method="PUT"/>
-   &lt;maxRetries>5&lt;/maxRetries>
-   &lt;retryWaitMillis>1000&lt;/retryWaitMillis>
-   &lt;disableOnFailure>true&lt;/disableOnFailure>
-&lt;/push-registration></programlisting>
-
-            <para>The <literal>durable</literal> 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<literal>false</literal>. If
-                durable is set to true, an XML file for the push subscription will be
-                created within the directory specified by the
-                <literal>queue-push-store-dir</literal> config variable defined in
-                Chapter 2 (<literal>topic-push-store-dir</literal> for topics).
-            </para>
-
-            <para>The <literal>selector</literal> 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.
-            </para>
-
-            <para>The <literal>maxRetries</literal> element specifies how many times
-                a the server will try to push a message to a URL if there is a
-                connection failure.
-            </para>
-
-            <para>The <literal>retryWaitMillis</literal> element specifies how long
-                to wait before performing a retry.
-            </para>
-
-            <para>The
-                <literal>disableOnFailure</literal> 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.
-            </para>
-
-            <para>The <literal>link</literal> element specifies the basis of the
-                interaction. The <literal>href</literal> attribute contains the URL you
-                want to interact with. It is the only required attribute. The
-                <literal>type</literal> attribute specifies the content-type of what the
-                push URL is expecting. The <literal>method</literal> 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
-                <literal>rel</literal> attribute is very important and the value of it
-                triggers different behavior. Here's the values a rel attribute can
-                have:
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para><literal>destination</literal>. 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:
-                    </para>
-
-                    <programlisting>
-&lt;push-registration>
-   &lt;link rel="destination" href="http://somewhere.com/queues/jms.queue.foo"/>
-&lt;/push-registration></programlisting>
-                </listitem>
-                <listitem>
-                    <para><literal>template</literal>. 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:
-                    </para>
-
-                    <programlisting>
-&lt;push-registration>
-   &lt;link rel="template" href="http://somewhere.com/resources/{id}/messages" method="PUT"/>
-&lt;/push-registration></programlisting>
-
-                    <para>In this example, the {id} sub-string is the one and only one
-                        URL parameter.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para><literal>user defined</literal>. 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:
-                    </para>
-
-                    <programlisting>
-&lt;push-registration>
-   &lt;link href="http://somewhere.com" type="application/json" method="PUT"/>
-&lt;/push-registration></programlisting>
-                </listitem>
-            </itemizedlist>
-        </section>
-
-        <section>
-            <title>The Topic Push Subscription XML</title>
-
-            <para>The push XML for a topic is the same except the root element is
-                push-topic-registration. (Also remember the <literal>selector</literal>
-                element is optional). The rest of the document is the same. Here's an
-                example of a template registration:
-            </para>
-
-            <programlisting>
-&lt;push-topic-registration>
-   &lt;durable>true&lt;/durable>
-   &lt;selector>&lt;![CDATA[
-   SomeAttribute > 1
-   ]]&gt;
-   &lt;/selector>
-   &lt;link rel="template" href="http://somewhere.com/resources/{id}/messages" method="POST"/>
-&lt;/push-topic registration></programlisting>
-        </section>
-
-        <section>
-            <title>Creating a Push Subscription at Runtime</title>
-
-            <para>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:
-            </para>
-
-            <orderedlist>
-                <listitem>
-                    <para>First do a HEAD request to the queue resource:</para>
-
-                    <programlisting>
-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</programlisting>
-                </listitem>
-
-                <listitem>
-                    <para>Next POST your subscription XML to the URL returned from
-                        msg-push-consumers header
-                    </para>
-
-                    <programlisting>
-POST /queues/jms.queue.bar/push-consumers
-Host: example.com
-Content-Type: application/xml
-
-&lt;push-registration>
-   &lt;link rel="destination" href="http://somewhere.com/queues/jms.queue.foo"/>
-&lt;/push-registration>
-
---- Response ---
-HTTP/1.1 201 Created
-Location: http://example.com/queues/jms.queue.bar/push-consumers/1-333-1212</programlisting>
-
-                    <para>The Location header contains the URL for the created resource.
-                        If you want to unregister this, then do a HTTP DELETE on this
-                        URL.
-                    </para>
-                </listitem>
-            </orderedlist>
-
-            <para>Here's an example of creating a push registration for a
-                topic:
-            </para>
-
-            <orderedlist>
-                <listitem>
-                    <para>First do a HEAD request to the topic resource:</para>
-
-                    <programlisting>
-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</programlisting>
-                </listitem>
-
-                <listitem>
-                    <para>Next POST your subscription XML to the URL returned from
-                        msg-push-subscriptions header
-                    </para>
-
-                    <programlisting>
-POST /topics/jms.topic.bar/push-subscriptions
-Host: example.com
-Content-Type: application/xml
-
-&lt;push-registration>
-   &lt;link rel="template" href="http://somewhere.com/resources/{id}"/>
-&lt;/push-registration>
-
---- Response ---
-HTTP/1.1 201 Created
-Location: http://example.com/topics/jms.topic.bar/push-subscriptions/1-333-1212</programlisting>
-
-                    <para>The Location header contains the URL for the created resource.
-                        If you want to unregister this, then do a HTTP DELETE on this
-                        URL.
-                    </para>
-                </listitem>
-            </orderedlist>
-        </section>
-
-        <section>
-            <title>Creating a Push Subscription by Hand</title>
-
-            <para>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.
-            </para>
-
-            <para>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:
-            </para>
-
-            <programlisting>
-&lt;push-registration id="111">
-   &lt;destination>jms.queue.bar&lt;/destination>
-   &lt;durable>true&lt;/durable>
-   &lt;link rel="template" href="http://somewhere.com/resources/{id}/messages" method="PUT"/>
-&lt;/push-registration></programlisting>
-
-            <para>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:
-            </para>
-
-            <programlisting>
-&lt;push-topic-registration id="112">
-   &lt;destination>my-subscription-1&lt;/destination
-   &lt;durable>true&lt;/durable>
-   &lt;link rel="template" href="http://somewhere.com/resources/{id}/messages" method="PUT"/>
-   &lt;topic>jms.topic.foo&lt;/topic>
-&lt;/push-topic-registra

<TRUNCATED>