Added: qpid/java/trunk/doc/jms-client-0-10/src/docbkx/JMS-Client-0-10-Book.xml
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/doc/jms-client-0-10/src/docbkx/JMS-Client-0-10-Book.xml?rev=1743759&view=auto
==============================================================================
--- qpid/java/trunk/doc/jms-client-0-10/src/docbkx/JMS-Client-0-10-Book.xml 
(added)
+++ qpid/java/trunk/doc/jms-client-0-10/src/docbkx/JMS-Client-0-10-Book.xml Fri 
May 13 21:45:40 2016
@@ -0,0 +1,6594 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd";>
+
+<!--
+
+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.
+
+-->
+
+<book id="client-api-tutorial">
+  <title>Programming in Apache Qpid</title>
+  <subtitle>Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and 
Python</subtitle>
+
+  <chapter>
+    <title>Introduction</title>
+
+    <para>Apache Qpid is a reliable, asynchronous messaging system that
+    supports the AMQP messaging protocol in several common programming
+    languages. Qpid is supported on most common platforms.
+    </para>
+
+    <itemizedlist>
+      <listitem>
+       <para>
+         On the Java platform, Qpid uses the
+         established <ulink url="http://java.sun.com/products/jms/";>Java JMS
+         API</ulink>.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         For Python, C++, and .NET, Qpid defines its own messaging API, the
+         <firstterm>Qpid Messaging API</firstterm>, which is
+         conceptually similar in each.
+       </para>
+       <para>
+         On the .NET platform, Qpid also provides a WCF binding.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         Ruby will also use the Qpid Messaging API, which will soon
+         be implemented. (Ruby currently uses an API that is closely
+         tied to the AMQP version).
+       </para>
+      </listitem>
+    </itemizedlist>
+
+  </chapter>
+
+  <chapter>
+    <title>Using the Qpid Messaging API</title>
+
+    <para>The Qpid Messaging API is quite simple, consisting of only a
+    handful of core classes.
+    </para>
+
+    <itemizedlist>
+
+      <listitem>
+        <para>
+          A <firstterm>message</firstterm> consists of a standard set
+          of fields (e.g. <literal>subject</literal>,
+          <literal>reply-to</literal>), an application-defined set of
+          properties, and message content (the main body of the
+          message).
+        </para>
+      </listitem>
+
+      <listitem>
+        <para>
+          A <firstterm>connection</firstterm> represents a network
+          connection to a remote endpoint.
+        </para>
+      </listitem>
+
+      <listitem>
+        <para>
+          A <firstterm>session</firstterm> provides a sequentially
+          ordered context for sending and receiving
+          <emphasis>messages</emphasis>. A session is obtained from a
+          connection.
+        </para>
+      </listitem>
+
+      <listitem>
+        <para>
+         A <firstterm>sender</firstterm> sends messages to a target
+         using the <literal>sender.send</literal> method. A sender is
+         obtained from a session for a given target address.
+        </para>
+      </listitem>
+
+      <listitem>
+        <para>
+         A <firstterm>receiver</firstterm> receives messages from a
+         source using the <literal>receiver.fetch</literal> method.
+         A receiver is obtained from a session for a given source
+         address.
+        </para>
+      </listitem>
+
+    </itemizedlist>
+
+    <para>
+      The following sections show how to use these classes in a
+      simple messaging program.
+    </para>
+
+    <section>
+      <title>A Simple Messaging Program in C++</title>
+
+      <para>The following C++ program shows how to create a connection,
+      create a session, send messages using a sender, and receive
+      messages using a receiver.</para>
+
+      <example>
+       <title>"Hello world!" in C++</title>
+       <programlisting lang="c++"><![CDATA[
+       #include <qpid/messaging/Connection.h>
+       #include <qpid/messaging/Message.h>
+       #include <qpid/messaging/Receiver.h>
+       #include <qpid/messaging/Sender.h>
+       #include <qpid/messaging/Session.h>
+
+       #include <iostream>]]>
+
+       using namespace qpid::messaging;
+
+       int main(int argc, char** argv) {
+       std::string broker = argc > 1 ? argv[1] : "localhost:5672";
+       std::string address = argc > 2 ? argv[2] : "amq.topic";
+       std::string connectionOptions = argc > 3 ? argv[3] : "";
+
+       Connection connection(broker, connectionOptions);
+       try {
+        connection.open();  <co id="hello-cpp-open" 
linkends="callout-cpp-open"/>
+        Session session = connection.createSession(); <co 
id="hello-cpp-session" linkends="callout-cpp-session"/>
+
+        Receiver receiver = session.createReceiver(address); <co 
id="hello-cpp-receiver" linkends="callout-cpp-receiver"/>
+        Sender sender = session.createSender(address); <co 
id="hello-cpp-sender" linkends="callout-cpp-sender"/>
+
+        sender.send(Message("Hello world!"));
+
+        Message message = receiver.fetch(Duration::SECOND * 1); <co 
id="hello-cpp-fetch" linkends="callout-cpp-fetch"/>
+        <![CDATA[std::cout << message.getContent() << std::endl;]]>
+        session.acknowledge(); <co id="hello-cpp-acknowledge" 
linkends="callout-cpp-acknowledge"/>
+
+        connection.close(); <co id="hello-cpp-close" 
linkends="callout-cpp-close"/>
+        return 0;
+       } catch(const std::exception&amp; error) {
+        <![CDATA[std::cerr << error.what() << std::endl;]]>
+        connection.close();
+        return 1;
+       }
+       }</programlisting>
+
+       <calloutlist>
+         <callout id="callout-cpp-open" arearefs="hello-cpp-open">
+           <para>Establishes the connection with the messaging broker.</para>
+         </callout>
+         <callout id="callout-cpp-session" arearefs="hello-cpp-session">
+           <para>Creates a session object on which messages will be sent and 
received.</para>
+         </callout>
+         <callout id="callout-cpp-receiver" arearefs="hello-cpp-receiver">
+           <para>Creates a receiver that receives messages from the given 
address.</para>
+         </callout>
+         <callout id="callout-cpp-sender" arearefs="hello-cpp-sender">
+           <para>Creates a sender that sends to the given address.</para>
+         </callout>
+         <callout id="callout-cpp-fetch" arearefs="hello-cpp-fetch">
+           <para>Receives the next message. The duration is optional, if 
omitted, will wait indefinitely for the next message.</para>
+         </callout>
+         <callout id="callout-cpp-acknowledge" 
arearefs="hello-cpp-acknowledge">
+           <para>Acknowledges receipt of all fetched messages on the
+           session. This informs the broker that the messages were
+           transferred and processed by the client successfully.</para>
+         </callout>
+         <callout id="callout-cpp-close" arearefs="hello-cpp-close">
+           <para>Closes the connection, all sessions managed by the 
connection, and all senders and receivers managed by each session.</para>
+         </callout>
+       </calloutlist>
+      </example>
+
+
+    </section>
+
+    <section>
+      <title>A Simple Messaging Program in Python</title>
+
+      <para>The following Python program shows how to create a
+      connection, create a session, send messages using a sender, and
+      receive messages using a receiver.</para>
+
+      <example>
+       <title>"Hello world!" in Python</title>
+       <programlisting lang="python"><![CDATA[
+       import sys
+       from qpid.messaging import *
+
+       broker =  "localhost:5672" if len(sys.argv)<2 else sys.argv[1]
+       address = "amq.topic" if len(sys.argv)<3 else sys.argv[2]]]>
+
+       connection = Connection(broker)
+
+       try:
+       connection.open()  <co id="hello-python-open" 
linkends="callout-python-open"/>
+       session = connection.session()   <co id="hello-python-session" 
linkends="callout-python-session"/>
+
+       sender = session.sender(address)  <co id="hello-python-sender" 
linkends="callout-python-sender"/>
+       receiver = session.receiver(address)  <co id="hello-python-receiver" 
linkends="callout-python-receiver"/>
+
+       sender.send(Message("Hello world!"));
+
+       message = receiver.fetch(timeout=1)  <co id="hello-python-fetch" 
linkends="callout-python-fetch"/>
+       print message.content
+       session.acknowledge() <co id="hello-python-acknowledge" 
linkends="callout-python-acknowledge"/>
+
+       except MessagingError,m:
+       print m
+       finally:
+       connection.close()  <co id="hello-python-close" 
linkends="callout-python-close"/>
+       </programlisting>
+
+       <calloutlist>
+         <callout id="callout-python-open" arearefs="hello-python-open">
+           <para>Establishes the connection with the messaging broker.</para>
+         </callout>
+         <callout id="callout-python-session" arearefs="hello-python-session">
+           <para>Creates a session object on which messages will be sent and 
received.</para>
+         </callout>
+         <callout id="callout-python-receiver" 
arearefs="hello-python-receiver">
+           <para>Creates a receiver that receives messages from the given 
address.</para>
+         </callout>
+         <callout id="callout-python-sender" arearefs="hello-python-sender">
+           <para>Creates a sender that sends to the given address.</para>
+         </callout>
+         <callout id="callout-python-fetch" arearefs="hello-python-fetch">
+           <para>Receives the next message. The duration is optional, if 
omitted, will wait indefinitely for the next message.</para>
+         </callout>
+         <callout id="callout-python-acknowledge" 
arearefs="hello-python-acknowledge">
+           <para>Acknowledges receipt of all fetched messages on
+           the session. This informs the broker that the messages were
+           transfered and processed by the client successfully.</para>
+         </callout>
+         <callout id="callout-python-close" arearefs="hello-python-close">
+           <para>Closes the connection, all sessions managed by the 
connection, and all senders and receivers managed by each session.</para>
+         </callout>
+       </calloutlist>
+
+      </example>
+
+    </section>
+
+
+
+
+    <section>
+      <title>A Simple Messaging Program in .NET C#</title>
+
+      <para>The following .NET C#
+      <footnote>
+       <para>
+         The .NET binding for the Qpid C++ Messaging API
+         applies to all .NET Framework managed code languages. C# was chosen
+         for illustration purposes only.
+       </para>
+      </footnote>
+      program shows how to create a connection,
+      create a session, send messages using a sender, and receive
+      messages using a receiver.
+      </para>
+
+      <example>
+       <title>"Hello world!" in .NET C#</title>
+       <programlisting lang="c++">
+         using System;
+         using Org.Apache.Qpid.Messaging;  <co id="hello-csharp-using" 
linkends="callout-csharp-using"/>
+
+         namespace Org.Apache.Qpid.Messaging {
+         class Program {
+         static void Main(string[] args) {
+         String broker = args.Length > 0 ? args[0] : "localhost:5672";
+         String address = args.Length > 1 ? args[1] : "amq.topic";
+
+         Connection connection = null;
+         try {
+         connection = new Connection(broker);
+         connection.Open();   <co id="hello-csharp-open" 
linkends="callout-csharp-open"/>
+         Session session = connection.CreateSession();   <co 
id="hello-csharp-session" linkends="callout-csharp-session"/>
+
+         Receiver receiver = session.CreateReceiver(address);   <co 
id="hello-csharp-receiver" linkends="callout-csharp-receiver"/>
+         Sender sender = session.CreateSender(address);   <co 
id="hello-csharp-sender" linkends="callout-csharp-sender"/>
+
+         sender.Send(new Message("Hello world!"));
+
+         Message message = new Message();
+         message = receiver.Fetch(DurationConstants.SECOND * 1);   <co 
id="hello-csharp-fetch" linkends="callout-csharp-fetch"/>
+         Console.WriteLine("{0}", message.GetContent());
+         session.Acknowledge();   <co id="hello-csharp-acknowledge" 
linkends="callout-csharp-acknowledge"/>
+
+         connection.Close();   <co id="hello-csharp-close" 
linkends="callout-csharp-close"/>
+         } catch (Exception e) {
+         Console.WriteLine("Exception {0}.", e);
+         if (null != connection)
+         connection.Close();
+         }
+         }
+         }
+         }
+
+       </programlisting>
+
+       <calloutlist>
+         <callout id="callout-csharp-using" arearefs="hello-csharp-using">
+           <para> Permits use of Org.Apache.Qpid.Messaging types and methods 
without explicit namespace qualification. Any .NET project must have a project 
reference to the assembly file <literal>Org.Apache.Qpid.Messaging.dll</literal> 
in order to obtain the definitions of the .NET Binding for Qpid Messaging 
namespace.</para>
+         </callout>
+         <callout id="callout-csharp-open" arearefs="hello-csharp-open">
+           <para>Establishes the connection with the messaging broker.</para>
+         </callout>
+         <callout id="callout-csharp-session" arearefs="hello-csharp-session">
+           <para>Creates a session object on which messages will be sent and 
received.</para>
+         </callout>
+         <callout id="callout-csharp-receiver" 
arearefs="hello-csharp-receiver">
+           <para>Creates a receiver that receives messages from the given 
address.</para>
+         </callout>
+         <callout id="callout-csharp-sender" arearefs="hello-csharp-sender">
+           <para>Creates a sender that sends to the given address.</para>
+         </callout>
+         <callout id="callout-csharp-fetch" arearefs="hello-csharp-fetch">
+           <para>Receives the next message. The duration is optional, if 
omitted, will wait indefinitely for the next message.</para>
+         </callout>
+         <callout id="callout-csharp-acknowledge" 
arearefs="hello-csharp-acknowledge">
+           <para>Acknowledges receipt of all fetched messages on the
+           session. This informs the broker that the messages were
+           transfered and processed by the client successfully.</para>
+         </callout>
+         <callout id="callout-csharp-close" arearefs="hello-csharp-close">
+           <para>Closes the connection, all sessions managed by the 
connection, and all senders and receivers managed by each session.</para>
+         </callout>
+       </calloutlist>
+      </example>
+
+
+    </section>
+
+
+
+
+
+
+    <section id="section-addresses">
+      <title>Addresses</title>
+
+      <para>An <firstterm>address</firstterm> is the name of a message
+      target or message source.
+
+      <footnote><para>In the programs we have just seen, we used
+      <literal>amq.topic</literal> as the default address if none is
+      passed in. This is the name of a standard exchange that always
+      exists on an AMQP 0-10 messaging broker.</para></footnote>
+
+      The methods that create senders and receivers require an
+      address. The details of sending to a particular target or
+      receiving from a particular source are then handled by the
+      sender or receiver. A different target or source can be used
+      simply by using a different address.
+      </para>
+
+      <para>An address resolves to a <firstterm>node</firstterm>. The
+      Qpid Messaging API recognises two kinds of nodes,
+      <firstterm>queues</firstterm> and <firstterm>topics</firstterm>
+
+      <footnote><para>The terms <emphasis>queue</emphasis> and
+      <emphasis>topic</emphasis> here were chosen to align with
+      their meaning in JMS. These two addressing 'patterns',
+      queue and topic, are sometimes refered as point-to-point
+      and publish-subscribe. AMQP 0-10 has an exchange type
+      called a <emphasis>topic exchange</emphasis>. When the term
+      <emphasis>topic</emphasis> occurs alone, it refers to a
+      Messaging API topic, not the topic
+      exchange.</para></footnote>.
+
+      A queue stores each message until it has been received and
+      acknowledged, and only one receiver can receive a given message
+
+      <footnote><para>There are exceptions to this rule; for instance,
+      a receiver can use <literal>browse</literal> mode, which leaves
+      messages on the queue for other receivers to
+      read.</para></footnote>.
+
+      A topic immediately delivers a message to all eligible
+      receivers; if there are no eligible receivers, it discards the
+      message.  In the AMQP 0-10 implementation of the API,
+
+      <footnote><para>The AMQP 0-10 implementation is the only one
+      that currently exists.</para></footnote>
+
+      queues map to AMQP queues, and topics map to AMQP exchanges.
+
+      <footnote><para>In AMQP 0-10, messages are sent to
+      exchanges, and read from queues. The Messaging API also
+      allows a sender to send messages to a queue; internally,
+      Qpid implements this by sending the message to the default
+      exchange, with the name of the queue as the routing key. The
+      Messaging API also allows a receiver to receive messages
+      from a topic; internally, Qpid implements this by setting up
+      a private subscription queue for the receiver and binding
+      the subscription queue to the exchange that corresponds to
+      the topic.</para></footnote>
+      </para>
+
+      <para>In the rest of this tutorial, we present many examples
+      using two programs that take an address as a command line
+      parameter.  <command>spout</command> sends messages to the
+      target address, <command>drain</command> receives messages from
+      the source address.  The source code is available in C++, Python, and
+      .NET C# and can be found in the examples directory for each
+      language. These programs can use any address string as a source
+      or a destination, and have many command line options to
+      configure behavior&mdash;use the <command>-h</command> option
+      for documentation on these options.
+
+      <footnote><para>Currently, the C++, Python, and .NET C#
+      implementations of <command>drain</command> and
+      <command>spout</command> have slightly different
+      options. This tutorial uses the C++ implementation. The
+      options will be reconciled in the near
+      future.</para></footnote>
+
+
+      The examples in this tutorial also use the
+      <command>qpid-config</command> utility to configure AMQP 0-10
+      queues and exchanges on a Qpid broker.
+      </para>
+
+
+      <example>
+        <title>Queues</title>
+
+        <para>Create a queue with <command>qpid-config</command>, send a 
message using
+       <command>spout</command>, and read it using 
<command>drain</command>:</para>
+
+        <screen>
+         $ qpid-config add queue hello-world
+         $ ./spout hello-world
+         $ ./drain hello-world
+
+         Message(properties={spout-id:c877e622-d57b-4df2-bf3e-6014c68da0ea:0}, 
content='')
+        </screen>
+
+        <para>The queue stored the message sent by <command>spout</command> 
and delivered
+        it to <command>drain</command> when requested.</para>
+
+       <para>Once the message has been delivered and and acknowledged
+       by <command>drain</command>, it is no longer available on the queue. If 
we run
+       <command>drain</command> one more time, no messages will be 
retrieved.</para>
+
+        <screen>
+         $ ./drain hello-world
+         $
+       </screen>
+
+      </example>
+
+      <example>
+       <title>Topics</title>
+
+       <para>This example is similar to the previous example, but it
+       uses a topic instead of a queue.</para>
+
+       <para>First, use <command>qpid-config</command> to remove the queue
+       and create an exchange with the same name:</para>
+
+        <screen>
+         $ qpid-config del queue hello-world
+         $ qpid-config add exchange topic hello-world
+        </screen>
+
+       <para>Now run <command>drain</command> and <command>spout</command> the 
same way we did in the previous example:</para>
+
+       <screen>
+         $ ./spout hello-world
+         $ ./drain hello-world
+         $
+        </screen>
+
+        <para>Topics deliver messages immediately to any interested
+        receiver, and do not store messages. Because there were no
+        receivers at the time <command>spout</command> sent the
+        message, it was simply discarded. When we ran
+        <command>drain</command>, there were no messages to
+        receive.</para>
+
+       <para>Now let's run <command>drain</command> first, using the
+       <literal>-t</literal> option to specify a timeout in seconds.
+       While <command>drain</command> is waiting for messages,
+       run <command>spout</command> in another window.</para>
+
+        <para><emphasis>First Window:</emphasis></para>
+
+        <screen>
+         $ ./drain -t 30 hello-word
+        </screen>
+
+
+        <para><emphasis>Second Window:</emphasis></para>
+
+        <screen>
+         $ ./spout hello-word
+        </screen>
+
+        <para>Once <command>spout</command> has sent a message, return
+       to the first window to see the output from
+       <command>drain</command>:</para>
+
+        <screen>
+         Message(properties={spout-id:7da2d27d-93e6-4803-8a61-536d87b8d93f:0}, 
content='')
+        </screen>
+
+        <para>You can run <command>drain</command> in several separate
+       windows; each creates a subscription for the exchange, and
+       each receives all messages sent to the exchange.</para>
+
+      </example>
+
+      <section>
+       <title>Address Strings</title>
+
+       <para>So far, our examples have used address strings that
+       contain only the name of a node. An <firstterm>address
+       string</firstterm> can also contain a
+       <firstterm>subject</firstterm> and
+       <firstterm>options</firstterm>.</para>
+
+       <para>The syntax for an address string is:</para>
+
+       <programlisting><![CDATA[
+       address_string ::=  <address> [ / <subject> ] [ ; <options> ]
+       options ::=  { <key> : <value>, ... }
+       ]]></programlisting>
+
+       <para>Addresses, subjects, and keys are strings.  Values can
+       be numbers, strings (with optional single or double quotes),
+       maps, or lists. A complete BNF for address strings appears in
+       <xref linkend="section-address-string-bnf"/>.</para>
+
+
+       <para>So far, the address strings in this tutorial have only
+       used simple names. The following sections show how to use
+       subjects and options.</para>
+
+      </section>
+
+      <section>
+       <title>Subjects</title>
+
+
+       <para>Every message has a property called
+       <firstterm>subject</firstterm>, which is analogous to the
+       subject on an email message. If no subject is specified, the
+       message's subject is null. For convenience, address strings
+       also allow a subject. If a sender's address contains a
+       subject, it is used as the default subject for the messages
+       it sends.
+
+       If a receiver's address contains a subject, it is used to
+       select only messages that match the subject&mdash;the matching
+       algorithm depends on the message source.
+       </para>
+
+       <para>
+         In AMQP 0-10, each exchange type has its own matching
+         algorithm. This is discussed in
+         <xref linkend="section-amqp0-10-mapping"/>.
+       </para>
+
+       <note>
+         <para>
+           Currently, a receiver bound to a queue ignores subjects,
+           receiving messages from the queue without filtering. Support
+           for subject filtering on queues will be implemented soon.
+         </para>
+       </note>
+
+
+       <example>
+         <title>Using subjects</title>
+
+         <para>In this example we show how subjects affect message
+         flow.</para>
+
+         <para>First, let's use <command>qpid-config</command> to create a 
topic exchange.</para>
+
+         <screen>
+           $ qpid-config add exchange topic news-service
+         </screen>
+
+         <para>Now we use drain to receive messages from 
<literal>news-service</literal> that match the subject 
<literal>sports</literal>.</para>
+         <para><emphasis>First Window:</emphasis></para>
+         <screen>
+           $ ./drain -t 30 news-service/sports
+         </screen>
+
+         <para>In a second window, let's send messages to 
<literal>news-service</literal> using two different subjects:</para>
+
+         <para><emphasis>Second Window:</emphasis></para>
+         <screen>
+           $ ./spout news-service/sports
+           $ ./spout news-service/news
+         </screen>
+
+         <para>Now look at the first window, the message with the
+         subject <literal>sports</literal> has been received, but not
+         the message with the subject <literal>news</literal>:</para>
+
+         <screen>
+           Message(properties={qpid.subject:sports, 
spout-id:9441674e-a157-4780-a78e-f7ccea998291:0}, content='')
+         </screen>
+
+         <para>If you run <command>drain</command> in multiple
+          windows using the same subject, all instances of
+          <command>drain</command> receive the messages for that
+          subject.</para>
+       </example>
+
+
+        <para>The AMQP exchange type we are using here,
+        <literal>amq.topic</literal>, can also do more sophisticated
+        matching.
+
+       A sender's subject can contain multiple words separated by a
+       <quote>.</quote> delimiter. For instance, in a news
+       application, the sender might use subjects like
+       <literal>usa.news</literal>, <literal>usa.weather</literal>,
+       <literal>europe.news</literal>, or
+       <literal>europe.weather</literal>.
+
+       The receiver's subject can include wildcard characters&mdash;
+       <quote>#</quote> matches one or more words in the message's
+       subject, <quote>*</quote> matches a single word.
+
+       For instance, if the subject in the source address is
+       <literal>*.news</literal>, it matches messages with the
+       subject <literal>europe.news</literal> or
+       <literal>usa.news</literal>; if it is
+       <literal>europe.#</literal>, it matches messages with subjects
+       like <literal>europe.news</literal> or
+       <literal>europe.pseudo.news</literal>.</para>
+
+       <example>
+         <title>Subjects with multi-word keys</title>
+
+         <para>This example uses drain and spout to demonstrate the
+         use of subjects with two-word keys.</para>
+
+         <para>Let's use <command>drain</command> with the subject
+         <literal>*.news</literal> to listen for messages in which
+         the second word of the key is
+         <literal>news</literal>.</para>
+
+         <para><emphasis>First Window:</emphasis></para>
+
+         <screen>
+           $ ./drain -t 30 news-service/*.news
+         </screen>
+
+         <para>Now let's send messages using several different
+         two-word keys:</para>
+
+         <para><emphasis>Second Window:</emphasis></para>
+
+         <screen>
+           $ ./spout news-service/usa.news
+           $ ./spout news-service/usa.sports
+           $ ./spout news-service/europe.sports
+           $ ./spout news-service/europe.news
+         </screen>
+
+         <para>In the first window, the messages with
+         <literal>news</literal> in the second word of the key have
+         been received:</para>
+
+         <screen>
+           Message(properties={qpid.subject:usa.news, 
spout-id:73fc8058-5af6-407c-9166-b49a9076097a:0}, content='')
+           Message(properties={qpid.subject:europe.news, 
spout-id:f72815aa-7be4-4944-99fd-c64c9747a876:0}, content='')
+         </screen>
+
+
+         <para>Next, let's use <command>drain</command> with the
+         subject <literal>#.news</literal> to match any sequence of
+         words that ends with <literal>news</literal>.</para>
+
+         <para><emphasis>First Window:</emphasis></para>
+
+         <screen>
+           $ ./drain -t 30 news-service/#.news
+         </screen>
+
+         <para>In the second window, let's send messages using a
+         variety of different multi-word keys:</para>
+
+         <para><emphasis>Second Window:</emphasis></para>
+
+         <screen>
+           $ ./spout news-service/news
+           $ ./spout news-service/sports
+           $ ./spout news-service/usa.news
+           $ ./spout news-service/usa.sports
+           $ ./spout news-service/usa.faux.news
+           $ ./spout news-service/usa.faux.sports
+         </screen>
+
+         <para>In the first window, messages with
+         <literal>news</literal> in the last word of the key have been
+         received:</para>
+
+         <screen>
+           Message(properties={qpid.subject:news, 
spout-id:cbd42b0f-c87b-4088-8206-26d7627c9640:0}, content='')
+           Message(properties={qpid.subject:usa.news, 
spout-id:234a78d7-daeb-4826-90e1-1c6540781eac:0}, content='')
+           Message(properties={qpid.subject:usa.faux.news, 
spout-id:6029430a-cfcb-4700-8e9b-cbe4a81fca5f:0}, content='')
+         </screen>
+       </example>
+
+      </section>
+
+      <section>
+       <title>Address String Options</title>
+
+       <para>
+         The options in an address string can contain additional
+         information for the senders or receivers created for it,
+         including:
+       </para>
+       <itemizedlist>
+         <listitem>
+           <para>
+             Policies for assertions about the node to which an address
+             refers.
+           </para>
+           <para>
+             For instance, in the address string <literal>my-queue;
+             {assert: always, node:{ type: queue }}</literal>, the node
+             named <literal>my-queue</literal> must be a queue; if not,
+             the address does not resolve to a node, and an exception
+             is raised.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+             Policies for automatically creating or deleting the node to which 
an address refers.
+           </para>
+           <para>
+             For instance, in the address string <literal>xoxox ; {create: 
always}</literal>,
+             the queue <literal>xoxox</literal> is created, if it does
+             not exist, before the address is resolved.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+             Extension points that can be used for sender/receiver 
configuration.
+           </para>
+           <para>
+             For instance, if the address for a receiver is
+             <literal>my-queue; {mode: browse}</literal>, the receiver
+             works in <literal>browse</literal> mode, leaving messages
+             on the queue so other receivers can receive them.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+             Extension points providing more direct control over the 
underlying protocol.
+           </para>
+           <para>
+             For instance, the <literal>x-bindings</literal> property
+             allows greater control over the AMQP 0-10 binding process
+             when an address is resolved.
+           </para>
+         </listitem>
+       </itemizedlist>
+
+
+       <para>
+         Let's use some examples to show how these different kinds of
+         address string options affect the behavior of senders and
+         receives.
+       </para>
+
+       <section>
+         <title>assert</title>
+         <para>
+           In this section, we use the <literal>assert</literal> option
+           to ensure that the address resolves to a node of the required
+           type.
+         </para>
+
+
+         <example>
+           <title>Assertions on Nodes</title>
+
+           <para>Let's use <command>qpid-config</command> to create a
+           queue and a topic.</para>
+
+           <screen>
+             $ qpid-config add queue my-queue
+             $ qpid-config add exchange topic my-topic
+           </screen>
+
+           <para>
+             We can now use the address specified to drain to assert that it is
+             of a particular type:
+           </para>
+
+           <screen>
+             $ ./drain 'my-queue; {assert: always, node:{ type: queue }}'
+             $ ./drain 'my-queue; {assert: always, node:{ type: topic }}'
+             2010-04-20 17:30:46 warning Exception received from broker: 
not-found: not-found: Exchange not found: my-queue 
(../../src/qpid/broker/ExchangeRegistry.cpp:92) [caused by 2 \x07:\x01]
+             Exchange my-queue does not exist
+           </screen>
+
+           <para>
+             The first attempt passed without error as my-queue is indeed a
+             queue. The second attempt however failed; my-queue is not a
+             topic.
+           </para>
+
+           <para>
+             We can do the same thing for my-topic:
+           </para>
+
+           <screen>
+             $ ./drain 'my-topic; {assert: always, node:{ type: topic }}'
+             $ ./drain 'my-topic; {assert: always, node:{ type: queue }}'
+             2010-04-20 17:31:01 warning Exception received from broker: 
not-found: not-found: Queue not found: my-topic 
(../../src/qpid/broker/SessionAdapter.cpp:754) [caused by 1 \x08:\x01]
+             Queue my-topic does not exist
+           </screen>
+         </example>
+
+         <para>Now let's use the <literal>create</literal> option to
+         create the queue <literal>xoxox</literal> if it does not already
+         exist:</para>
+
+       </section>
+
+       <section>
+         <title>create</title>
+
+         <para>In previous examples, we created the queue before
+         listening for messages on it. Using <literal>create:
+         always</literal>, the queue is automatically created if it
+         does not exist.</para>
+
+         <example>
+           <title>Creating a Queue Automatically</title>
+
+           <para><emphasis>First Window:</emphasis></para>
+           <screen>$ ./drain -t 30 "xoxox ; {create: always}"</screen>
+
+
+           <para>Now we can send messages to this queue:</para>
+
+           <para><emphasis>Second Window:</emphasis></para>
+           <screen>$ ./spout "xoxox ; {create: always}"</screen>
+
+           <para>Returning to the first window, we see that 
<command>drain</command> has received this message:</para>
+
+           
<screen>Message(properties={spout-id:1a1a3842-1a8b-4f88-8940-b4096e615a7d:0}, 
content='')</screen>
+         </example>
+         <para>The details of the node thus created can be controlled by 
further options within the node. See <xref linkend="table-node-properties"/> 
for details.</para>
+       </section>
+
+       <section>
+         <title>browse</title>
+         <para>Some options specify message transfer semantics; for
+         instance, they may state whether messages should be consumed or
+         read in browsing mode, or specify reliability
+         characteristics. The following example uses the
+         <literal>browse</literal> option to receive messages without
+         removing them from a queue.</para>
+
+         <example>
+           <title>Browsing a Queue</title>
+           <para>
+             Let's use the browse mode to receive messages without
+             removing them from the queue. First we send three messages to the
+             queue:
+           </para>
+           <screen>
+             $ ./spout my-queue --content one
+             $ ./spout my-queue --content two
+             $ ./spout my-queue --content three
+           </screen>
+
+           <para>Now we use drain to get those messages, using the browse 
option:</para>
+           <screen>
+             $ ./drain 'my-queue; {mode: browse}'
+             
Message(properties={spout-id:fbb93f30-0e82-4b6d-8c1d-be60eb132530:0}, 
content='one')
+             
Message(properties={spout-id:ab9e7c31-19b0-4455-8976-34abe83edc5f:0}, 
content='two')
+             
Message(properties={spout-id:ea75d64d-ea37-47f9-96a9-d38e01c97925:0}, 
content='three')
+           </screen>
+
+           <para>We can confirm the messages are still on the queue by 
repeating the drain:</para>
+           <screen>
+             $ ./drain 'my-queue; {mode: browse}'
+             
Message(properties={spout-id:fbb93f30-0e82-4b6d-8c1d-be60eb132530:0}, 
content='one')
+             
Message(properties={spout-id:ab9e7c31-19b0-4455-8976-34abe83edc5f:0}, 
content='two')
+             
Message(properties={spout-id:ea75d64d-ea37-47f9-96a9-d38e01c97925:0}, 
content='three')
+           </screen>
+         </example>
+       </section>
+
+       <section>
+         <title>x-bindings</title>
+
+         <para>Greater control over the AMQP 0-10 binding process can
+         be achieved by including an <literal>x-bindings</literal>
+         option in an address string.
+
+         For instance, the XML Exchange is an AMQP 0-10 custom exchange
+         provided by the Apache Qpid C++ broker. It allows messages to
+         be filtered using XQuery; queries can address either message
+         properties or XML content in the body of the message. The
+         xquery is specified in the arguments field of the AMQP 0-10
+         command. When using the messaging API an xquery can be
+         specified in and address that resolves to an XML exchange by
+         using the x-bindings property.</para>
+
+
+         <para>An instance of the XML Exchange must be added before it
+         can be used:</para>
+
+         <programlisting>
+           $ qpid-config add exchange xml xml
+         </programlisting>
+
+         <para>When using the XML Exchange, a receiver provides an
+         XQuery as an x-binding argument. If the query contains a
+         context item (a path starting with <quote>.</quote>), then it
+         is applied to the content of the message, which must be
+         well-formed XML. For instance, <literal>./weather</literal> is
+         a valid XQuery, which matches any message in which the root
+         element is named <literal>weather</literal>. Here is an
+         address string that contains this query:</para>
+
+         <programlisting><![CDATA[
+         xml; {
+         link: {
+         x-bindings: [{exchange:xml, key:weather, 
arguments:{xquery:"./weather"} }]
+         }
+         }
+         ]]></programlisting>
+
+         <para>When using longer queries with <command>drain</command>,
+         it is often useful to place the query in a file, and use
+         <command>cat</command> in the command line. We do this in the
+         following example.</para>
+
+         <example>
+           <title>Using the XML Exchange</title>
+
+           <para>This example uses an x-binding that contains queries, which 
filter based on the content of XML messages. Here is an XQuery that we will use 
in this example:</para>
+
+           <programlisting>
+             <![CDATA[
+                      let $w := ./weather
+                      return $w/station = 'Raleigh-Durham International 
Airport (KRDU)'
+                      and $w/temperature_f > 50
+                      and $w/temperature_f - $w/dewpoint > 5
+                      and $w/wind_speed_mph > 7
+                      and $w/wind_speed_mph < 20 ]]>
+           </programlisting>
+
+           <para>We can specify this query in an x-binding to listen to 
messages that meet the criteria specified by the query:</para>
+
+           <para><emphasis>First Window:</emphasis></para>
+
+           <screen>
+             $ ./drain -f "xml; {link:{x-bindings:[{key:'weather',
+             arguments:{xquery:\"$(cat rdu.xquery )\"}}]}}"
+           </screen>
+
+           <para>In another window, let's create an XML message that meets the 
criteria in the query, and place it in the file 
<filename>rdu.xml</filename>:</para>
+
+           <programlisting>
+             <![CDATA[
+                      <weather>
+                      <station>Raleigh-Durham International Airport 
(KRDU)</station>
+                      <wind_speed_mph>16</wind_speed_mph>
+                      <temperature_f>70</temperature_f>
+                      <dewpoint>35</dewpoint>
+                      </weather>
+             ]]></programlisting>
+
+             <para>Now let's use <command>spout</command> to send this message 
to the XML exchange:</para>
+
+             <para><emphasis>Second Window:</emphasis></para>
+             <screen>
+               spout --content "$(cat rdu.xml)" xml/weather
+             </screen>
+
+             <para>Returning to the first window, we see that the message has 
been received:</para>
+
+             <screen><![CDATA[$ ./drain -f "xml; 
{link:{x-bindings:[{exchange:'xml', key:'weather', arguments:{xquery:\"$(cat 
rdu.xquery )\"}}]}}"
+             Message(properties={qpid.subject:weather, 
spout-id:31c431de-593f-4bec-a3dd-29717bd945d3:0},
+             content='<weather>
+             <station>Raleigh-Durham International Airport (KRDU)</station>
+             <wind_speed_mph>16</wind_speed_mph>
+             <temperature_f>40</temperature_f>
+             <dewpoint>35</dewpoint>
+             </weather>') ]]>
+             </screen>
+         </example>
+       </section>
+
+       <!--
+           <para>When sending data using <command>cat</command> to provide 
arguments to <command>spout</command>, you can use <command>sed</command> to 
change the values that are sent:</para>
+
+<screen>
+spout - -content "$(cat rdu.xml | sed -e 's/70/45/')" xml/weather
+</screen>
+       -->
+
+       <!--
+           TODO: Add some reliability option examples
+        -->
+
+       <section>
+         <title>Address String Options - Reference</title>
+
+         <table pgwide="1">
+           <title>Address String Options</title>
+           <tgroup cols="3">
+             <thead>
+               <colspec colnum="1" colwidth="1*"/>
+               <colspec colnum="2" colwidth="3*"/>
+               <colspec colnum="3" colwidth="3*"/>
+               <row>
+                 <entry>option</entry>
+                 <entry>value</entry>
+                 <entry>semantics</entry>
+               </row>
+             </thead>
+             <tbody>
+               <row>
+                 <entry>
+                   assert
+                 </entry>
+                 <entry>
+                   one of: always, never, sender or receiver
+                 </entry>
+                 <entry>
+                   Asserts that the properties specified in the node option
+                   match whatever the address resolves to. If they do not,
+                   resolution fails and an exception is raised. <!-- ###
+                   Which exception -->
+                 </entry>
+               </row>
+
+               <row>
+                 <entry>
+                   create
+                 </entry>
+                 <entry>
+                   one of: always, never, sender or receiver
+                 </entry>
+                 <entry>
+                   Creates the node to which an address refers if it does
+                   not exist. No error is raised if the node does
+                   exist. The details of the node may be specified in the
+                   node option.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   delete
+                 </entry>
+                 <entry>
+                   one of: always, never, sender or receiver
+                 </entry>
+                 <entry>
+                   Delete the node when the sender or receiver is closed.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   node
+                 </entry>
+                 <entry>
+                   A nested map containing the entries shown in <xref 
linkend="table-node-properties"/>.
+                 </entry>
+                 <entry>
+                   Specifies properties of the node to which the address
+                   refers. These are used in conjunction with the assert or
+                   create options.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   link
+                 </entry>
+                 <entry>
+                   A nested map containing the entries shown in <xref 
linkend="table-link-properties"/>.
+                 </entry>
+                 <entry>
+                   Used to control the establishment of a conceptual link
+                   from the client application to or from the target/source
+                   address.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   mode
+                 </entry>
+                 <entry>
+                   one of: browse, consume
+                 </entry>
+                 <entry>
+                   This option is only of relevance for source addresses
+                   that resolve to a queue. If browse is specified the
+                   messages delivered to the receiver are left on the queue
+                   rather than being removed. If consume is specified the
+                   normal behaviour applies; messages are removed from the
+                   queue once the client acknowledges their receipt.
+                 </entry>
+               </row>
+             </tbody>
+           </tgroup>
+         </table>
+
+
+         <table id="table-node-properties" pgwide="1">
+           <title>Node Properties</title>
+           <tgroup cols="3">
+             <thead>
+               <colspec colnum="1" colwidth="1*"/>
+               <colspec colnum="2" colwidth="3*"/>
+               <colspec colnum="3" colwidth="3*"/>
+               <row>
+                 <entry>property</entry>
+                 <entry>value</entry>
+                 <entry>semantics</entry>
+               </row>
+             </thead>
+             <tbody>
+               <row>
+                 <entry>
+                   type
+                 </entry>
+                 <entry>
+                   topic, queue
+                 </entry>
+                 <entry>
+                   Indicates the type of the node.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   durable
+                 </entry>
+                 <entry>
+                   True, False
+                 </entry>
+                 <entry>
+                   Indicates whether the node survives a loss of
+                   volatile storage e.g. if the broker is restarted.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   x-declare
+                 </entry>
+                 <entry>
+                   A nested map whose values correspond to the valid fields
+                   on an AMQP 0-10 queue-declare or exchange-declare
+                   command.
+                 </entry>
+                 <entry>
+                   These values are used to fine tune the creation or
+                   assertion process. Note however that they are protocol
+                   specific.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   x-bindings
+                 </entry>
+                 <entry>
+                   A nested list in which each binding is represented by
+                   a map. The entries of the map for a binding contain
+                   the fields that describe an AMQP 0-10 binding. Here is
+                   the format for x-bindings:
+
+                   <programlisting><![CDATA[
+                   [
+                   {
+                   exchange: <exchange>,
+                   queue: <queue>,
+                   key: <key>,
+                   arguments: {
+                   <key_1>: <value_1>,
+                   ...,
+                   <key_n>: <value_n> }
+                   },
+                   ...
+                   ]
+                   ]]></programlisting>
+                 </entry>
+                 <entry>
+                   In conjunction with the create option, each of these
+                   bindings is established as the address is resolved. In
+                   conjunction with the assert option, the existence of
+                   each of these bindings is verified during
+                   resolution. Again, these are protocol specific.
+                 </entry>
+               </row>
+             </tbody>
+           </tgroup>
+         </table>
+
+         <table id="table-link-properties" pgwide="1">
+           <title>Link Properties</title>
+           <tgroup cols="3">
+             <thead>
+               <colspec colnum="1" colwidth="1*"/>
+               <colspec colnum="2" colwidth="3*"/>
+               <colspec colnum="3" colwidth="3*"/>
+               <row>
+                 <entry>option</entry>
+                 <entry>value</entry>
+                 <entry>semantics</entry>
+               </row>
+             </thead>
+             <tbody>
+               <row>
+                 <entry>
+                   reliability
+                 </entry>
+                 <entry>
+                   one of: unreliable, at-least-once, at-most-once, 
exactly-once
+                 </entry>
+                 <entry>
+                   Reliability indicates the level of reliability that
+                   the sender or receiver.  <literal>unreliable</literal>
+                   and <literal>at-most-once</literal> are currently
+                   treated as synonyms, and allow messages to be lost if
+                   a broker crashes or the connection to a broker is
+                   lost. <literal>at-least-once</literal> guarantees that
+                   a message is not lost, but duplicates may be
+                   received. <literal>exactly-once</literal> guarantees
+                   that a message is not lost, and is delivered precisely
+                   once. Currently only <literal>unreliable</literal>
+                   and <literal>at-least-once</literal> are supported.
+                   <footnote><para>If at-most-once is requested,
+                   unreliable will be used and for durable messages on
+                   durable queues there is the possibility that messages
+                   will be redelivered; if exactly-once is requested,
+                   at-least-once will be used and the application needs to
+                   be able to deal with duplicates.</para></footnote>
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   durable
+                 </entry>
+                 <entry>
+                   True, False
+                 </entry>
+                 <entry>
+                   Indicates whether the link survives a loss of
+                   volatile storage e.g. if the broker is restarted.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   x-declare
+                 </entry>
+                 <entry>
+                   A nested map whose values correspond to the valid fields
+                   of an AMQP 0-10 queue-declare command.
+                 </entry>
+                 <entry>
+                   These values can be used to customise the subscription
+                   queue in the case of receiving from an exchange. Note
+                   however that they are protocol specific.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   x-subscribe
+                 </entry>
+                 <entry>
+                   A nested map whose values correspond to the valid fields
+                   of an AMQP 0-10 message-subscribe command.
+                 </entry>
+                 <entry>
+                   These values can be used to customise the subscription.
+                 </entry>
+               </row>
+               <row>
+                 <entry>
+                   x-bindings
+                 </entry>
+                 <entry>
+                   A nested list each of whose entries is a map that may
+                   contain fields (queue, exchange, key and arguments)
+                   describing an AMQP 0-10 binding.
+                 </entry>
+                 <entry>
+                   These bindings are established during resolution
+                   independent of the create option. They are considered
+                   logically part of the linking process rather than of
+                   node creation.
+                 </entry>
+               </row>
+             </tbody>
+           </tgroup>
+         </table>
+
+       </section>
+      </section>
+
+      <section id="section-address-string-bnf">
+       <title>Address String Grammar</title>
+
+       <para>This section provides a formal grammar for address strings.</para>
+
+       <formalpara>
+         <title>Tokens</title>
+         <para>The following regular expressions define the tokens used
+       to parse address strings:</para></formalpara>
+       <programlisting><![CDATA[
+       LBRACE: \\{
+       RBRACE: \\}
+       LBRACK: \\[
+       RBRACK: \\]
+       COLON:  :
+       SEMI:   ;
+       SLASH:  /
+       COMMA:  ,
+       NUMBER: [+-]?[0-9]*\\.?[0-9]+
+       ID:     [a-zA-Z_](?:[a-zA-Z0-9_-]*[a-zA-Z0-9_])?
+       STRING: "(?:[^\\\\"]|\\\\.)*"|\'(?:[^\\\\\']|\\\\.)*\'
+       ESC:    
\\\\[^ux]|\\\\x[0-9a-fA-F][0-9a-fA-F]|\\\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]
+       SYM:    [.#*%@$^!+-]
+       WSPACE: [ \\n\\r\\t]+
+       ]]></programlisting>
+
+       <formalpara>
+         <title>Grammar</title>
+         <para>The formal grammar for addresses is given below:</para>
+       </formalpara>
+
+       <programlisting><![CDATA[
+       address := name [ SLASH subject ] [ ";" options ]
+       name := ( part | quoted )+
+       subject := ( part | quoted | SLASH )*
+       quoted := STRING / ESC
+       part := LBRACE / RBRACE / COLON / COMMA / NUMBER / ID / SYM
+       options := map
+       map := "{" ( keyval ( "," keyval )* )? "}"
+       keyval "= ID ":" value
+       value := NUMBER / STRING / ID / map / list
+       list := "[" ( value ( "," value )* )? "]"
+       ]]></programlisting>
+
+
+       <formalpara>
+         <title>Address String Options</title>
+         <para>The address string options map supports the following 
parameters:</para>
+       </formalpara>
+
+       <programlisting><![CDATA[
+       <name> [ / <subject> ] ; {
+       create: always | sender | receiver | never,
+       delete: always | sender | receiver | never,
+       assert: always | sender | receiver | never,
+       mode: browse | consume,
+       node: {
+       type: queue | topic,
+       durable: True | False,
+       x-declare: { ... <declare-overrides> ... },
+       x-bindings: [<binding_1>, ... <binding_n>]
+       },
+       link: {
+       name: <link-name>,
+       durable: True | False,
+       reliability: unreliable | at-most-once | at-least-once | exactly-once,
+       x-declare: { ... <declare-overrides> ... },
+       x-bindings: [<binding_1>, ... <binding_n>],
+       x-subscribe: { ... <subscribe-overrides> ... }
+       }
+       }
+       ]]></programlisting>
+
+
+       <itemizedlist>
+         <title>Create, Delete, and Assert Policies</title>
+         <para>The create, delete, and assert policies specify who should
+         perfom the associated action:</para>
+         <listitem><para><emphasis>always</emphasis>: the action is performed 
by any messaging client</para></listitem>
+         <listitem><para><emphasis>sender</emphasis>: the action is only 
performed by a sender</para></listitem>
+         <listitem><para><emphasis>receiver</emphasis>: the action is only 
performed by a receiver</para></listitem>
+         <listitem><para><emphasis>never</emphasis>: the action is never 
performed (this is the default)</para></listitem>
+       </itemizedlist>
+
+       <itemizedlist>
+         <title>Node-Type</title>
+         <para>The node-type is one of:</para>
+         <listitem><para><emphasis>topic</emphasis>: in the AMQP 0-10
+         mapping, a topic node defaults to the topic exchange, x-declare
+         may be used to specify other exchange types</para></listitem>
+         <listitem><para><emphasis>queue</emphasis>: this is the default 
node-type</para></listitem>
+       </itemizedlist>
+      </section>
+
+
+    </section>
+
+    <section id="replay">
+      <title>Sender Capacity and Replay</title>
+
+      <para>The send method of a sender has an optional second parameter
+      that controls whether the send call is synchronous or not. A
+      synchronous send call will block until the broker has confirmed
+      receipt of the message. An asynchronous send call will return
+      before the broker confirms receipt of the message, allowing for
+      example further send calls to be made without waiting for a
+      roundtrip to the broker for each message. This is desirable where
+      increased throughput is important.</para>
+
+      <para>The sender maintains a list of sent messages whose receipt
+      has yet to be confirmed by the broker. The maximum number of such
+      messages that it will hold is defined by the capacity of the
+      sender, which can be set by the application. If an application
+      tries to send with a sender whose capacity is already fully used
+      up, the send call will block waiting for capacity regardless of
+      the value of the sync flag.</para>
+
+      <para>The sender can be queried for the available space (i.e. the
+      unused capacity), and for the current count of unsettled messages
+      (i.e. those held in the replay list pending confirmation by the
+      server). When the unsettled count is zero, all messages on that
+      sender have been successfully sent.</para>
+
+      <para>If the connection fails and is transparently reconnected
+      (see <xref linkend="connection-options"/> for details on how to control
+      this feature), the unsettled messages for each sender over that
+      connection will be re-transmitted. This provides a transparent
+      level of reliability. This feature can be controlled through the
+      link's reliability as defined in the address (see
+      <xref linkend="table-link-properties"/>). At present only
+      at-least-once guarantees are offered. </para>
+    </section>
+
+    <section id="prefetch">
+      <title>Receiver Capacity (Prefetch)</title>
+
+      <para>By default, a receiver requests the next message from the
+      server in response to each fetch call, resulting in messages being
+      sent to the receiver one at a time. As in the case of sending, it
+      is often desirable to avoid this roundtrip for each message. This
+      can be achieved by allowing the receiver
+      to <firstterm>prefetch</firstterm> messages in anticipation of
+      fetch calls being made. The receiver needs to be able to store
+      these prefetched messages, the number it can hold is controlled by
+      the receivers capacity.</para>
+
+    </section>
+
+    <section id="acknowledgements">
+      <title>Acknowledging Received Messages</title>
+
+      <para>Applications that receive messages should acknowledge their
+      receipt by calling the session's acknowledge method. As in the
+      case of sending messages, acknowledged transfer of messages to
+      receivers provides at-least-once reliability, which means that the
+      loss of the connection or a client crash does not result in lost
+      messages; durable messages are not lost even if the broker is
+      restarted.
+
+      Some cases may not require this however and the reliability can be
+      controlled through a link property in the address options (see
+      <xref linkend="table-link-properties"/>).</para>
+
+      <para>The acknowledge call acknowledges all messages received on
+      the session (i.e. all message that have been returned from a fetch
+      call on a receiver created on that session).</para>
+
+      <para>The acknowledge call also support an optional parameter
+      controlling whether the call is synchronous or not. A synchronous
+      acknowledge will block until the server has confirmed that it has
+      received the acknowledgement. In the asynchronous case, when the
+      call returns there is not yet any guarantee that the server has
+      received and processed the acknowledgement. The session may be
+      queried for the number of unsettled acknowledgements; when that
+      count is zero all acknowledgements made for received messages have
+      been successful.</para>
+
+    </section>
+
+
+    <section>
+      <title>Receiving Messages from Multiple Sources</title>
+
+      <para>A receiver can only read from one source, but many
+      programs need to be able to read messages from many sources. In
+      the Qpid Messaging API, a program can ask a session for
+      the <quote>next receiver</quote>; that is, the receiver that is
+      responsible for the next available message. The following
+      examples show how this is done in C++, Python, and .NET C#.
+      </para>
+
+      <para>Note that to use this pattern you must enable prefetching
+      for each receiver of interest so that the broker will send
+      messages before a fetch call is made. See
+      <xref linkend="prefetch"/> for more on this.</para>
+
+      <example>
+       <title>Receiving Messages from Multiple Sources</title>
+
+       <para>C++:</para>
+
+       <programlisting><![CDATA[
+       Receiver receiver1 = session.createReceiver(address1);
+       receiver1.setCapacity(10);
+       Receiver receiver2 = session.createReceiver(address2);
+       receiver2.setCapacity(10);
+
+       Message message =  session.nextReceiver().fetch();
+       std::cout << message.getContent() << std::endl;
+       session.acknowledge(); // acknowledge message receipt
+       ]]>       </programlisting>
+
+       <para>Python:</para>
+       <programlisting><![CDATA[
+       receiver1 = session.receiver(address1)
+       receiver1.capacity = 10
+       receiver2 = session.receiver(address)
+       receiver2.capacity = 10
+       message = session.next_receiver().fetch()
+       print message.content
+       session.acknowledge()
+       ]]>       </programlisting>
+
+       <para>.NET C#:</para>
+       <programlisting><![CDATA[
+       Receiver receiver1 = session.CreateReceiver(address1);
+       receiver1.Capacity = 10;
+       Receiver receiver2 = session.CreateReceiver(address2);
+       receiver2.Capacity = 10;
+
+       Message message = new Message();
+       message =  session.NextReceiver().Fetch();
+       Console.WriteLine("{0}", message.GetContent());
+       session.Acknowledge();
+       ]]>       </programlisting>
+
+      </example>
+    </section>
+
+    <section>
+      <title>Transactions</title>
+
+      <para>Sometimes it is useful to be able to group messages
+      transfers - sent and/or received - on a session into atomic
+      grouping. This can be done be creating the session as
+      transactional. On a transactional session sent messages only
+      become available at the target address on commit. Likewise any
+      received and acknowledged messages are only discarded at their
+      source on commit
+
+      <footnote><para>Note that this currently is only true for
+      messages received using a reliable mode
+      e.g. at-least-once. Messages sent by a broker to a receiver in
+      unreliable receiver will be discarded immediately regardless of
+      transctionality.</para></footnote>
+
+      .</para>
+
+      <example>
+       <title>Transactions</title>
+       <para>C++:</para>
+       <programlisting><![CDATA[
+       Connection connection(broker);
+       Session session =  connection.createTransactionalSession();
+       ...
+       if (smellsOk())
+       session.commit();
+       else
+       session.rollback();
+       ]]></programlisting>
+       <para>
+         .NET C#:
+       </para>
+
+       <programlisting>
+         Connection connection = new Connection(broker);
+         Session session =  connection.CreateTransactionalSession();
+         ...
+         if (smellsOk())
+         session.Commit();
+         else
+         session.Rollback();
+       </programlisting>
+       <!--
+           <para>Python</para>
+           <programlisting><![CDATA[
+           ### TODO
+           ]]></programlisting>
+       -->
+      </example>
+
+    </section>
+
+    <section id="connections">
+      <title>Connections</title>
+      
+      <para>
+       Messaging connections are created by specifying a broker or a list of 
brokers, and 
+       an optional set of connection options. The constructor prototypes for 
Connections
+       are:
+      </para>
+
+      <programlisting><![CDATA[
+      Connection connection();
+      Connection connection(const string url);
+      Connection connection(const string url, const string& options);
+      Connection connection(const string url, const Variant::Map& options);
+      ]]></programlisting>
+
+      <para>
+       Messaging connection URLs specify only the network host address(es). 
Connection 
+       options are specified separately as an options string or map. This is 
different
+       from JMS Connection URLs that combine the network address and 
connection properties
+       in a single string.
+      </para>
+
+      <section id="connection-url">
+       <title>Connection URLs</title>
+       <para>  
+         Connection URLs describe the broker or set of brokers to which the 
connection
+         is to attach. The format of the Connection URL is defined by AMQP 0.10
+         Domain:connection.amqp-host-url.
+       </para>
+
+       <programlisting><![CDATA[
+       amqp_url = "amqp:" prot_addr_list
+       prot_addr_list = [prot_addr ","]* prot_addr
+       prot_addr = tcp_prot_addr | tls_prot_addr
+       
+       tcp_prot_addr = tcp_id tcp_addr
+       tcp_id = "tcp:" | ""
+       tcp_addr = [host [":" port] ]
+       host = <as per http://www.ietf.org/rfc/rfc3986.txt>
+       port = number   ]]></programlisting>
+
+       <para>
+         Examples of Messaging Connection URLs
+       </para>
+
+       <programlisting><![CDATA[
+       localhost
+       localhost:5672
+       localhost:9999
+       192.168.1.2:5672
+       mybroker.example.com:5672
+       amqp:tcp:localhost:5672
+       tcp:locahost:5672,localhost:5800
+       ]]></programlisting>
+
+      </section>
+
+      <section id="connection-options">
+       <title>Connection Options</title>
+       
+       <para>
+          Aspects of the connections behaviour can be controlled through
+          specifying connection options. For example, connections can be
+          configured to automatically reconnect if the connection to a
+          broker is lost.
+       </para>
+       
+       <example>
+         <title>Specifying Connection Options in C++, Python, and .NET</title>
+         
+         <para>In C++, these options can be set using 
<function>Connection::setOption()</function> or by passing in a set of options 
to the constructor. The options can be passed in as a map or in string 
form:</para>
+         
+         
+         <para>or</para>
+         
+         <programlisting><![CDATA[
+         Connection connection("localhost:5672");
+         connection.setOption("reconnect", true);
+         try {
+         connection.open();
+         !!! SNIP !!!
+         ]]></programlisting>
+         
+         <para>In Python, these options can be set as attributes of the 
connection or using named arguments in
+         the <function>Connection</function> constructor:</para>
+         
+         <programlisting><![CDATA[
+         connection = Connection("localhost:5672", reconnect=True)
+         try:
+         connection.open()
+         !!! SNIP !!!
+         ]]></programlisting>
+         
+         <para>or</para>
+         
+         <programlisting><![CDATA[
+         connection = Connection("localhost:5672")
+         connection.reconnect = True
+         try:
+         connection.open()
+         !!! SNIP !!!
+         ]]></programlisting>
+         <para>
+           In .NET, these options can be set using 
<function>Connection.SetOption()</function> or by passing in a set of options 
to the constructor. The options can be passed in as a map or in string form:
+         </para>
+         
+         <programlisting>
+           Connection connection= new Connection(&#34;localhost:5672&#34;, 
&#34;{reconnect: true}&#34;);
+           try {
+           connection.Open();
+           !!! SNIP !!!
+         </programlisting>
+         <para>
+           or
+         </para>
+         
+         <programlisting>
+           Connection connection = new Connection(&#34;localhost:5672&#34;);
+           connection.SetOption(&#34;reconnect&#34;, true);
+           try {
+           connection.Open();
+           !!! SNIP !!!
+         </programlisting>
+         
+         <para>See the reference documentation for details in each 
language.</para>
+       </example>
+       
+       <para>The following table lists the supported connection options.</para>
+       
+       <table pgwide="1">
+         <title>Connection Options</title>
+         <tgroup cols="3">
+           <thead>
+             <colspec colnum="1" colwidth="1*"/>
+             <colspec colnum="2" colwidth="1*"/>
+             <colspec colnum="3" colwidth="3*"/>
+             <row>
+               <entry>option name</entry>
+               <entry>value type</entry>
+               <entry>semantics</entry>
+             </row>
+           </thead>
+           <tbody>
+             
+             <row>
+               <entry>
+                 <literal>username</literal>
+               </entry>
+               <entry>
+                 string
+               </entry>
+               <entry>
+                 The username to use when authenticating to the broker.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>password</literal>
+               </entry>
+               <entry>
+                 string
+               </entry>
+               <entry>
+                 The password to use when authenticating to the broker.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>sasl_mechanisms</literal>
+               </entry>
+               <entry>
+                 string
+               </entry>
+               <entry>
+                 The specific SASL mechanisms to use with the python
+                 client when authenticating to the broker. The value
+                 is a space separated list.
+               </entry>
+             </row>
+             
+             
+             <row>
+               <entry>
+                 <literal>reconnect</literal>
+               </entry>
+               <entry>
+                 boolean
+               </entry>
+               <entry>
+                 Transparently reconnect if the connection is lost.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>reconnect_timeout</literal>
+               </entry>
+               <entry>
+                 integer
+               </entry>
+               <entry>
+                 Total number of seconds to continue reconnection attempts 
before giving up and raising an exception.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>reconnect_limit</literal>
+               </entry>
+               <entry>
+                 integer
+               </entry>
+               <entry>
+                 Maximum number of reconnection attempts before giving up and 
raising an exception.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>reconnect_interval_min</literal>
+               </entry>
+               <entry>
+                 integer representing time in seconds
+               </entry>
+               <entry>
+                 Minimum number of seconds between reconnection attempts. The 
first reconnection attempt is made immediately; if that fails, the first 
reconnection delay is set to the value of 
<literal>reconnect_interval_min</literal>; if that attempt fails, the reconnect 
interval increases exponentially until a reconnection attempt succeeds or 
<literal>reconnect_interval_max</literal> is reached.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>reconnect_interval_max</literal>
+               </entry>
+               <entry>
+                 integer representing time in seconds
+               </entry>
+               <entry>
+                 Maximum reconnect interval.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>reconnect_interval</literal>
+               </entry>
+               <entry>
+                 integer representing time in seconds
+               </entry>
+               <entry>
+                 Sets both <literal>reconnection_interval_min</literal> and 
<literal>reconnection_interval_max</literal> to the same value.
+               </entry>
+             </row>
+             
+             <row>
+               <entry>
+                 <literal>heartbeat</literal>
+               </entry>
+               <entry>
+                 integer representing time in seconds
+               </entry>
+               <entry>
+                 Requests that heartbeats be sent every N seconds. If two
+                 successive heartbeats are missed the connection is
+                 considered to be lost.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>transport</literal>
+               </entry>
+               <entry>
+                 string
+               </entry>
+               <entry>
+                 Sets the underlying transport protocol used. The default 
option is 'tcp'. To enable ssl, set to 'ssl'. The C++ client additionally 
supports 'rdma'.
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>tcp-nodelay</literal>
+               </entry>
+               <entry>
+                 boolean
+               </entry>
+               <entry>
+                 Set tcp no-delay, i.e. disable Nagle algorithm. [C++ only]
+               </entry>
+             </row>
+             <row>
+               <entry>
+                 <literal>protocol</literal>
+               </entry>
+               <entry>
+                 string
+               </entry>
+               <entry>
+                 Sets the application protocol used. The default option is 
'amqp0-10'. To enable AMQP 1.0, set to 'amqp1.0'.
+               </entry>
+             </row>
+           </tbody>
+         </tgroup>
+       </table>
+       
+      </section>
+    </section>
+
+    <section id="section-Maps">
+      <title>Maps and Lists in Message Content</title>
+
+      <para>Many messaging applications need to exchange data across
+      languages and platforms, using the native datatypes of each
+      programming language.</para>
+
+      <para>The Qpid Messaging API supports <classname>map</classname> and 
<classname>list</classname> in message content.
+
+      <footnote><para>Unlike JMS, there is not a specific message type for
+      map messages.</para></footnote>
+
+      <footnote>
+       <para>
+         Note that the Qpid JMS client supports MapMessages whose values can 
be nested maps or lists. This is not standard JMS behaviour.
+       </para>
+      </footnote>
+      Specific language support for <classname>map</classname> and 
<classname>list</classname> objects are shown in the following table.
+      </para>
+      <table id="tabl-Programming_in_Apache_Qpid-Qpid_Maps_in_Message_Content">
+       <title>Map and List Representation in Supported Languages</title>
+       <tgroup cols="3">
+         <thead>
+           <row>
+             <entry>Language</entry>
+             <entry>map</entry>
+             <entry>list</entry>
+           </row>
+         </thead>
+         <tbody>
+           <row>
+             <entry>Python</entry>
+             <entry><classname>dict</classname></entry>
+             <entry><classname>list</classname></entry>
+           </row>
+           <row>
+             <entry>C++</entry>
+             <entry><classname>Variant::Map</classname></entry>
+             <entry><classname>Variant::List</classname></entry>
+           </row>
+           <row>
+             <entry>Java</entry>
+             <entry><classname>MapMessage</classname></entry>
+             <entry><classname>&nbsp;</classname></entry>
+           </row>
+           <row>
+             <entry>.NET</entry>
+             <entry><classname>Dictionary&#60;string, 
object&#62;</classname></entry>
+             <entry><classname>Collection&#60;object&#62;</classname></entry>
+           </row>
+         </tbody>
+       </tgroup>
+      </table>
+      <para>
+       In all languages, messages are encoded using AMQP&#39;s portable 
datatypes.
+      </para>
+
+      <tip>
+       <para>Because of the differences in type systems among
+       languages, the simplest way to provide portable messages is to
+       rely on maps, lists, strings, 64 bit signed integers, and
+       doubles for messages that need to be exchanged across languages
+       and platforms.</para>
+      </tip>
+
+      <section id="section-Python-Maps">
+       <title>Qpid Maps and Lists in Python</title>
+
+       <para>In Python, Qpid supports the <classname>dict</classname> and 
<classname>list</classname> types directly in message content. The following 
code shows how to send these structures in a message:</para>
+
+       <example>
+         <title>Sending Qpid Maps and Lists in Python</title>
+         <programlisting><![CDATA[
+         from qpid.messaging import *
+         # !!! SNIP !!!
+
+         content = {'Id' : 987654321, 'name' : 'Widget', 'percent' : 0.99}
+         content['colours'] = ['red', 'green', 'white']
+         content['dimensions'] = {'length' : 10.2, 'width' : 5.1,'depth' : 
2.0};
+         content['parts'] = [ [1,2,5], [8,2,5] ]
+         content['specs'] = {'colors' : content['colours'],
+         'dimensions' : content['dimensions'],
+         'parts' : content['parts'] }
+         message = Message(content=content)
+         sender.send(message)
+         ]]>   </programlisting>
+       </example>
+
+
+       <para>The following table shows the datatypes that can be sent in a 
Python map message,
+       and the corresponding datatypes that will be received by clients in 
Java or C++.</para>
+
+
+       <table id="table-Python-Maps" >
+         <title>Python Datatypes in Maps</title>
+         <tgroup cols="3">
+           <thead>
+             <row>
+               <entry>Python Datatype</entry>
+               <entry>&rarr; C++</entry>
+               <entry>&rarr; Java</entry>
+             </row>
+           </thead>
+           <tbody>
+             
<row><entry>bool</entry><entry>bool</entry><entry>boolean</entry></row>
+             
<row><entry>int</entry><entry>int64</entry><entry>long</entry></row>
+             
<row><entry>long</entry><entry>int64</entry><entry>long</entry></row>
+             
<row><entry>float</entry><entry>double</entry><entry>double</entry></row>
+             
<row><entry>unicode</entry><entry>string</entry><entry>java.lang.String</entry></row>
+             
<row><entry>uuid</entry><entry>qpid::types::Uuid</entry><entry>java.util.UUID</entry></row>
+             
<row><entry>dict</entry><entry>Variant::Map</entry><entry>java.util.Map</entry></row>
+             
<row><entry>list</entry><entry>Variant::List</entry><entry>java.util.List</entry></row>
+           </tbody>
+         </tgroup>
+       </table>
+
+      </section>
+
+
+
+
+      <section id="section-cpp-Maps">
+       <title>Qpid Maps and Lists in C++</title>
+
+
+       <para>In C++, Qpid defines the the
+       <classname>Variant::Map</classname> and
+       <classname>Variant::List</classname> types, which can be
+       encoded into message content. The following code shows how to
+       send these structures in a message:</para>
+
+       <example>
+         <title>Sending Qpid Maps and Lists in C++</title>
+         <programlisting><![CDATA[
+         using namespace qpid::types;
+
+         // !!! SNIP !!!
+
+         Message message;
+         Variant::Map content;
+         content["id"] = 987654321;
+         content["name"] = "Widget";
+         content["percent"] = 0.99;
+         Variant::List colours;
+         colours.push_back(Variant("red"));
+         colours.push_back(Variant("green"));
+         colours.push_back(Variant("white"));
+         content["colours"] = colours;
+
+         Variant::Map dimensions;
+         dimensions["length"] = 10.2;
+         dimensions["width"] = 5.1;
+         dimensions["depth"] = 2.0;
+         content["dimensions"]= dimensions;
+
+         Variant::List part1;
+         part1.push_back(Variant(1));
+         part1.push_back(Variant(2));
+         part1.push_back(Variant(5));
+
+         Variant::List part2;
+         part2.push_back(Variant(8));
+         part2.push_back(Variant(2));
+         part2.push_back(Variant(5));
+
+         Variant::List parts;
+         parts.push_back(part1);
+         parts.push_back(part2);
+         content["parts"]= parts;
+
+         Variant::Map specs;
+         specs["colours"] = colours;
+         specs["dimensions"] = dimensions;
+         specs["parts"] = parts;
+         content["specs"] = specs;
+
+         encode(content, message);
+         sender.send(message, true);
+         ]]>     </programlisting>
+       </example>
+
+       <para>The following table shows the datatypes that can be sent
+       in a C++ map message, and the corresponding datatypes that
+       will be received by clients in Java and Python.</para>
+
+       <table  id="table-cpp-Maps">
+         <title>C++ Datatypes in Maps</title>
+         <tgroup cols="3">
+           <thead>
+             <row>
+               <entry>C++ Datatype</entry>
+               <entry>&rarr; Python</entry>
+               <entry>&rarr; Java</entry>
+             </row>
+           </thead>
+           <tbody>
+             
<row><entry>bool</entry><entry>bool</entry><entry>boolean</entry></row>
+             <row><entry>uint16</entry><entry>int | 
long</entry><entry>short</entry></row>
+             <row><entry>uint32</entry><entry>int | 
long</entry><entry>int</entry></row>
+             <row><entry>uint64</entry><entry>int | 
long</entry><entry>long</entry></row>
+             <row><entry>int16</entry><entry>int | 
long</entry><entry>short</entry></row>
+             <row><entry>int32</entry><entry>int | 
long</entry><entry>int</entry></row>
+             <row><entry>int64</entry><entry>int | 
long</entry><entry>long</entry></row>
+             
<row><entry>float</entry><entry>float</entry><entry>float</entry></row>
+             
<row><entry>double</entry><entry>float</entry><entry>double</entry></row>
+             
<row><entry>string</entry><entry>unicode</entry><entry>java.lang.String</entry></row>
+             
<row><entry>qpid::types::Uuid</entry><entry>uuid</entry><entry>java.util.UUID</entry></row>
+             
<row><entry>Variant::Map</entry><entry>dict</entry><entry>java.util.Map</entry></row>
+             
<row><entry>Variant::List</entry><entry>list</entry><entry>java.util.List</entry></row>
+           </tbody>
+         </tgroup>
+       </table>
+      </section>
+
+      <section id="section-dotnet-Maps">
+       <title>Qpid Maps and Lists in .NET</title>
+
+
+       <para>
+         The .NET binding for the Qpid Messaging API binds .NET managed data 
types
+         to C++ <classname>Variant</classname> data types.  The following code 
shows how to
+         send Map and List structures in a message:
+       </para>
+
+       <example>
+         <?dbfo keep-together="auto" ?>
+         <title>Sending Qpid Maps and Lists in .NET C#</title>
+         <programlisting><![CDATA[
+         using System;
+         using Org.Apache.Qpid.Messaging;
+
+         // !!! SNIP !!!
+
+         Dictionary<string, object> content = new Dictionary<string, object>();
+         Dictionary<string, object> subMap = new Dictionary<string, object>();
+         Collection<object> colors = new Collection<object>();
+
+         // add simple types
+         content["id"] = 987654321;
+         content["name"] = "Widget";
+         content["percent"] = 0.99;
+
+         // add nested amqp/map
+         subMap["name"] = "Smith";
+         subMap["number"] = 354;
+         content["nestedMap"] = subMap;
+
+         // add an amqp/list
+         colors.Add("red");
+         colors.Add("green");
+         colors.Add("white");
+         content["colorsList"] = colors;
+
+         // add one of each supported amqp data type
+         bool mybool = true;
+         content["mybool"] = mybool;
+
+         byte mybyte = 4;
+         content["mybyte"] = mybyte;
+
+         UInt16 myUInt16 = 5;
+         content["myUInt16"] = myUInt16;
+
+         UInt32 myUInt32 = 6;
+         content["myUInt32"] = myUInt32;
+
+         UInt64 myUInt64 = 7;
+         content["myUInt64"] = myUInt64;
+
+         char mychar = 'h';
+         content["mychar"] = mychar;
+
+         Int16 myInt16 = 9;
+         content["myInt16"] = myInt16;
+
+         Int32 myInt32 = 10;
+         content["myInt32"] = myInt32;
+
+         Int64 myInt64 = 11;
+         content["myInt64"] = myInt64;
+
+         Single mySingle = (Single)12.12;
+         content["mySingle"] = mySingle;
+
+         Double myDouble = 13.13;
+         content["myDouble"] = myDouble;
+
+         Guid myGuid = new Guid("000102030405060708090a0b0c0d0e0f");
+         content["myGuid"] = myGuid;
+
+         Message message = new Message(content);
+         Send(message, true);
+         ]]>     </programlisting>
+       </example>
+
+       <para>
+         The following table shows the mapping between datatypes in .NET and 
C++.
+       </para>
+
+       <table  id="table-dotnet-Maps">
+         <title>Datatype Mapping between C++ and .NET binding</title>
+         <tgroup cols="2">
+           <thead>
+             <row>
+               <entry>C++ Datatype</entry>
+               <entry>&rarr; .NET binding</entry>
+             </row>
+           </thead>
+           <tbody>
+             <row><entry>void</entry><entry>nullptr</entry></row>
+             <row><entry>bool</entry><entry>bool</entry></row>
+             <row><entry>uint8</entry><entry>byte</entry></row>
+             <row><entry>uint16</entry><entry>UInt16</entry></row>
+             <row><entry>uint32</entry><entry>UInt32</entry></row>
+             <row><entry>uint64</entry><entry>UInt64</entry></row>
+             <row><entry>uint8</entry><entry>char</entry></row>
+             <row><entry>int16</entry><entry>Int16</entry></row>
+             <row><entry>int32</entry><entry>Int32</entry></row>
+             <row><entry>int64</entry><entry>Int64</entry></row>
+             <row><entry>float</entry><entry>Single</entry></row>
+             <row><entry>double</entry><entry>Double</entry></row>
+             <row><entry>string</entry><entry>string
+             <footnote id="callout-dotnet-string">
+               <para>Strings are currently interpreted only with UTF-8 
encoding.</para>
+             </footnote></entry></row>
+             <row><entry>qpid::types::Uuid</entry><entry>Guid</entry></row>
+             
<row><entry>Variant::Map</entry><entry><![CDATA[Dictionary<string, object>]]>
+             <footnoteref linkend="callout-dotnet-string"/></entry></row>
+             
<row><entry>Variant::List</entry><entry><![CDATA[Collection<object>]]>
+             <footnoteref linkend="callout-dotnet-string"/></entry></row>
+           </tbody>
+         </tgroup>
+       </table>
+
+
+      </section>
+
+
+    </section>
+
+    <section>
+      <title>The Request / Response Pattern</title>
+      <para>Request / Response applications use the reply-to property,
+      described in <xref
+      linkend="table-amqp0-10-message-properties"/>, to allow a server
+      to respond to the client that sent a message. A server sets up a
+      service queue, with a name known to clients. A client creates a
+      private queue for the server's response, creates a message for a
+      request, sets the request's reply-to property to the address of
+      the client's response queue, and sends the request to the
+      service queue. The server sends the response to the address
+      specified in the request's reply-to property.
+      </para>
+      <example>
+       <title>Request / Response Applications in C++</title>
+
+       <para>This example shows the C++ code for a client and server
+       that use the request / response pattern.</para>
+
+       <para>The server creates a service queue and waits for a
+       message to arrive. If it receives a message, it sends a
+       message back to the sender.</para>
+
+       <programlisting><![CDATA[Receiver receiver = 
session.createReceiver("service_queue; {create: always}");
+
+       Message request = receiver.fetch();
+       const Address&amp; address = request.getReplyTo(); // Get "reply-to" 
from request ...
+       if (address) {
+       Sender sender = session.createSender(address); // ... send response to 
"reply-to"
+       Message response("pong!");
+       sender.send(response);
+       session.acknowledge();
+       }
+       ]]></programlisting>
+
+       <para>The client creates a sender for the service queue, and
+       also creates a response queue that is deleted when the
+       client closes the receiver for the response queue. In the C++
+       client, if the address starts with the character
+       <literal>#</literal>, it is given a unique name.</para>
+
+       <programlisting><![CDATA[
+       Sender sender = session.createSender("service_queue");
+
+       Address responseQueue("#response-queue; {create:always, 
delete:always}");
+       Receiver receiver = session.createReceiver(responseQueue);
+
+       Message request;
+       request.setReplyTo(responseQueue);
+       request.setContent("ping");
+       sender.send(request);
+       Message response = receiver.fetch();
+       std::cout << request.getContent() << " -> " << response.getContent() << 
std::endl;
+       ]]>       </programlisting>
+
+       <para>The client sends the string <literal>ping</literal> to
+       the server. The server sends the response
+       <literal>pong</literal> back to the same client, using the
+       <varname>replyTo</varname> property.</para>
+
+      </example>
+      <!--
+         <example>
+         <title>Request / Response Applications in Python</title>
+         <programlisting>### TODO</programlisting>
+         </example>
+      -->
+    </section>
+
+
+    <section>
+      <title>Performance Tips</title>
+
+      <itemizedlist>
+       <listitem>
+          <para>Consider prefetching messages for receivers (see
+          <xref linkend="prefetch"/>). This helps eliminate roundtrips
+          and increases throughput. Prefetch is disabled by default,
+          and enabling it is the most effective means of improving
+          throughput of received messages.</para>
+       </listitem>
+       <listitem>
+          <para>Send messages asynchronously. Again, this helps
+          eliminate roundtrips and increases throughput. The C++ and
+          .NET clients send asynchronously by default, however the
+          python client defaults to synchronous sends.  </para>
+       </listitem>
+       <listitem>
+          <para>Acknowledge messages in batches (see
+          <xref linkend="acknowledgements"/>). Rather than
+          acknowledging each message individually, consider issuing
+          acknowledgements after n messages and/or after a particular
+          duration has elapsed.</para>
+       </listitem>
+       <listitem>
+          <para>Tune the sender capacity (see
+          <xref linkend="replay"/>). If the capacity is too low the
+          sender may block waiting for the broker to confirm receipt
+          of messages, before it can free up more capacity.</para>
+       </listitem>
+       <listitem>
+          <para>If you are setting a reply-to address on messages
+          being sent by the c++ client, make sure the address type is
+          set to either queue or topic as appropriate. This avoids the
+          client having to determine which type of node is being
+          refered to, which is required when hanling reply-to in AMQP
+          0-10. </para>
+       </listitem>
+       <listitem>
+         <para>For latency sensitive applications, setting tcp-nodelay
+         on qpidd and on client connections can help reduce the
+         latency.</para>
+       </listitem>
+      </itemizedlist>
+    </section>
+
+    <section>
+      <title>Cluster Failover</title>
+
+      <para>The messaging broker can be run in clustering mode, which provides 
high reliability through replicating state between brokers in the cluster. If 
one broker in a cluster fails, clients can choose another broker in the cluster 
and continue their work. Each broker in the cluster also advertises the 
addresses of all known brokers
+
+      <footnote><para>This is done via the amq.failover exchange in AMQP 
0-10</para></footnote>
+
+      . A client can use this information to dynamically keep the list of 
reconnection urls up to date.</para>
+
+      <para>In C++, the <classname>FailoverUpdates</classname> class provides 
this functionality:</para>
+
+      <example>
+       <title>Tracking cluster membership</title>
+
+       <para>In C++:</para>
+
+       <programlisting><![CDATA[
+       #include <qpid/messaging/FailoverUpdates.h>
+       ...
+       Connection connection("localhost:5672");
+       connection.setOption("reconnect", true);
+       try {
+       connection.open();
+       std::auto_ptr<FailoverUpdates> updates(new FailoverUpdates(connection));
+       ]]>
+       </programlisting>
+
+       <para>In python:</para>
+
+       <programlisting><![CDATA[
+       import qpid.messaging.util
+       ...
+       connection = Connection("localhost:5672")
+       connection.reconnect = True
+       try:
+       connection.open()
+       auto_fetch_reconnect_urls(connection)
+       ]]>
+       </programlisting>
+       <para>
+         In .NET C#:
+       </para>
+
+       <programlisting>
+         using Org.Apache.Qpid.Messaging;
+         ...
+         connection = new Connection(&#34;localhost:5672&#34;);
+         connection.SetOption("reconnect", true);
+         try {
+         connection.Open();
+         FailoverUpdates failover = new FailoverUpdates(connection);
+
+       </programlisting>
+
+
+      </example>
+    </section>
+
+
+
+    <section>
+      <title>Logging</title>
+
+      <para>To simplify debugging, Qpid provides a logging facility
+      that prints out messaging events.</para>
+
+      <section>
+       <title>Logging in C++</title>
+       <para>
+         The Qpidd broker and C++ clients can both use environment variables 
to enable logging. Linux and Windows systems use the same named environment 
variables and values.
+       </para>
+       <para>Use QPID_LOG_ENABLE to set the level of logging you are 
interested in (trace, debug, info, notice, warning, error, or critical):
+       </para>
+
+       <screen>
+         export QPID_LOG_ENABLE=&#34;warning+&#34;
+       </screen>
+       <para>
+         The Qpidd broker and C++ clients use QPID_LOG_OUTPUT to determine 
where logging output should be sent. This is either a file name or the special 
values stderr, stdout, or syslog:
+       </para>
+
+       <screen>
+         export QPID_LOG_TO_FILE=&#34;/tmp/myclient.out&#34;
+       </screen>
+
+       <para>
+         From a Windows command prompt, use the following command format to 
set the environment variables:
+       </para>
+
+       <screen>
+         set QPID_LOG_ENABLE=warning+
+         set QPID_LOG_TO_FILE=D:\tmp\myclient.out
+       </screen>
+      </section>
+
+      <section>
+       <title>Logging in Python</title>
+       <para>
+         The Python client library supports logging using the standard Python 
logging module. The easiest way to do logging is to use the 
<command>basicConfig()</command>, which reports all warnings and errors:
+       </para>
+
+       <programlisting>from logging import basicConfig
+       basicConfig()
+       </programlisting>
+       <para>
+         Qpidd also provides a convenience method that makes it easy to 
specify the level of logging desired. For instance, the following code enables 
logging at the <command>DEBUG</command> level:
+       </para>
+
+       <programlisting>from qpid.log import enable, DEBUG
+       enable("qpid.messaging.io", DEBUG)
+       </programlisting>
+       <para>
+         For more information on Python logging, see <ulink 
url="http://docs.python.org/lib/node425.html";>http://docs.python.org/lib/node425.html</ulink>.
 For more information on Qpid logging, use <command>$ pydoc qpid.log</command>.
+       </para>
+      </section>
+    </section>
+
+
+
+    <section id="section-amqp0-10-mapping">
+      <title>The AMQP 0-10 mapping</title>
+
+      <para>
+       This section describes the AMQP 0-10 mapping for the Qpid
+       Messaging API.
+      </para>
+      <para>
+        The interaction with the broker triggered by creating a sender
+        or receiver depends on what the specified address resolves
+        to. Where the node type is not specified in the address, the
+        client queries the broker to determine whether it refers to a
+        queue or an exchange.
+      </para>
+      <para>
+        When sending to a queue, the queue's name is set as the
+        routing key and the message is transfered to the default (or
+        nameless) exchange. When sending to an exchange, the message
+        is transfered to that exchange and the routing key is set to
+        the message subject if one is specified. A default subject may
+        be specified in the target address. The subject may also be
+        set on each message individually to override the default if
+        required. In each case any specified subject is also added as
+        a qpid.subject entry in the application-headers field of the
+        message-properties.
+      </para>
+      <para>
+        When receiving from a queue, any subject in the source address
+        is currently ignored. The client sends a message-subscribe
+        request for the queue in question. The accept-mode is
+        determined by the reliability option in the link properties;
+        for unreliable links the accept-mode is none, for reliable
+        links it is explicit. The default for a queue is reliable. The
+        acquire-mode is determined by the value of the mode option. If
+        the mode is set to browse the acquire mode is not-acquired,
+        otherwise it is set to pre-acquired. The exclusive and
+        arguments fields in the message-subscribe command can be
+        controlled using the x-subscribe map.
+      </para>
+      <para>
+        When receiving from an exchange, the client creates a
+        subscription queue and binds that to the exchange. The
+        subscription queue's arguments can be specified using the
+        x-declare map within the link properties. The reliability
+        option determines most of the other parameters. If the
+        reliability is set to unreliable then an auto-deleted,
+        exclusive queue is used meaning that if the client or
+        connection fails messages may be lost. For exactly-once the
+        queue is not set to be auto-deleted. The durability of the
+        subscription queue is determined by the durable option in the
+        link properties. The binding process depends on the type of
+        the exchange the source address resolves to.
+      </para>
+
+      <itemizedlist>
+        <listitem>
+          <para>
+            For a topic exchange, if no subject is specified and no
+            x-bindings are defined for the link, the subscription
+            queue is bound using a wildcard matching any routing key
+            (thus satisfying the expectation that any message sent to
+            that address will be received from it). If a subject is
+            specified in the source address however, it is used for
+            the binding key (this means that the subject in the source
+            address may be a binding pattern including wildcards).
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            For a fanout exchange the binding key is irrelevant to
+            matching. A receiver created from a source address that
+            resolves to a fanout exchange receives all messages

[... 4017 lines stripped ...]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to