You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2012/03/05 22:31:59 UTC
svn commit: r1297234 [2/3] - in /qpid/trunk/qpid: cpp/design_docs/
cpp/src/qpid/ha/ cpp/src/tests/ doc/book/src/ tools/src/py/
Modified: qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml?rev=1297234&r1=1297233&r2=1297234&view=diff
==============================================================================
--- qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml (original)
+++ qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml Mon Mar 5 21:31:58 2012
@@ -3,24 +3,24 @@
<!--
- 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.
+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>
@@ -30,8 +30,8 @@
<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.
+ supports the AMQP messaging protocol in several common programming
+ languages. Qpid is supported on most common platforms.
</para>
<itemizedlist>
@@ -67,7 +67,7 @@
<title>Using the Qpid Messaging API</title>
<para>The Qpid Messaging API is quite simple, consisting of only a
- handful of core classes.
+ handful of core classes.
</para>
<itemizedlist>
@@ -126,29 +126,29 @@
<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>
+ 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] : "";
+ <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 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"/>
@@ -163,38 +163,38 @@ int main(int argc, char** argv) {
connection.close(); <co id="hello-cpp-close" linkends="callout-cpp-close"/>
return 0;
- } catch(const std::exception& error) {
+ } catch(const std::exception& error) {
<![CDATA[std::cerr << error.what() << std::endl;]]>
connection.close();
return 1;
- }
-}</programlisting>
+ }
+ }</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>
+ <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>
@@ -204,66 +204,66 @@ int main(int argc, char** argv) {
<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>
+ 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>
+ <title>"Hello world!" in Python</title>
+ <programlisting lang="python"><![CDATA[
+ import sys
+ from qpid.messaging import *
- </example>
+ 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>
@@ -274,86 +274,86 @@ finally:
<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.
+ <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();
- }
- }
- }
-}
+ <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>
+ </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>
+ <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>
@@ -386,43 +386,43 @@ namespace Org.Apache.Qpid.Messaging {
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>.
+ <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>.
+ <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>
+ <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>
+ <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
@@ -430,7 +430,7 @@ namespace Org.Apache.Qpid.Messaging {
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
+ .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—use the <command>-h</command> option
@@ -454,14 +454,14 @@ namespace Org.Apache.Qpid.Messaging {
<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>
+ <command>spout</command>, and read it using <command>drain</command>:</para>
<screen>
-$ qpid-config add queue hello-world
-$ ./spout hello-world
-$ ./drain hello-world
+ $ qpid-config add queue hello-world
+ $ ./spout hello-world
+ $ ./drain hello-world
-Message(properties={spout-id:c877e622-d57b-4df2-bf3e-6014c68da0ea:0}, content='')
+ 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
@@ -472,8 +472,8 @@ Message(properties={spout-id:c877e622-d5
<command>drain</command> one more time, no messages will be retrieved.</para>
<screen>
-$ ./drain hello-world
-$
+ $ ./drain hello-world
+ $
</screen>
</example>
@@ -488,16 +488,16 @@ $
and create an exchange with the same name:</para>
<screen>
-$ qpid-config del queue hello-world
-$ qpid-config add exchange topic hello-world
+ $ 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
-$
+ $ ./spout hello-world
+ $ ./drain hello-world
+ $
</screen>
<para>Topics deliver messages immediately to any interested
@@ -515,27 +515,27 @@ $
<para><emphasis>First Window:</emphasis></para>
<screen>
-$ ./drain -t 30 hello-word
+ $ ./drain -t 30 hello-word
</screen>
<para><emphasis>Second Window:</emphasis></para>
<screen>
-$ ./spout hello-word
+ $ ./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>
+ 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='')
+ 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>
+ windows; each creates a subscription for the exchange, and
+ each receives all messages sent to the exchange.</para>
</example>
@@ -551,9 +551,9 @@ Message(properties={spout-id:7da2d27d-93
<para>The syntax for an address string is:</para>
<programlisting><![CDATA[
-address_string ::= <address> [ / <subject> ] [ ; <options> ]
-options ::= { <key> : <value>, ... }
-]]></programlisting>
+ 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),
@@ -582,62 +582,62 @@ options ::= { <key> : <value>, ... }
If a receiver's address contains a subject, it is used to
select only messages that match the subject—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>
+ </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.
+ In AMQP 0-10, each exchange type has its own matching
+ algorithm. This is discussed in
+ <xref linkend="section-amqp0-10-mapping"/>.
</para>
- </note>
+ <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>
+ <example>
+ <title>Using subjects</title>
- <para>First, let's use <command>qpid-config</command> to create a topic exchange.</para>
+ <para>In this example we show how subjects affect message
+ flow.</para>
- <screen>
-$ qpid-config add exchange topic news-service
- </screen>
+ <para>First, let's use <command>qpid-config</command> to create a topic exchange.</para>
- <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>
+ <screen>
+ $ qpid-config add exchange topic news-service
+ </screen>
- <para>In a second window, let's send messages to <literal>news-service</literal> using two different subjects:</para>
+ <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><emphasis>Second Window:</emphasis></para>
- <screen>
-$ ./spout news-service/sports
-$ ./spout news-service/news
- </screen>
+ <para>In a second window, let's send messages to <literal>news-service</literal> using two different subjects:</para>
- <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>
+ <para><emphasis>Second Window:</emphasis></para>
+ <screen>
+ $ ./spout news-service/sports
+ $ ./spout news-service/news
+ </screen>
- <screen>
-Message(properties={qpid.subject:sports, spout-id:9441674e-a157-4780-a78e-f7ccea998291:0}, content='')
- </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
+ <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>
+ </example>
<para>The AMQP exchange type we are using here,
@@ -663,855 +663,855 @@ Message(properties={qpid.subject:sports,
like <literal>europe.news</literal> or
<literal>europe.pseudo.news</literal>.</para>
- <example>
- <title>Subjects with multi-word keys</title>
+ <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>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>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>
+ <para><emphasis>First Window:</emphasis></para>
- <screen>
-$ ./drain -t 30 news-service/*.news
- </screen>
+ <screen>
+ $ ./drain -t 30 news-service/*.news
+ </screen>
- <para>Now let's send messages using several different
- two-word keys:</para>
+ <para>Now let's send messages using several different
+ two-word keys:</para>
- <para><emphasis>Second Window:</emphasis></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>
+ <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>
+ <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>
+ <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>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>
+ <para><emphasis>First Window:</emphasis></para>
- <screen>
-$ ./drain -t 30 news-service/#.news
- </screen>
+ <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>In the second window, let's send messages using a
+ variety of different multi-word keys:</para>
- <para><emphasis>Second Window:</emphasis></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>
+ <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>
+ <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>
+ <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>
- <section>
- <title>Address String Options</title>
+ <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>
+ 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>
- 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.
+ In this section, we use the <literal>assert</literal> option
+ to ensure that the address resolves to a node of the required
+ type.
</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>
+ <example>
+ <title>Assertions on Nodes</title>
- <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>
+ <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>
- <example>
- <title>Assertions on Nodes</title>
+ <para>
+ We can now use the address specified to drain to assert that it is
+ of a particular type:
+ </para>
- <para>Let's use <command>qpid-config</command> to create a
- queue and a topic.</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>
- <screen>
-$ qpid-config add queue my-queue
-$ qpid-config add exchange topic my-topic
- </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>
- <para>
- We can now use the address specified to drain to assert that it is
- of a particular type:
- </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>
- <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>Now let's use the <literal>create</literal> option to
+ create the queue <literal>xoxox</literal> if it does not already
+ exist:</para>
- <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>
+ </section>
- <para>
- We can do the same thing for my-topic:
- </para>
+ <section>
+ <title>create</title>
- <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>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>
- <para>Now let's use the <literal>create</literal> option to
- create the queue <literal>xoxox</literal> if it does not already
- exist:</para>
+ <example>
+ <title>Creating a Queue Automatically</title>
- </section>
+ <para><emphasis>First Window:</emphasis></para>
+ <screen>$ ./drain -t 30 "xoxox ; {create: always}"</screen>
- <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>
+ <para>Now we can send messages to this queue:</para>
- <example>
- <title>Creating a Queue Automatically</title>
+ <para><emphasis>Second Window:</emphasis></para>
+ <screen>$ ./spout "xoxox ; {create: always}"</screen>
- <para><emphasis>First Window:</emphasis></para>
- <screen>$ ./drain -t 30 "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>
- <para>Now we can send messages to this queue:</para>
+ <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>
- <para><emphasis>Second Window:</emphasis></para>
- <screen>$ ./spout "xoxox ; {create: always}"</screen>
+ <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>Returning to the first window, we see that <command>drain</command> has received this message:</para>
+ <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>
- <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>
+ <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>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>
+ <section>
+ <title>x-bindings</title>
- <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>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>
- <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>
+ <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>
- <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>
+ <example>
+ <title>Using the XML Exchange</title>
- <section>
- <title>x-bindings</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>
- <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>
+ <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>An instance of the XML Exchange must be added before it
- can be used:</para>
+ <para><emphasis>First Window:</emphasis></para>
- <programlisting>
-$ qpid-config add exchange xml xml
- </programlisting>
+ <screen>
+ $ ./drain -f "xml; {link:{x-bindings:[{key:'weather',
+ arguments:{xquery:\"$(cat rdu.xquery )\"}}]}}"
+ </screen>
- <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>
+ <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[
-xml; {
- link: {
- x-bindings: [{exchange:xml, key:weather, arguments:{xquery:"./weather"} }]
- }
-}
- ]]></programlisting>
+ <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 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>
+ <!--
+ <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>
- <example>
- <title>Using the XML Exchange</title>
+<screen>
+spout - -content "$(cat rdu.xml | sed -e 's/70/45/')" xml/weather
+</screen>
+ -->
- <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>
+ <!--
+ TODO: Add some reliability option examples
+ -->
- <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>
+ <section>
+ <title>Address String Options - Reference</title>
- <para>We can specify this query in an x-binding to listen to messages that meet the criteria specified by the query:</para>
+ <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-most-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>
- <para><emphasis>First Window:</emphasis></para>
+ </section>
+ </section>
- <screen>
-$ ./drain -f "xml; {link:{x-bindings:[{key:'weather',
-arguments:{xquery:\"$(cat rdu.xquery )\"}}]}}"
- </screen>
+ <section id="section-address-string-bnf">
+ <title>Address String Grammar</title>
- <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>
+ <para>This section provides a formal grammar for address strings.</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>
+ <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>
- <para>Now let's use <command>spout</command> to send this message to the XML exchange:</para>
+ <formalpara>
+ <title>Grammar</title>
+ <para>The formal grammar for addresses is given below:</para>
+ </formalpara>
- <para><emphasis>Second Window:</emphasis></para>
- <screen>
-spout --content "$(cat rdu.xml)" xml/weather
- </screen>
+ <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>
- <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>
+ <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>
-<!--
- <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>
--->
+ </section>
- <!--
- TODO: Add some reliability option examples
- -->
+ <section id="replay">
+ <title>Sender Capacity and Replay</title>
- <section>
- <title>Address String Options - Reference</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>
- <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>
+ <section id="prefetch">
+ <title>Receiver Capacity (Prefetch)</title>
- <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-most-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>
+ <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>
-
- <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 id="acknowledgements">
+ <title>Acknowledging Received Messages</title>
-</section>
+ <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 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
[... 3140 lines stripped ...]
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org