summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2006-12-13 19:03:52 +0000
committerGordon Sim <gsim@apache.org>2006-12-13 19:03:52 +0000
commit8e367bd7aa3d0fc3517f093e117e53bbe7c1f83d (patch)
tree906c287bfc338cdfe981a906a20858db7ee4d381
parentaefda495b3452c599ea92cdb22b1d01b7ceed11d (diff)
downloadqpid-python-8e367bd7aa3d0fc3517f093e117e53bbe7c1f83d.tar.gz
A bit more documentation for the client tests which are currently doubling as examples.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@486797 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--cpp/tests/client_test.cpp56
-rw-r--r--cpp/tests/echo_service.cpp32
-rw-r--r--cpp/tests/topic_listener.cpp26
-rw-r--r--cpp/tests/topic_publisher.cpp24
4 files changed, 128 insertions, 10 deletions
diff --git a/cpp/tests/client_test.cpp b/cpp/tests/client_test.cpp
index 5ee53e3fa8..6a22a65ad2 100644
--- a/cpp/tests/client_test.cpp
+++ b/cpp/tests/client_test.cpp
@@ -18,6 +18,14 @@
* under the License.
*
*/
+
+/**
+ * This file provides a simple test (and example) of basic
+ * functionality including declaring an exchange and a queue, binding
+ * these together, publishing a message and receiving that message
+ * asynchronously.
+ */
+
#include <iostream>
#include <QpidError.h>
@@ -32,14 +40,19 @@ using namespace qpid::client;
using namespace qpid::sys;
using std::string;
+/**
+ * A simple message listener implementation that prints out the
+ * message content then notifies a montitor allowing the test to
+ * complete.
+ */
class SimpleListener : public virtual MessageListener{
Monitor* monitor;
public:
inline SimpleListener(Monitor* _monitor) : monitor(_monitor){}
- inline virtual void received(Message& /*msg*/){
- std::cout << "Received message " /**<< msg **/<< std::endl;
+ inline virtual void received(Message& msg){
+ std::cout << "Received message " << msg.getData() << std::endl;
monitor->notify();
}
};
@@ -47,44 +60,67 @@ public:
int main(int argc, char**)
{
try{
- Connection con(argc > 1);
- Channel channel;
+ //Use a custom exchange
Exchange exchange("MyExchange", Exchange::TOPIC_EXCHANGE);
+ //Use a named, temporary queue
Queue queue("MyQueue", true);
-
- string host("localhost");
-
+
+ //Create and open a connection
+ Connection con(argc > 1);
+ string host("localhost");
con.open(host);
std::cout << "Opened connection." << std::endl;
+
+ //Create and open a channel on the connection through which
+ //most functionality is exposed
+ Channel channel;
con.openChannel(&channel);
std::cout << "Opened channel." << std::endl;
+
+ //'declare' the exchange and the queue, which will create them
+ //as they don't exist
channel.declareExchange(exchange);
std::cout << "Declared exchange." << std::endl;
channel.declareQueue(queue);
std::cout << "Declared queue." << std::endl;
+
+ //now bind the queue to the exchange
qpid::framing::FieldTable args;
channel.bind(exchange, queue, "MyTopic", args);
std::cout << "Bound queue to exchange." << std::endl;
- //set up a message listener
+ //Set up a message listener to receive any messages that
+ //arrive in our queue on the broker. We only expect one, and
+ //as it will be received on another thread, we create a
+ //montior to use to notify the main thread when that message
+ //is received.
Monitor monitor;
SimpleListener listener(&monitor);
string tag("MyTag");
channel.consume(queue, tag, &listener);
- channel.start();
std::cout << "Registered consumer." << std::endl;
+ //we need to enable the message dispatching for this channel
+ //and we want that to occur on another thread so we call
+ //start().
+ channel.start();
+
+ //Now we create and publish a message to our exchange with a
+ //routing key that will cause it to be routed to our queue
Message msg;
string data("MyMessage");
msg.setData(data);
channel.publish(msg, exchange, "MyTopic");
- std::cout << "Published message." << std::endl;
+ std::cout << "Published message: " << data << std::endl;
{
Monitor::ScopedLock l(monitor);
+ //now we wait until we receive notification that the
+ //message was received
monitor.wait();
}
+ //close the channel & connection
con.closeChannel(&channel);
std::cout << "Closed channel." << std::endl;
con.close();
diff --git a/cpp/tests/echo_service.cpp b/cpp/tests/echo_service.cpp
index c6685476a3..666c8cfa46 100644
--- a/cpp/tests/echo_service.cpp
+++ b/cpp/tests/echo_service.cpp
@@ -18,6 +18,15 @@
* under the License.
*
*/
+
+/**
+ * This class provides an example of using AMQP for a request-response
+ * style system. 'Requests' are messages sent to a well known
+ * destination. A 'service' process consumes these message and
+ * responds by echoing the message back to the sender on a
+ * sender-specified private queue.
+ */
+
#include <QpidError.h>
#include <ClientChannel.h>
#include <Connection.h>
@@ -32,6 +41,11 @@ using namespace qpid::client;
using namespace qpid::sys;
using std::string;
+
+/**
+ * A message listener implementation representing the 'service', this
+ * will 'echo' any requests received.
+ */
class EchoServer : public MessageListener{
Channel* const channel;
public:
@@ -39,11 +53,19 @@ public:
virtual void received(Message& msg);
};
+/**
+ * A message listener implementation that merely prints received
+ * messages to the console. Used to report on 'echo' responses.
+ */
class LoggingListener : public MessageListener{
public:
virtual void received(Message& msg);
};
+/**
+ * A utility class that manages the command line options needed to run
+ * the example confirgurably.
+ */
class Args{
string host;
int port;
@@ -62,6 +84,11 @@ public:
inline bool getClient() const { return client; }
};
+/**
+ * The main test path. There are two basic modes: 'client' and
+ * 'service'. First one or more services are started, then one or more
+ * clients are started and messages can be sent.
+ */
int main(int argc, char** argv){
const std::string echo_service("echo_service");
Args args;
@@ -69,6 +96,8 @@ int main(int argc, char** argv){
if (args.getHelp()) {
args.usage();
} else if (args.getClient()) {
+ //we have been started in 'client' mode, i.e. we will send an
+ //echo requests and print responses received.
try {
//Create connection & open a channel
Connection connection(args.getTrace());
@@ -110,6 +139,9 @@ int main(int argc, char** argv){
std::cout << error.what() << std::endl;
}
} else {
+ // we are in 'service' mode, i.e. we will consume messages
+ // from the request queue and echo each request back to the
+ // senders own private response queue.
try {
//Create connection & open a channel
Connection connection(args.getTrace());
diff --git a/cpp/tests/topic_listener.cpp b/cpp/tests/topic_listener.cpp
index 73ca243f35..06c1765786 100644
--- a/cpp/tests/topic_listener.cpp
+++ b/cpp/tests/topic_listener.cpp
@@ -18,6 +18,20 @@
* under the License.
*
*/
+
+/**
+ * This file provides one half of a test and example of a pub-sub
+ * style of interaction. See topic_publisher.cpp for the other half,
+ * in which the logic for publishing is defined.
+ *
+ * This file contains the listener logic. A listener will subscribe to
+ * a logical 'topic'. It will count the number of messages it receives
+ * and the time elapsed between the first one and the last one. It
+ * recognises two types of 'special' message that tell it to (a) send
+ * a report containing this information, (b) shutdown (i.e. stop
+ * listening).
+ */
+
#include <QpidError.h>
#include <ClientChannel.h>
#include <Connection.h>
@@ -32,6 +46,10 @@ using namespace qpid::client;
using namespace qpid::sys;
using std::string;
+/**
+ * A message listener implementation in which the runtime logic is
+ * defined.
+ */
class Listener : public MessageListener{
Channel* const channel;
const std::string responseQueue;
@@ -47,6 +65,9 @@ public:
virtual void received(Message& msg);
};
+/**
+ * A utility class for managing the options passed in.
+ */
class Args{
string host;
int port;
@@ -69,6 +90,11 @@ public:
inline bool getHelp() const { return help; }
};
+/**
+ * The main routine creates a Listener instance and sets it up to
+ * consume from a private queue bound to the exchange with the
+ * appropriate topic name.
+ */
int main(int argc, char** argv){
Args args;
args.parse(argc, argv);
diff --git a/cpp/tests/topic_publisher.cpp b/cpp/tests/topic_publisher.cpp
index 86dae8e172..b95abd9d66 100644
--- a/cpp/tests/topic_publisher.cpp
+++ b/cpp/tests/topic_publisher.cpp
@@ -18,6 +18,22 @@
* under the License.
*
*/
+
+/**
+ * This file provides one half of a test and example of a pub-sub
+ * style of interaction. See topic_listener.cpp for the other half, in
+ * which the logic for subscribers is defined.
+ *
+ * This file contains the publisher logic. The publisher will send a
+ * number of messages to the exchange with the appropriate routing key
+ * for the logical 'topic'. Once it has done this it will then send a
+ * request that each subscriber report back with the number of message
+ * it has received and the time that elapsed between receiving the
+ * first one and receiving the report request. Once the expected
+ * number of reports are received, it sends out a request that each
+ * subscriber shutdown.
+ */
+
#include <QpidError.h>
#include <ClientChannel.h>
#include <Connection.h>
@@ -34,6 +50,11 @@ using namespace qpid::client;
using namespace qpid::sys;
using std::string;
+/**
+ * The publishing logic is defined in this class. It implements
+ * message listener and can therfore be used to receive messages sent
+ * back by the subscribers.
+ */
class Publisher : public MessageListener{
Channel* const channel;
const std::string controlTopic;
@@ -51,6 +72,9 @@ public:
void terminate();
};
+/**
+ * A utility class for managing the options passed in to the test
+ */
class Args{
string host;
int port;