You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2010/05/05 13:17:42 UTC
svn commit: r941250 - in /qpid/trunk/qpid: cpp/examples/messaging/
cpp/examples/messaging/extra_dist/ doc/book/src/
Author: gsim
Date: Wed May 5 11:17:41 2010
New Revision: 941250
URL: http://svn.apache.org/viewvc?rev=941250&view=rev
Log:
Some cleanup on examples:
* removed obsolete examples (queue-/topic-sender/receiver)
* removed the need to include headers with boost dependencies
* moved the argument handling in darin and spout closer to that of python (and update docs to reflect that)
* changed to ship a manually constructed makefile for messaging examples (generated one doesn't work and maintaining that seems like more work with little benefit)
Added:
qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp
qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h
qpid/trunk/qpid/cpp/examples/messaging/extra_dist/
qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile
Removed:
qpid/trunk/qpid/cpp/examples/messaging/messaging_queue_receiver.vcproj
qpid/trunk/qpid/cpp/examples/messaging/messaging_queue_sender.vcproj
qpid/trunk/qpid/cpp/examples/messaging/messaging_topic_receiver.vcproj
qpid/trunk/qpid/cpp/examples/messaging/messaging_topic_sender.vcproj
qpid/trunk/qpid/cpp/examples/messaging/queue_receiver.cpp
qpid/trunk/qpid/cpp/examples/messaging/queue_sender.cpp
qpid/trunk/qpid/cpp/examples/messaging/topic_receiver.cpp
qpid/trunk/qpid/cpp/examples/messaging/topic_sender.cpp
Modified:
qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt
qpid/trunk/qpid/cpp/examples/messaging/Makefile.am
qpid/trunk/qpid/cpp/examples/messaging/drain.cpp
qpid/trunk/qpid/cpp/examples/messaging/spout.cpp
qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
Modified: qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt Wed May 5 11:17:41 2010
@@ -19,14 +19,26 @@
# drain and spout have explicit Boost.program_options usage in them, so be
# sure that lib is linked in.
-add_example(messaging drain ${Boost_PROGRAM_OPTIONS_LIBRARY})
-add_example(messaging spout ${Boost_PROGRAM_OPTIONS_LIBRARY})
-add_example(messaging queue_receiver)
-add_example(messaging queue_sender)
+macro(add_messaging_example example)
+ add_executable(${example} ${example}.cpp OptionParser.cpp)
+ set_target_properties(${example} PROPERTIES OUTPUT_NAME ${example})
+ target_link_libraries(${example} qpidclient ${_boost_libs_needed})
+ # For installs, don't install the built example; that would be pointless.
+ # Install the things a user needs to build the example on-site.
+ install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${example}.cpp ${CMAKE_CURRENT_SOURCE_DIR}/OptionParser.h ${CMAKE_CURRENT_SOURCE_DIR}/OptionParser.cpp
+ DESTINATION ${QPID_INSTALL_EXAMPLESDIR}/messaging
+ COMPONENT ${QPID_COMPONENT_EXAMPLES})
+ if (MSVC)
+ install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/messaging_${example}.vcproj
+ DESTINATION ${QPID_INSTALL_EXAMPLESDIR}/messaging
+ COMPONENT ${QPID_COMPONENT_EXAMPLES})
+ endif (MSVC)
-add_example(messaging topic_receiver)
-add_example(messaging topic_sender)
+endmacro(add_messaging_example)
+
+add_messaging_example(drain)
+add_messaging_example(spout)
add_example(messaging map_receiver)
add_example(messaging map_sender)
Modified: qpid/trunk/qpid/cpp/examples/messaging/Makefile.am
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/Makefile.am?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/Makefile.am (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/Makefile.am Wed May 5 11:17:41 2010
@@ -18,32 +18,23 @@
#
examplesdir=$(pkgdatadir)/examples/messaging
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
+# Settings to build the examples in automake
+AM_CXXFLAGS = $(WARNING_CFLAGS)
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include
+CLIENT_LIB=$(top_builddir)/src/libqpidclient.la
+CLIENTFLAGS=-lqpidclient
-noinst_PROGRAMS=drain spout queue_sender queue_receiver topic_sender topic_receiver client server map_sender map_receiver hello_world
+noinst_PROGRAMS=drain spout client server map_sender map_receiver hello_world
hello_world_SOURCES=hello_world.cpp
hello_world_LDADD=$(CLIENT_LIB)
-drain_SOURCES=drain.cpp
+drain_SOURCES=drain.cpp OptionParser.h OptionParser.cpp
drain_LDADD=$(CLIENT_LIB)
-spout_SOURCES=spout.cpp
+spout_SOURCES=spout.cpp OptionParser.h OptionParser.cpp
spout_LDADD=$(CLIENT_LIB)
-queue_sender_SOURCES=queue_sender.cpp
-queue_sender_LDADD=$(CLIENT_LIB)
-
-queue_receiver_SOURCES=queue_receiver.cpp
-queue_receiver_LDADD=$(CLIENT_LIB)
-
-topic_sender_SOURCES=topic_sender.cpp
-topic_sender_LDADD=$(CLIENT_LIB)
-
-topic_receiver_SOURCES=topic_receiver.cpp
-topic_receiver_LDADD=$(CLIENT_LIB)
-
client_SOURCES=client.cpp
client_LDADD=$(CLIENT_LIB)
@@ -56,15 +47,24 @@ map_sender_LDADD=$(CLIENT_LIB)
map_receiver_SOURCES=map_receiver.cpp
map_receiver_LDADD=$(CLIENT_LIB)
+examples_DATA= \
+ hello_world.cpp \
+ drain.cpp \
+ spout.cpp \
+ OptionParser.cpp \
+ OptionParser.h \
+ client.cpp \
+ server.cpp \
+ map_sender.cpp \
+ map_receiver.cpp \
+ extra_dist/Makefile
+
EXTRA_DIST= \
+ $(examples_DATA) \
CMakeLists.txt \
messaging_client.vcproj \
messaging_drain.vcproj \
messaging_map_receiver.vcproj \
messaging_map_sender.vcproj \
- messaging_queue_receiver.vcproj \
- messaging_queue_sender.vcproj \
messaging_server.vcproj \
- messaging_spout.vcproj \
- messaging_topic_receiver.vcproj \
- messaging_topic_sender.vcproj
+ messaging_spout.vcproj
Added: qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp?rev=941250&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp (added)
+++ qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp Wed May 5 11:17:41 2010
@@ -0,0 +1,257 @@
+/*
+ *
+ * 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.
+ *
+ */
+#include "OptionParser.h"
+#include <qpid/types/Exception.h>
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+
+class Option
+{
+ public:
+ Option(const std::string& name, const std::string& description);
+ virtual ~Option() {}
+ virtual void setValue(const std::string&) = 0;
+ virtual bool isValueExpected() = 0;
+ bool match(const std::string&);
+ std::ostream& print(std::ostream& out);
+ private:
+ std::string longName;
+ std::string shortName;
+ std::string description;
+ std::ostream& printNames(std::ostream& out);
+ friend class OptionParser;
+};
+
+class StringOption : public Option
+{
+ public:
+ StringOption(const std::string& name, const std::string& description, std::string& v) : Option(name, description), value(v) {}
+ void setValue(const std::string& v) { value = v; }
+ bool isValueExpected() { return true; }
+ private:
+ std::string& value;
+};
+
+class IntegerOption : public Option
+{
+ public:
+ IntegerOption(const std::string& name, const std::string& description, int& v) : Option(name, description), value(v) {}
+ void setValue(const std::string& v) { value = atoi(v.c_str()); }
+ bool isValueExpected() { return true; }
+ private:
+ int& value;
+};
+
+class BooleanOption : public Option
+{
+ public:
+ BooleanOption(const std::string& name, const std::string& description, bool& v) : Option(name, description), value(v) {}
+ void setValue(const std::string&) { value = true; }
+ bool isValueExpected() { return false; }
+ private:
+ bool& value;
+};
+
+class MultiStringOption : public Option
+{
+ public:
+ MultiStringOption(const std::string& name, const std::string& description, std::vector<std::string>& v) : Option(name, description), value(v) {}
+ void setValue(const std::string& v) { value.push_back(v); }
+ bool isValueExpected() { return true; }
+ private:
+ std::vector<std::string>& value;
+};
+
+class OptionMatch
+{
+ public:
+ OptionMatch(const std::string& argument);
+ bool operator()(Option* option);
+ bool isOption();
+ private:
+ std::string name;
+};
+
+class OptionsError : public qpid::types::Exception
+{
+ public:
+ OptionsError(const std::string& message) : qpid::types::Exception(message) {}
+};
+
+Option::Option(const std::string& name, const std::string& desc) : description(desc)
+{
+ std::string::size_type i = name.find(",");
+ if (i != std::string::npos) {
+ longName = name.substr(0, i);
+ if (i + 1 < name.size())
+ shortName = name.substr(i+1);
+ } else {
+ longName = name;
+ }
+}
+
+bool Option::match(const std::string& name)
+{
+ return name == longName || name == shortName;
+}
+
+std::ostream& Option::printNames(std::ostream& out)
+{
+ if (shortName.size()) {
+ out << "-" << shortName;
+ if (isValueExpected()) out << " VALUE";
+ out << ", --" << longName;
+ if (isValueExpected()) out << " VALUE";
+ } else {
+ out << "--" << longName;
+ if (isValueExpected()) out << " VALUE";
+ }
+ return out;
+}
+
+std::ostream& Option::print(std::ostream& out)
+{
+ std::stringstream names;
+ printNames(names);
+ out << std::setw(30) << std::left << names.str() << description << std::endl;
+ return out;
+}
+
+std::vector<std::string>& OptionParser::getArguments() { return arguments; }
+
+void OptionParser::add(Option* option)
+{
+ options.push_back(option);
+}
+
+void OptionParser::add(const std::string& name, std::string& value, const std::string& description)
+{
+ add(new StringOption(name, description, value));
+}
+void OptionParser::add(const std::string& name, int& value, const std::string& description)
+{
+ add(new IntegerOption(name, description, value));
+}
+void OptionParser::add(const std::string& name, bool& value, const std::string& description)
+{
+ add(new BooleanOption(name, description, value));
+}
+void OptionParser::add(const std::string& name, std::vector<std::string>& value, const std::string& description)
+{
+ add(new MultiStringOption(name, description, value));
+}
+
+OptionMatch::OptionMatch(const std::string& argument)
+{
+ if (argument.find("--") == 0) {
+ name = argument.substr(2);
+ } else if (argument.find("-") == 0) {
+ name = argument.substr(1);
+ }
+}
+
+bool OptionMatch::operator()(Option* option)
+{
+ return option->match(name);
+}
+
+bool OptionMatch::isOption()
+{
+ return name.size();
+}
+
+OptionParser::OptionParser(const std::string& s, const std::string& d) : summary(s), description(d), help(false)
+{
+ add("help,h", help, "show this message");
+}
+
+Option* OptionParser::getOption(const std::string& argument)
+{
+ OptionMatch match(argument);
+ if (match.isOption()) {
+ Options::iterator i = std::find_if(options.begin(), options.end(), match);
+ if (i == options.end()) {
+ std::stringstream error;
+ error << "Unrecognised option: " << argument;
+ throw OptionsError(error.str());
+ } else {
+ return *i;
+ }
+ } else {
+ return 0;
+ }
+}
+
+void OptionParser::error(const std::string& message)
+{
+ std::cout << summary << std::endl << std::endl;
+ std::cerr << "Error: " << message << "; try --help for more information" << std::endl;
+}
+
+bool OptionParser::parse(int argc, char** argv)
+{
+ try {
+ for (int i = 1; i < argc; ++i) {
+ std::string argument = argv[i];
+ Option* o = getOption(argument);
+ if (o) {
+ if (o->isValueExpected()) {
+ if (i + 1 < argc) {
+ o->setValue(argv[++i]);
+ } else {
+ std::stringstream error;
+ error << "Value expected for option " << o->longName;
+ throw OptionsError(error.str());
+ }
+ } else {
+ o->setValue("");
+ }
+ } else {
+ arguments.push_back(argument);
+ }
+ }
+ if (help) {
+ std::cout << summary << std::endl << std::endl;
+ std::cout << description << std::endl << std::endl;
+ std::cout << "Options: " << std::endl;
+ for (Options::iterator i = options.begin(); i != options.end(); ++i) {
+ (*i)->print(std::cout);
+ }
+ return false;
+ } else {
+ return true;
+ }
+ } catch (const std::exception& e) {
+ error(e.what());
+ return false;
+ }
+}
+
+
+OptionParser::~OptionParser()
+{
+ for (Options::iterator i = options.begin(); i != options.end(); ++i) {
+ delete *i;
+ }
+}
Added: qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h?rev=941250&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h (added)
+++ qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h Wed May 5 11:17:41 2010
@@ -0,0 +1,56 @@
+#ifndef OPTIONPARSER_H
+#define OPTIONPARSER_H
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <map>
+#include <string>
+#include <vector>
+
+class Option;
+
+class OptionParser
+{
+ public:
+ OptionParser(const std::string& usage, const std::string& description);
+ ~OptionParser();
+ void add(const std::string& name, std::string& value, const std::string& description = std::string());
+ void add(const std::string& name, int& value, const std::string& description = std::string());
+ void add(const std::string& name, bool& value, const std::string& description = std::string());
+ void add(const std::string& name, std::vector<std::string>& value, const std::string& description = std::string());
+ bool parse(int argc, char** argv);
+ void error(const std::string& message);
+ std::vector<std::string>& getArguments();
+ private:
+ typedef std::vector<Option*> Options;
+
+ const std::string summary;
+ const std::string description;
+ bool help;
+ Options options;
+ std::vector<std::string> arguments;
+
+ void add(Option*);
+ Option* getOption(const std::string& argument);
+};
+
+#endif /*!OPTIONPARSER_H*/
Modified: qpid/trunk/qpid/cpp/examples/messaging/drain.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/drain.cpp?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/drain.cpp (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/drain.cpp Wed May 5 11:17:41 2010
@@ -23,76 +23,56 @@
#include <qpid/messaging/Message.h>
#include <qpid/messaging/Receiver.h>
#include <qpid/messaging/Session.h>
-#include <qpid/Exception.h>
-#include <qpid/Options.h>
-#include <qpid/log/Logger.h>
-#include <qpid/log/Options.h>
#include <iostream>
+#include "OptionParser.h"
+
using namespace qpid::messaging;
using namespace qpid::types;
-struct Options : public qpid::Options
+struct Options : OptionParser
{
- bool help;
std::string url;
std::string address;
std::string connectionOptions;
- int64_t timeout;
+ int timeout;
bool forever;
- qpid::log::Options log;
- Options(const std::string& argv0=std::string())
- : qpid::Options("Options"),
- help(false),
- url("amqp:tcp:127.0.0.1"),
+ Options()
+ : OptionParser("Usage: drain [OPTIONS] ADDRESS", "Drains messages from the specified address"),
+ url("127.0.0.1"),
timeout(0),
- forever(false),
- log(argv0)
+ forever(false)
{
- addOptions()
- ("broker,b", qpid::optValue(url, "URL"), "url of broker to connect to")
- ("address,a", qpid::optValue(address, "ADDRESS"), "address to drain from")
- ("timeout,t", qpid::optValue(timeout, "TIMEOUT"), "timeout in seconds to wait before exiting")
- ("forever,f", qpid::optValue(forever), "ignore timeout and wait forever")
- ("connection-options", qpid::optValue(connectionOptions,"OPTIONS"), "connection options string in the form {name1=value1, name2=value2}")
- ("help", qpid::optValue(help), "print this usage statement");
- add(log);
+ add("broker,b", url, "url of broker to connect to");
+ add("timeout,t", timeout, "timeout in seconds to wait before exiting");
+ add("forever,f", forever, "ignore timeout and wait forever");
+ add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
}
Duration getTimeout()
{
if (forever) return Duration::FOREVER;
else return timeout*Duration::SECOND;
-
}
- bool parse(int argc, char** argv)
+
+ bool checkAddress()
{
- try {
- qpid::Options::parse(argc, argv);
- if (address.empty()) throw qpid::Exception("Address must be specified!");
- qpid::log::Logger::instance().configure(log);
- if (help) {
- std::ostringstream msg;
- std::cout << msg << *this << std::endl << std::endl
- << "Drains messages from the specified address" << std::endl;
- return false;
- } else {
- return true;
- }
- } catch (const std::exception& e) {
- std::cerr << *this << std::endl << std::endl << e.what() << std::endl;
+ if (getArguments().empty()) {
+ error("Address is required");
return false;
+ } else {
+ address = getArguments()[0];
+ return true;
}
}
};
-
int main(int argc, char** argv)
{
- Options options(argv[0]);
- if (options.parse(argc, argv)) {
+ Options options;
+ if (options.parse(argc, argv) && options.checkAddress()) {
Connection connection(options.url, options.connectionOptions);
try {
connection.open();
Added: qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile?rev=941250&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile (added)
+++ qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile Wed May 5 11:17:41 2010
@@ -0,0 +1,12 @@
+CXX=g++
+CXXFLAGS=-g -O2
+LDFLAGS=-lqpidclient
+
+all: drain spout client server map_sender map_receiver hello_world
+
+drain: drain.o OptionParser.o
+
+spout: spout.o OptionParser.o
+
+clean:
+ rm -f drain spout client server map_sender map_receiver hello_world *.o
Modified: qpid/trunk/qpid/cpp/examples/messaging/spout.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/spout.cpp?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/spout.cpp (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/spout.cpp Wed May 5 11:17:41 2010
@@ -25,16 +25,13 @@
#include <qpid/messaging/Sender.h>
#include <qpid/messaging/Session.h>
#include <qpid/types/Variant.h>
-#include <qpid/Exception.h>
-#include <qpid/Options.h>
-#include <qpid/log/Logger.h>
-#include <qpid/log/Options.h>
#include <qpid/sys/Time.h>
#include <iostream>
+#include <sstream>
#include <vector>
-#include <boost/format.hpp>
+#include "OptionParser.h"
using namespace qpid::messaging;
using namespace qpid::types;
@@ -44,62 +41,34 @@ using qpid::sys::TIME_INFINITE;
typedef std::vector<std::string> string_vector;
-struct Options : public qpid::Options
+struct Options : OptionParser
{
- bool help;
std::string url;
std::string address;
- int64_t timeout;
- uint count;
+ int timeout;
+ int count;
std::string id;
std::string replyto;
string_vector properties;
string_vector entries;
std::string content;
std::string connectionOptions;
- qpid::log::Options log;
- Options(const std::string& argv0=std::string())
- : qpid::Options("Options"),
- help(false),
- url("amqp:tcp:127.0.0.1"),
- timeout(TIME_INFINITE),
- count(1),
- log(argv0)
- {
- addOptions()
- ("broker,b", qpid::optValue(url, "URL"), "url of broker to connect to")
- ("address,a", qpid::optValue(address, "ADDRESS"), "address to drain from")
- ("timeout,t", qpid::optValue(timeout, "TIMEOUT"), "exit after the specified time")
- ("count,c", qpid::optValue(count, "COUNT"), "stop after count messages have been sent, zero disables")
- ("id,i", qpid::optValue(id, "ID"), "use the supplied id instead of generating one")
- ("reply-to", qpid::optValue(replyto, "REPLY-TO"), "specify reply-to address")
- ("property,P", qpid::optValue(properties, "NAME=VALUE"), "specify message property")
- ("map,M", qpid::optValue(entries, "NAME=VALUE"), "specify entry for map content")
- ("content", qpid::optValue(content, "CONTENT"), "specify textual content")
- ("connection-options", qpid::optValue(connectionOptions,"OPTIONS"), "connection options string in the form {name1=value1, name2=value2}")
- ("help", qpid::optValue(help), "print this usage statement");
- add(log);
- }
-
- bool parse(int argc, char** argv)
- {
- try {
- qpid::Options::parse(argc, argv);
- if (address.empty()) throw qpid::Exception("Address must be specified!");
- qpid::log::Logger::instance().configure(log);
- if (help) {
- std::ostringstream msg;
- std::cout << msg << *this << std::endl << std::endl
- << "Drains messages from the specified address" << std::endl;
- return false;
- } else {
- return true;
- }
- } catch (const std::exception& e) {
- std::cerr << *this << std::endl << std::endl << e.what() << std::endl;
- return false;
- }
+ Options()
+ : OptionParser("Usage: spout [OPTIONS] ADDRESS", "Send messages to the specified address"),
+ url("127.0.0.1"),
+ timeout(0),
+ count(1)
+ {
+ add("broker,b", url, "url of broker to connect to");
+ add("timeout,t", timeout, "exit after the specified time");
+ add("count,c", count, "stop after count messages have been sent, zero disables");
+ add("id,i", id, "use the supplied id instead of generating one");
+ add("reply-to", replyto, "specify reply-to address");
+ add("property,P", properties, "specify message property");
+ add("map,M", entries, "specify entry for map content");
+ add("content", content, "specify textual content");
+ add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
}
static bool nameval(const std::string& in, std::string& name, std::string& value)
@@ -149,13 +118,24 @@ struct Options : public qpid::Options
}
}
}
+
+ bool checkAddress()
+ {
+ if (getArguments().empty()) {
+ error("Address is required");
+ return false;
+ } else {
+ address = getArguments()[0];
+ return true;
+ }
+ }
};
int main(int argc, char** argv)
{
- Options options(argv[0]);
- if (options.parse(argc, argv)) {
+ Options options;
+ if (options.parse(argc, argv) && options.checkAddress()) {
Connection connection(options.url, options.connectionOptions);
try {
connection.open();
@@ -172,12 +152,15 @@ int main(int argc, char** argv)
message.setContent(options.content);
message.setContentType("text/plain");
}
- AbsTime end(now(), options.timeout);
- for (uint count = 0; (count < options.count || options.count == 0) && end > now(); count++) {
+ AbsTime end(now(), options.timeout * qpid::sys::TIME_SEC);
+ for (int count = 0; (count < options.count || options.count == 0) && (options.timeout == 0 || end > now()); count++) {
if (!options.replyto.empty()) message.setReplyTo(Address(options.replyto));
std::string id = options.id.empty() ? Uuid(true).str() : options.id;
- message.getProperties()["spout-id"] = (boost::format("%1%:%2%") % id % count).str();
+ std::stringstream spoutid;
+ spoutid << id << ":" << count;
+ message.getProperties()["spout-id"] = spoutid.str();
sender.send(message);
+ std::cout << "Sent " << (count+1) << " of " << options.count << " messages" <<std::endl;
}
connection.close();
return 0;
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=941250&r1=941249&r2=941250&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 Wed May 5 11:17:41 2010
@@ -305,8 +305,8 @@ finally:
<screen>
$ qpid-config add queue hello-world
-$ ./spout -a hello-world
-$ ./drain -a hello-world
+$ ./spout hello-world
+$ ./drain hello-world
Message(properties={spout-id:c877e622-d57b-4df2-bf3e-6014c68da0ea:0}, content='')
</screen>
@@ -319,7 +319,7 @@ Message(properties={spout-id:c877e622-d5
<command>drain</command> one more time, no messages will be retrieved.</para>
<screen>
-$ ./drain -a hello-world
+$ ./drain hello-world
$
</screen>
@@ -342,8 +342,8 @@ $ qpid-config add exchange topic hello-w
<para>Now run <command>drain</command> and <command>spout</command> the same way we did in the previous example:</para>
<screen>
-$ ./spout -a hello-world
-$ ./drain -a hello-world
+$ ./spout hello-world
+$ ./drain hello-world
$
</screen>
@@ -362,14 +362,14 @@ $
<para><emphasis>First Window:</emphasis></para>
<screen>
-$ ./drain -a hello-word -t 30
+$ ./drain -t 30 hello-word
</screen>
<para><emphasis>Second Window:</emphasis></para>
<screen>
-$ ./spout -a hello-word
+$ ./spout hello-word
</screen>
<para>Once <command>spout</command> has sent a message, return
@@ -464,15 +464,15 @@ $ qpid-config add exchange topic news-se
<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 -a news-service/sports -t 30
+$ ./drain -t 30 news-service/sports
</screen>
<para>In a second window, let's send messages to <literal>news-service</literal> using two different subjects:</para>
<para><emphasis>Second Window:</emphasis></para>
<screen>
-$ ./spout -a news-service/sports
-$ ./spout -a news-service/news
+$ ./spout news-service/sports
+$ ./spout news-service/news
</screen>
<para>Now look at the first window, the message with the
@@ -527,7 +527,7 @@ Message(properties={qpid.subject:sports,
<para><emphasis>First Window:</emphasis></para>
<screen>
-$ ./drain -a news-service/*.news -t 30
+$ ./drain -t 30 news-service/*.news
</screen>
<para>Now let's send messages using several different
@@ -536,10 +536,10 @@ $ ./drain -a news-service/*.news -t 30
<para><emphasis>Second Window:</emphasis></para>
<screen>
-$ ./spout -a news-service/usa.news
-$ ./spout -a news-service/usa.sports
-$ ./spout -a news-service/europe.sports
-$ ./spout -a news-service/europe.news
+$ ./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
@@ -559,7 +559,7 @@ Message(properties={qpid.subject:europe.
<para><emphasis>First Window:</emphasis></para>
<screen>
-$ ./drain -a news-service/#.news -t 30
+$ ./drain -t 30 news-service/#.news
</screen>
<para>In the second window, let's send messages using a
@@ -568,12 +568,12 @@ $ ./drain -a news-service/#.news -t 30
<para><emphasis>Second Window:</emphasis></para>
<screen>
-$ ./spout -a news-service/news
-$ ./spout -a news-service/sports
-$ ./spout -a news-service/usa.news
-$ ./spout -a news-service/usa.sports
-$ ./spout -a news-service/usa.faux.news
-$ ./spout -a news-service/usa.faux.sports
+$ ./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
@@ -666,8 +666,8 @@ $ qpid-config add exchange topic my-topi
</para>
<screen>
-$ ./drain -a 'my-queue; {assert: always, node:{ type: queue }}'
-$ ./drain -a 'my-queue; {assert: always, node:{ type: topic }}'
+$ ./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>
@@ -683,8 +683,8 @@ Exchange my-queue does not exist
</para>
<screen>
-$ ./drain -a 'my-topic; {assert: always, node:{ type: topic }}'
-$ ./drain -a 'my-topic; {assert: always, node:{ type: queue }}'
+$ ./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>
@@ -698,7 +698,7 @@ Queue my-topic does not exist
<title>Creating a Queue Automatically</title>
<para><emphasis>First Window:</emphasis></para>
- <screen>$ ./drain -a "xoxox ; {create: always}" -t 30</screen>
+ <screen>$ ./drain -t 30 "xoxox ; {create: always}"</screen>
<para>In previous examples, we created the queue before
listening for messages on it. Using <literal>create:
@@ -706,7 +706,7 @@ Queue my-topic does not exist
does not exist. Now we can send messages to this queue:</para>
<para><emphasis>Second Window:</emphasis></para>
- <screen>$ ./spout -a "xoxox ; {create: always}"</screen>
+ <screen>$ ./spout "xoxox ; {create: always}"</screen>
<para>Returning to the first window, we see that <command>drain</command> has received this message:</para>
@@ -732,14 +732,14 @@ Queue my-topic does not exist
queue:
</para>
<screen>
-$ ./spout -a my-queue --content one
-$ ./spout -a my-queue --content two
-$ ./spout -a my-queue --content three
+$ ./spout my-queue --content one
+$ ./spout my-queue --content two
+$ ./spout my-queue --content three
</screen>
<para>Now we use drain to get those messages, using the browse option:</para>
<screen>
-$ ./drain -a 'my-queue; {mode: browse}'
+$ ./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')
@@ -747,7 +747,7 @@ Message(properties={spout-id:ea75d64d-ea
<para>We can confirm the messages are still on the queue by repeating the drain:</para>
<screen>
-$ ./drain -a 'my-queue; {mode: browse}'
+$ ./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')
@@ -1414,8 +1414,8 @@ declare variable $control external;
<para>The following shows the arguments used with <command>drain</command> to retrieve messages whose root element is named <literal>weather</literal>:</para>
<programlisting><![CDATA[
-$ ./drain -a "xml; {link:{x-bindings: [{exchange: xml, key:"weather",
-arguments:{xquery:\"./weather\"}}]}}" -f
+$ ./drain -f "xml; {link:{x-bindings: [{exchange: xml, key:"weather",
+arguments:{xquery:\"./weather\"}}]}}"
]]></programlisting>
</example>
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org