summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qpid/doc/book/src/High-Level-API.xml392
1 files changed, 318 insertions, 74 deletions
diff --git a/qpid/doc/book/src/High-Level-API.xml b/qpid/doc/book/src/High-Level-API.xml
index 3116846159..4049dfbafb 100644
--- a/qpid/doc/book/src/High-Level-API.xml
+++ b/qpid/doc/book/src/High-Level-API.xml
@@ -108,7 +108,7 @@ int main() {
<title>A Message Sender</title>
<para>The sender program creates a Sender object that sends messages
to <varname>message_queue</varname>, which happens to be a queue on
- on AMQP 0-10 messaging broker:</para>
+ on AMQP 0-10 messaging broker.</para>
<programlisting><![CDATA[
Sender sender = session.createSender("message_queue");
@@ -121,6 +121,10 @@ int main() {
sender.close();
}]]></programlisting>
+ <para> The AMQP 0-10 mapping implements this by sending messages
+ to the default exchange, with <varname>message_queue</varname> as
+ the routing key.</para>
+
</section>
<section>
<title>A Message Receiver</title>
@@ -268,73 +272,330 @@ $ ./drain -a hello-world
$
</programlisting>
- <para>In AMQP 0-10, exchanges discard messages if ####</para>
+ <para>However, in AMQP 0-10, exchanges discard messages if no
+ queue is bound to the exchange, unlike queues, which store
+ messages until they are retrieved. Because of this, no messages
+ were output in the above screen. If <command>drain</command> is
+ called before <command>spout</command>, a Receiver is created
+ for the exchange, which also creates a subscription queue and a
+ binding. Run <command>drain</command> in one terminal window
+ using <literal>-t</literal> to specify a timeout in seconds, and
+ run <command>spout</command> in another window to send a message
+ for <command>drain</command> to receive.</para>
-<!--
+ <para>First window:</para>
+
+ <programlisting>
+$ ./drain -a hello-word -t 30
+ </programlisting>
+
+ <para>Second window:</para>
+
+ <programlisting>
+$ ./spout -a hello-word
+ </programlisting>
+
+ <para>Once <command>spout</command> has sent a message, return
+ to the first window to see the output from
+ <command>drain</command>:</para>
+
+ <programlisting>
+Message(properties={spout-id:7da2d27d-93e6-4803-8a61-536d87b8d93f:0}, content='')
+ </programlisting>
+
+ <para>You can run <command>drain</command> in several separate
+ windows; each will create a subscription for the exchange, and
+ each will receive all messages sent to the exchange.</para>
-SH: qpid-config add queue hello-world
- - once created, an address simply refers to them by name
-SH: spout -c 10 hello-world
-SH: drain hello-world
-SH: qpid-config
- + this works the same for exchanges
-SH: qpid-config del queue hello-world
-SH: qpid-config add exchange topic hello-world
-SH: spout -c 10 hello-world
-SH: drain hello-world
- - client code remains exactly the same, but routing behavior
- changes
- - exchanges drop messages if nobody is listening, so we need to
- start drain first
- - drain will exit immediately if the source is empty (note that
- this is actually a semantic guarantee provided by the API, we
- know for a fact that the source is empty when drain/fetch
- reports it, no fudge factor timeout is required [this assumes
- nobody is concurrently publishing of course])
- - drain -f invokes blocking fetch (you could use a timeout here also)
-SH1: drain -f hello-world
-SH: spout -c 10 hello-world
-SH2: drain -f hello-world
-SH: spout -c 10 hello-world
- - multiple drains will get all messages because this is an
- exchange
- - for a queue messages will be load balanced between drains
-SH: qpid-config add queue hello-queue
-SH1: drain -f hello-world
-SH2: drain -f hello-world
-SH: spout -c 10 hello-world
- + an address is resolved to a node
- - the API internals will adjust how they send/receive based on
- the type of node
- - in AMQP 0-10 exchanges and queues are the two standard
- categories of nodes
- - in JMS these are called topics and queues
- - we use the topic terminology to be consistent with JMS (note
- that when used in this sense topic refers to any exchange, not
- just a topic exchange)
- - we'll cover the precise details of the mapping later
--->
</example>
</section>
<section>
<title>Subjects</title>
- <para>
- A simple name with a subject will also resolve to a node, but the
- presence of the subject will cause a sender using this address to
- set the subject on outgoing messages, and receivers to filter based
- on the subject:
+ <para>Subjects are used to classify messages.</para>
+
+ <para>A Sender's subject is assigned to each message that it
+ sends (this can be overridden by specifying a subject directly
+ on the message). In the AMQP 0-10 mapping, the message's subject
+ is used as the routing key for all messages sent to the
+ messaging broker. If a Sender is bound to an AMQP 0-10 exchange,
+ it sends messages to that exchange. If a Sender is bound to an
+ AMQP 0-10 queue, the message is sent to the default
+ exchange.</para>
+
+ <para>A Receiver's subject is used to filter messages; only
+ messages with a subject that matches the Receiver's subject will
+ be received. If a Receiver's name resolves to an AMQP 0-10
+ exchange, the subject is used as a binding key for the
+ corresponding AMQP 0-10 exchange type.
+ </para>
- my-queue-or-topic/my-subject
+ <note>
+ <para>The C++ implementation of the Qpid messaging broker does
+ not currently support selectors, so a Receiver's subject does
+ not filter messages if the Receiver's address resolves to a
+ queue.</para>
+ </note>
+
+ <section>
+ <title>Direct Exchanges</title>
+
+ <para>In an AMQP 0-10 direct exchange, messages are routed
+ to queues if the routing key exactly matches the binding
+ key. In the High Level Client API, if a Sender and a
+ Receiver are bound to the same exchange, the Receiver will
+ receive messages if the Sender's subject matches the
+ Receiver's subject.</para>
+
+ <para>Let's create a direct exchange and listen for messages
+ whose subject is <literal>sports</literal>:</para>
+
+ <para>First window:</para>
+ <programlisting>
+$ qpid-config add exchange direct direct-exchange
+$ ./drain -a direct-exchange/sports -t 30
+ </programlisting>
+
+ <para>In a second window, let's send messages to the
+ exchange we created:</para>
+
+ <para>Second window:</para>
+ <programlisting>
+$ ./spout -a direct-exchange/sports
+$ ./spout -a direct-exchange/news
+ </programlisting>
+
+ <para>Now look at the first window, and you will see the
+ message with the subject <literal>sports</literal> has been
+ received, but not the message with the subject
+ <literal>news</literal>:</para>
+
+ <programlisting>
+Message(properties={qpid.subject:sports, spout-id:9441674e-a157-4780-a78e-f7ccea998291:0}, content='')
+ </programlisting>
+
+ <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>
+
+ </section>
+ <section>
+ <title>Topic Exchanges</title>
+
+ <para>An AMQP 0-10 topic exchange uses routing keys that
+ contain multiple words separated by a <quote>.</quote>
+ delimiter. For instance, in a news application, a Sender's
+ subject might be <literal>usa.news</literal>,
+ <literal>usa.weather</literal>,
+ <literal>europe.news</literal>, or
+ <literal>europe.weather</literal>. A 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 Receiver's
+ subject is <literal>*.news</literal>, it matches messages
+ with the subject <literal>europe.news</literal> or
+ <literal>usa.news</literal>; if the Receiver's subject is
+ <literal>europe.#</literal>, it matches messages with
+ subjects like <literal>europe.news</literal> or
+ <literal>europe.pseudo.news</literal>.</para>
+
+ <para>Let's create a topic exchange and listen for messages
+ whose subject is <literal>news</literal>:</para>
+
+ <para>First window:</para>
+
+ <programlisting>
+$ qpid-config add exchange topic topic-exchange
+$ ./drain -a topic-exchange/news -t 30
+ </programlisting>
+
+ <para>In a second window, let's send messages to the
+ exchange we created:</para>
+
+ <para>Second window:</para>
+ <programlisting>
+$ ./spout -a topic-exchange/news
+$ ./spout -a topic-exchange/sports
+ </programlisting>
+
+
+ <para>Now look at the first window, and you will see the
+ message with the subject <literal>news</literal> has been
+ received, but not the message with the subject
+ <literal>sports</literal>:</para>
+
+ <programlisting>
+Message(properties={qpid.subject:news, spout-id:bafefb74-c5be-4a8b-9e4b-45f7a855e250:0}, content='')
+ </programlisting>
+
+
+ <para>Now let's use the topic exchange with wildcards in the
+ Receiver and multi-word keys in the Sender. This time, let's
+ use two-word keys. The Receiver uses the subject
+ <literal>*.news</literal> to listen for messages in which
+ the second word of the key is
+ <literal>news</literal>:</para>
+
+
+ <para>First window:</para>
+
+ <programlisting>
+$ ./drain -a topic-exchange/*.news -t 30
+ </programlisting>
+
+ <para>Now let's send messages using several different
+ two-word keys:</para>
- A subject pattern can be used and will cause filtering if used by
- the receiver. If used for a sender, the literal value gets set as
- the subject::
+ <para>Second window:</para>
- my-queue-or-topic/my-*
+ <programlisting>
+$ ./spout -a topic-exchange/usa.news
+$ ./spout -a topic-exchange/usa.sports
+$ ./spout -a topic-exchange/europe.sports
+$ ./spout -a topic-exchange/europe.news
+$
+ </programlisting>
+
+ <para>Now look at the first window, and you will see the
+ messages with <literal>news</literal> in the second word of
+ the key have been received:</para>
+
+ <programlisting>
+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='')
+ </programlisting>
+
+ <para>Finally, let's use the <literal>#</literal> wildcard
+ in the Receiver to match any number of words in the key. The
+ Receiver uses the key <literal>#.news</literal> to listen
+ for messages in which the last word of the key is
+ <literal>news</literal>, no matter how many words are in the
+ key:</para>
+
+ <para>First window:</para>
+
+ <programlisting>
+$ ./drain -a topic-exchange/#.news -t 30
+ </programlisting>
+
+ <para>Now let's send messages using a variety of different
+ multi-word keys:</para>
+
+ <para>Second window:</para>
+
+ <programlisting>
+$ ./spout -a topic-exchange/news
+$ ./spout -a topic-exchange/sports
+$ ./spout -a topic-exchange/usa.news
+$ ./spout -a topic-exchange/usa.sports
+$ ./spout -a topic-exchange/usa.faux.news
+$ ./spout -a topic-exchange/usa.faux.sports
+ </programlisting>
+
+ <para>Now look at the first window, and you will see the
+ messages with <literal>news</literal> in the last word of
+ the key have been received:</para>
+
+ <programlisting>
+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='')
+ </programlisting>
+
+ </section>
+
+ <section>
+ <title>Fanout Exchanges</title>
+
+ <para>A fanout exchange ignores the subject, and no
+ filtering is done.</para>
+
+ <para>Let's create a fanout exchange and listen for
+ messages. We will use the subject <literal>news</literal>
+ in the Receiver to demonstrate that this subject is not
+ actually used to filter messages:</para>
+
+
+ <para>First window:</para>
+
+ <programlisting>
+$ qpid-config add exchange fanout fanout-exchange
+$ ./drain -a fanout-exchange/news -t 30
+ </programlisting>
+
+ <para>Now let's send a message using a different
+ subject:</para>
+
+ <para>Second window:</para>
+
+ <programlisting>
+$ ./spout -a fanout-exchange/sports
+ </programlisting>
+
+ <para>Returning to the first window, we see that the message
+ was received even though the Receiver's subject was
+ different from the Sender's subject:</para>
+
+ <programlisting>
+Message(properties={qpid.subject:sports, spout-id:931399a1-27fc-471c-8dbe-3048260f9441:0}, content='')
+ </programlisting>
+
+ <para>This happens because of the routing semantics of the AMQP 0-10 fanout exchange.</para>
+
+ </section>
+
+ </section>
+ <section>
+ <title>Queues</title>
+
+ <para>If a Sender is bound to a queue, its messages are sent
+ to the default exchange using the queue's name as the
+ routing key. If a Receiver is bound to a queue, it receives
+ messages from the queue.</para>
+
+ <para>Let's create a queue and listen for messages on it.</para>
+
+ <para>First window:</para>
+
+ <programlisting>
+$ ./qpid-config add queue amqp010-queue
+$ ./drain -a amqp010-queue -t 30
+ </programlisting>
+
+ <para>Now let's send some messages. The subject is not used for routing purposes.</para>
+ <programlisting>
+$ ./spout -a amqp010-queue/news
+$ ./spout -a amqp010-queue
+ </programlisting>
+
+ <para>Now look at the first window, and you will see that
+ both messages have been received:</para>
+
+ <programlisting>
+Message(properties={qpid.subject:news, spout-id:6c769437-60be-4bc0-9bf6-5a77cb6ba65f:0}, content='')
+Message(properties={spout-id:c8ab5013-a19e-4f54-967c-797c8ad6568b:0}, content='')
+ </programlisting>
+
+ </section>
+
+
+ <!-- ### header exchange? -->
+ <section>
+ <title>Custom Exchanges</title>
+
+ <para>AMQP 0-10 also supports custom exchanges. The
+ Qpid messaging broker includes the XML Exchange, which uses an
+ XQuery to filter messages based on message properties and XML
+ message content.</para>
+
+<!-- ### Do drain / spout support the XML Exchange? -->
+
+ </section>
- </para>
</section>
+
+
<section>
<title>Options</title>
@@ -442,7 +703,6 @@ SH: spout small-world/news.local
-->
<para></para>
- </section>
</section>
@@ -512,28 +772,12 @@ SH: spout small-world/news.local
</tgroup>
</table>
- </section>
-</chapter>
-
<!--
- * qpid.messaging.address
- * qpid.messaging.constants
- * qpid.messaging.driver
- * qpid.messaging.endpoints: A candidate high level messaging API for python.
- * qpid.messaging.exceptions
- * qpid.messaging.message
- * message hierarchy
- * qpid.messaging.util: Add-on utilities for the qpid.messaging API.
-
+Examples - do client / server, pub-sub here...
-->
-<!--
-
- <section>
- <title>Example Programs</title>
</section>
</chapter>
--->
<!--
- drain and spout are basically command line versions of the API