From ef24db23518533a04a482da5ff2c014a38d2bb2c Mon Sep 17 00:00:00 2001 From: Jonathan Robie Date: Fri, 9 Apr 2010 20:59:38 +0000 Subject: Now relatively complete for C++ and Python, but properties were changing today as I was writing this, and this will need to be revised Monday. The next big step: adding information for Java clients. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@932610 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/doc/book/src/High-Level-API.xml | 753 +++++++++++++++++++---------------- 1 file changed, 411 insertions(+), 342 deletions(-) diff --git a/qpid/doc/book/src/High-Level-API.xml b/qpid/doc/book/src/High-Level-API.xml index 4049dfbafb..7e5fd4a80a 100644 --- a/qpid/doc/book/src/High-Level-API.xml +++ b/qpid/doc/book/src/High-Level-API.xml @@ -1,4 +1,30 @@ - + + + + + + + Qpid High Level Client API The Apache Qpid High Level Client API is a reliable, @@ -210,7 +236,7 @@ options ::= { : , ... } When a Sender sends a message to a queue, the message is sent to the AQMP 0-10 default queue, using the name - of teh queue as the routing key. + of the queue as the routing key. When a Receiver receives messages from a queue, it is treated as a normal AMQP 0-10 queue subscription. The accept-mode property can be set using @@ -250,13 +276,13 @@ options ::= { : , ... } Create a queue with qpid-config, send a message using spout, and read it using drain: - + $ qpid-config add queue hello-world $ ./spout -a hello-world $ ./drain -a hello-world Message(properties={spout-id:c877e622-d57b-4df2-bf3e-6014c68da0ea:0}, content='') - + Exchanges and queues are addressed in exactly the same way in the Qpid High Level Client API. If we delete the queue named @@ -264,13 +290,13 @@ Message(properties={spout-id:c877e622-d57b-4df2-bf3e-6014c68da0ea:0}, content='' same name, we can write to and read from the exchange in the same way as for the queue: - + $ qpid-config del queue hello-world $ qpid-config add exchange topic hello-world $ ./spout -a hello-world $ ./drain -a hello-world $ - + However, in AMQP 0-10, exchanges discard messages if no queue is bound to the exchange, unlike queues, which store @@ -283,25 +309,28 @@ $ run spout in another window to send a message for drain to receive. - First window: + + + First Window: - + $ ./drain -a hello-word -t 30 - + + - Second window: + Second Window: - + $ ./spout -a hello-word - + Once spout has sent a message, return to the first window to see the output from drain: - + Message(properties={spout-id:7da2d27d-93e6-4803-8a61-536d87b8d93f:0}, content='') - + You can run drain in several separate windows; each will create a subscription for the exchange, and @@ -350,29 +379,29 @@ Message(properties={spout-id:7da2d27d-93e6-4803-8a61-536d87b8d93f:0}, content='' Let's create a direct exchange and listen for messages whose subject is sports: - First window: - + First Window: + $ qpid-config add exchange direct direct-exchange $ ./drain -a direct-exchange/sports -t 30 - + In a second window, let's send messages to the exchange we created: - Second window: - + Second Window: + $ ./spout -a direct-exchange/sports $ ./spout -a direct-exchange/news - + Now look at the first window, and you will see the message with the subject sports has been received, but not the message with the subject news: - + Message(properties={qpid.subject:sports, spout-id:9441674e-a157-4780-a78e-f7ccea998291:0}, content='') - + If you run drain in multiple windows using the same subject, all instances of @@ -403,21 +432,21 @@ Message(properties={qpid.subject:sports, spout-id:9441674e-a157-4780-a78e-f7ccea Let's create a topic exchange and listen for messages whose subject is news: - First window: + First Window: - + $ qpid-config add exchange topic topic-exchange $ ./drain -a topic-exchange/news -t 30 - + In a second window, let's send messages to the exchange we created: - Second window: - + Second Window: + $ ./spout -a topic-exchange/news $ ./spout -a topic-exchange/sports - + Now look at the first window, and you will see the @@ -425,9 +454,9 @@ $ ./spout -a topic-exchange/sports received, but not the message with the subject sports: - + Message(properties={qpid.subject:news, spout-id:bafefb74-c5be-4a8b-9e4b-45f7a855e250:0}, content='') - + Now let's use the topic exchange with wildcards in the @@ -438,33 +467,33 @@ Message(properties={qpid.subject:news, spout-id:bafefb74-c5be-4a8b-9e4b-45f7a855 news: - First window: + First Window: - + $ ./drain -a topic-exchange/*.news -t 30 - + Now let's send messages using several different two-word keys: - Second window: + Second Window: - + $ ./spout -a topic-exchange/usa.news $ ./spout -a topic-exchange/usa.sports $ ./spout -a topic-exchange/europe.sports $ ./spout -a topic-exchange/europe.news $ - + Now look at the first window, and you will see the messages with news in the second word of the key have been received: - + 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='') - + Finally, let's use the # wildcard in the Receiver to match any number of words in the key. The @@ -473,35 +502,35 @@ Message(properties={qpid.subject:europe.news, spout-id:f72815aa-7be4-4944-99fd-c news, no matter how many words are in the key: - First window: + First Window: - + $ ./drain -a topic-exchange/#.news -t 30 - + Now let's send messages using a variety of different multi-word keys: - Second window: + Second Window: - + $ ./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 - + Now look at the first window, and you will see the messages with news in the last word of the key have been received: - + 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='') - + @@ -517,29 +546,29 @@ Message(properties={qpid.subject:usa.faux.news, spout-id:6029430a-cfcb-4700-8e9b actually used to filter messages: - First window: + First Window: - + $ qpid-config add exchange fanout fanout-exchange $ ./drain -a fanout-exchange/news -t 30 - + Now let's send a message using a different subject: - Second window: + Second Window: - + $ ./spout -a fanout-exchange/sports - + 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: - + Message(properties={qpid.subject:sports, spout-id:931399a1-27fc-471c-8dbe-3048260f9441:0}, content='') - + This happens because of the routing semantics of the AMQP 0-10 fanout exchange. @@ -556,38 +585,39 @@ Message(properties={qpid.subject:sports, spout-id:931399a1-27fc-471c-8dbe-304826 Let's create a queue and listen for messages on it. - First window: + First Window: - + $ ./qpid-config add queue amqp010-queue $ ./drain -a amqp010-queue -t 30 - + Now let's send some messages. The subject is not used for routing purposes. - + $ ./spout -a amqp010-queue/news $ ./spout -a amqp010-queue - + Now look at the first window, and you will see that both messages have been received: - + 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='') - + - + +
Custom Exchanges - 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. + 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. @@ -597,7 +627,63 @@ Message(properties={spout-id:c8ab5013-a19e-4f54-967c-797c8ad6568b:0}, content=''
- Options + Extended Address Options + + + + Extended Address Options are parameters that affect the behavior of Senders and Receivers. + + Some of these options specify aspects of the resolution process; for instance, they may make assertions that must be satisfied in order for resolution to succeed, or they may state that the node should be created if it does not already exist. + + Let's use drain and spout to show how this works. First, let's use the assert option to insist that an address must resolve to a queue. In the High Level Client API, a node is either a queue or a topic. A queue is used the same way as in AMQP 0-10, but for consistency with Java JMS, a topic node is the same thing AMQP 0-10 calls an exchange.(In this section, we will use the term topic node for a High Level Client API topic node, and AMQP 0-10 topic exchange for the exchange type that has the same name.) + + AMQP 0-10 has several built-in exchanges that are predeclared: amq.topic, amq.direct, amq.match, and amq.fanout. To the High Level Exchange, any of these exchanges is considered a topic node. Let's use drain, and assert that amq.fanout is a topic node: + + $ ./drain -a "amq.fanout; { assert: always, node: { type: topic }}" + + The address resolves succesfully. No exception is raised, because a topic node named amq.fanout exists. Now let's assert that amq.fanout is a queue node: + + $ ./drain -a "amq.fanout; { assert: always, node: { type: queue }}" +2010-04-09 14:01:35 warning Exception received from broker: not-found: not-found: Queue not found: amq.fanout (qpid/broker/SessionAdapter.cpp:753) [caused by 0 \x08:\x01] +Queue amq.fanout does not exist + + An exception was raised because there is no queue named amq.fanout, so address resolution failed. + + + Now let's use the create option with drain, telling it to create the queue xoxox if it does not already exist: + + First Window: + $ ./drain -a "xoxox ; {create: always}" -t 30 + + In previous examples, we created the queue before listening for messages on it. Using create: always, the queue is automatically created if it does not exist. Now we can send messages to this queue: + + Second Window: + $ ./drain -a "xoxox ; {create: always}" -t 30 + + Returning to the first window, we see that drain has received this message: + + Message(properties={spout-id:1a1a3842-1a8b-4f88-8940-b4096e615a7d:0}, content='') + + + + + Other options specify message transfer semantics; for instance, they may state whether messages should be consumed or read in browsing mode, or specify reliability characteristics. For instance, we can use browse mode to receive messages without removing them from the queue, thus allowing other Readers to receive them: + + +$ ./drain 'hello-queue; {mode: browse}' + + - - - an extended address can include a subject and options (we'll get to the options later) - + subject is a standard message property - - subjects classify messages - + when you specify a subject in a target address, that value - becomes the default subject property on outgoing Messages (this - can be overriden by setting the subject explicitly on each - messages) - - extended address options adjust the semantics of senders/receivers - + some options control the resolution process: - - assert/create/delete, node-properties - - more on this later + + Extended Address Options + + + + option + parameters + semantics + + + + + + assert + + + node + + + Asserts that the node properties are satisfied for a + node. If they are not, node resolution fails and an + exception is raised. + + + + + + create + + + node (optional) + + + Creates the node if it does not exist. No error is raised if the node does exist. + + + + + delete + + + N/A + + + Delete the node when the Sender or Receiver is closed. + + + + + reliability + + + unreliable, at-least-once, at-most-once, exactly-once + + + + + + + mode + + + browse, consume + + + + + + + reconnect + + + True, False + + + Transparently reconnect if the connection is lost. + + + + + reconnect_timeout + + + N + + + Total number of seconds to continue reconnection attempts before giving up and raising an exception. + + + + + reconnect_limit + + + N + + + Maximum number of reconnection attempts before giving up and raising an exception. + + + + + reconnect_interval_min + + + N + + + Minimum number of seconds between reconnection attempts. The first reconnection attempt is made immediately; if that fails, the first reconnection delay is set to the value of reconnect_interval_min; if that attempt fails, the reconnection interval increases exponentially until a reconnection attempt succeeds or reconnect_interval_max is reached. + + + + + reconnect_interval_max + + + N + + + Maximum reconnection interval. + + + + + reconnection_interval + + + N + + + Sets both reconnection_interval_min and reconnection_interval_max to the same value. + + + + +
+ + + + Node Properties + + + + property + parameters + semantics + + + + + + type + + + topic, queue + + + + + + + durable + + + True, False + + + + + + + x-declare + + + unrestricted map + + + If the property is defined in the underlying protocol (AMQP 0-10), the values and semantics are defined by the protocol. Otherwise, values are added to the arguments map used to declare topicsThe High Level Client API, like Java JMS, uses the term topic to refer to what AMQP 0-10 calls an exchange. One kind of AMQP 0-10 exchange is called a topic exchange, that is not what is meant here. or queues. + + + + +
- + some options control message transfer semantics: - - reliability: unreliable/at-least-once/at-most-once/exactly-once - - mode: browse/consume (only for receivers) ---> - - + + x-declare properties for AMQP 0-10 + + + + property + parameters + semantics + + + + + + type + + + direct, topic, fanout, header, xml + + + The AMQP 0-10 exchange type. + + + + + bindings + + + ["exchange/binding-key", ... ] + + + This property is used to create bindings for queues. If the Address does not resolve to a queue, an error is raised. + + + + +
@@ -715,6 +969,24 @@ SH: spout small-world/news.local properties are mapped to AMQP message properties and delivery properties. + Request-response applications frequently use a reply-to property to tell a server where to send a response. The following code shows how a server extracts the reply-to property and uses it to set the address to respond to a client. + + + Message request = receiver.fetch(); + const Address& address = request.getReplyTo(); Get "reply-to" field from request ... + if (address) { + Sender sender = session.createSender(address); ... and use it as the address to send response + std::string s = request.getContent(); + std::transform(s.begin(), s.end(), s.begin(), toupper); + Message response(s); + sender.send(response); + std::cout << "Processed request: " + << request.getContent() + << " -> " + << response.getContent() << std::endl; + session.acknowledge(); + + In the following table, msg refers to the Message class defined in the High Level Client API, mp refers to an AMQP 0-10 @@ -780,37 +1052,6 @@ Examples - do client / server, pub-sub here... \ No newline at end of file -- cgit v1.2.1