summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2007-04-26 16:01:04 +0000
committerAlan Conway <aconway@apache.org>2007-04-26 16:01:04 +0000
commit0a90e5db613b035e15af3b7358205ed1f7960d2c (patch)
treec4b1ec81e60a3b93e414ddf725985d1a9ff5d291
parent4473eb5d9e9da37e515be063952d284034adbec3 (diff)
downloadqpid-python-0a90e5db613b035e15af3b7358205ed1f7960d2c.tar.gz
Merged revisions 532430 by hand from
https://svn.apache.org/repos/asf/incubator/qpid/branches/trunk/qpid/cpp ------------------------------------------------------------------------ r532430 | aconway | 2007-04-25 14:06:14 -0400 (Wed, 25 Apr 2007) | 10 lines * qpid/CommonOptions.h: - Convenience classs/functions to use boost::program_options. - CommonOptions class for options common to client/broker. * qpid/broker/Broker.h: - Replaced broker::Configuration with class Broker::Options, derived from CommonOptions. * qpidd.cpp: Updated options handling. * qpid/Exception.h: Added strError function to get std::string from errno. ------------------------------------------------------------------------ git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/M2@532787 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--cpp/lib/CommonOptions.cpp36
-rw-r--r--cpp/lib/CommonOptions.h91
-rw-r--r--cpp/lib/broker/Broker.cpp51
-rw-r--r--cpp/lib/broker/Broker.h19
-rw-r--r--cpp/lib/broker/Configuration.cpp252
-rw-r--r--cpp/lib/broker/Configuration.h170
-rw-r--r--cpp/lib/broker/Makefile.am2
-rw-r--r--cpp/lib/common/CommonOptions.cpp36
-rw-r--r--cpp/lib/common/CommonOptions.h91
-rw-r--r--cpp/lib/common/Exception.cpp8
-rw-r--r--cpp/lib/common/Exception.h4
-rw-r--r--cpp/lib/common/Makefile.am17
-rw-r--r--cpp/src/Makefile.am18
-rw-r--r--cpp/src/qpidd.cpp100
-rw-r--r--cpp/tests/ConfigurationTest.cpp98
-rw-r--r--cpp/tests/Makefile.am5
16 files changed, 405 insertions, 593 deletions
diff --git a/cpp/lib/CommonOptions.cpp b/cpp/lib/CommonOptions.cpp
new file mode 100644
index 0000000000..8efb3a6baa
--- /dev/null
+++ b/cpp/lib/CommonOptions.cpp
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed 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 "CommonOptions.h"
+
+namespace qpid {
+
+const int CommonOptions::DEFAULT_PORT=5672;
+
+CommonOptions::CommonOptions() : trace(false), port(DEFAULT_PORT) {}
+
+void CommonOptions::addTo(po::options_description& desc)
+{
+ using namespace po;
+ desc.add_options()
+ ("trace,t", optValue(trace), "Enable debug tracing" )
+ ("port,p", optValue(port,"PORT"), "Use PORT for AMQP connections.");
+}
+
+} // namespace qpid
+
diff --git a/cpp/lib/CommonOptions.h b/cpp/lib/CommonOptions.h
new file mode 100644
index 0000000000..2a4b9798cd
--- /dev/null
+++ b/cpp/lib/CommonOptions.h
@@ -0,0 +1,91 @@
+#ifndef QPID_COMMONOPTIONS_H
+#define QPID_COMMONOPTIONS_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 <boost/program_options.hpp>
+#include <boost/format.hpp>
+
+namespace qpid {
+
+/**@Qpid extensions to boost::program_options */
+namespace program_options {
+
+using namespace boost::program_options;
+
+/** @internal Normally only constructed by optValue() */
+template <class T>
+class OptionValue : public typed_value<T> {
+ public:
+ OptionValue(T& value, const std::string& arg)
+ : typed_value<T>(&value), argName(arg) {}
+ std::string name() const { return argName; }
+ private:
+ std::string argName;
+};
+
+/**
+ * Like boost::program_options::value() with more convenient signature
+ * for updating a value by reference and nicer help formatting.
+ *
+ *@param value displayed as default in help, updated from options.
+ * Must support ostream << operator.
+ *@param arg name for arguments in help.
+ *
+ *@see CommonOptions.cpp for example of use.
+ */
+template<class T>
+value_semantic* optValue(T& value, const char* arg) {
+ std::string val(boost::lexical_cast<std::string>(value));
+ std::string argName(
+ val.empty() ? std::string(arg) :
+ (boost::format("%s (=%s) ") % arg % val).str());
+ return new OptionValue<T>(value, argName);
+}
+
+/**
+ * Like boost::program_options::bool_switch but takes reference, not pointer.
+ */
+inline value_semantic* optValue(bool& value) { return bool_switch(&value); }
+
+} // namespace program_options
+
+namespace po=program_options; // Convenience alias.
+
+/**
+ * Common options for client and broker
+ */
+struct CommonOptions {
+ static const int DEFAULT_PORT;
+
+ CommonOptions();
+
+ bool trace;
+ int port;
+
+ /** Add members to program_options to be updated */
+ void addTo(po::options_description&);
+};
+
+} // namespace qpid
+
+#endif /*!QPID_COMMONOPTIONS_H*/
diff --git a/cpp/lib/broker/Broker.cpp b/cpp/lib/broker/Broker.cpp
index 6c0d7a3f3f..806127bf43 100644
--- a/cpp/lib/broker/Broker.cpp
+++ b/cpp/lib/broker/Broker.cpp
@@ -22,38 +22,63 @@
#include <memory>
#include <Broker.h>
-
using namespace qpid::broker;
using namespace qpid::sys;
-Broker::Broker(const Configuration& config) :
- acceptor(Acceptor::create(config.getPort(),
- config.getConnectionBacklog(),
- config.getWorkerThreads(),
- config.isTrace())),
- factory(config.getStore())
+Broker::Options::Options() :
+ workerThreads(5),
+ maxConnections(500),
+ connectionBacklog(10),
+ store(),
+ stagingThreshold(5000000)
+{}
+
+void Broker::Options::addTo(po::options_description& desc)
+{
+ using namespace po;
+ CommonOptions::addTo(desc);
+ desc.add_options()
+ ("worker-threads", optValue(workerThreads, "N"),
+ "Broker thread pool size")
+ ("max-connections", optValue(maxConnections, "N"),
+ "Maximum allowed connections")
+ ("connection-backlog", optValue(connectionBacklog, "N"),
+ "Connection backlog limit for server socket.")
+ ("staging-threshold", optValue(stagingThreshold, "N"),
+ "Messages over N bytes are staged to disk.")
+ ("store", optValue(store,"LIBNAME"),
+ "Name of message store shared library.");
+}
+
+
+Broker::Broker(const Options& config) :
+ acceptor(Acceptor::create(config.port,
+ config.connectionBacklog,
+ config.workerThreads,
+ config.trace)),
+ factory(config.store)
{ }
Broker::shared_ptr Broker::create(int16_t port)
{
- Configuration config;
- config.setPort(port);
+ Options config;
+ config.port=port;
return create(config);
}
-Broker::shared_ptr Broker::create(const Configuration& config) {
+Broker::shared_ptr Broker::create(const Options& config) {
return Broker::shared_ptr(new Broker(config));
}
-
+
void Broker::run() {
acceptor->run(&factory);
}
void Broker::shutdown() {
- acceptor->shutdown();
+ if (acceptor)
+ acceptor->shutdown();
}
Broker::~Broker() { }
-const int16_t Broker::DEFAULT_PORT(5672);
diff --git a/cpp/lib/broker/Broker.h b/cpp/lib/broker/Broker.h
index 8ea1a57c27..8b54bd592b 100644
--- a/cpp/lib/broker/Broker.h
+++ b/cpp/lib/broker/Broker.h
@@ -22,7 +22,7 @@
*
*/
-#include <Configuration.h>
+#include <CommonOptions.h>
#include <SessionHandlerFactoryImpl.h>
#include <sys/Runnable.h>
#include <sys/Acceptor.h>
@@ -37,7 +37,15 @@ class Broker : public qpid::sys::Runnable,
public qpid::SharedObject<Broker>
{
public:
- static const int16_t DEFAULT_PORT;
+ struct Options : public CommonOptions {
+ Options();
+ void addTo(po::options_description&);
+ int workerThreads;
+ int maxConnections;
+ int connectionBacklog;
+ std::string store;
+ long stagingThreshold;
+ };
virtual ~Broker();
@@ -45,12 +53,12 @@ class Broker : public qpid::sys::Runnable,
* Create a broker.
* @param port Port to listen on or 0 to pick a port dynamically.
*/
- static shared_ptr create(int16_t port = DEFAULT_PORT);
+ static shared_ptr create(int16_t port = Options::DEFAULT_PORT);
/**
* Create a broker using a Configuration.
*/
- static shared_ptr create(const Configuration& config);
+ static shared_ptr create(const Options& config);
/**
* Return listening port. If called before bind this is
@@ -70,7 +78,8 @@ class Broker : public qpid::sys::Runnable,
virtual void shutdown();
private:
- Broker(const Configuration& config);
+ Broker(const Options& config);
+ Options config;
qpid::sys::Acceptor::shared_ptr acceptor;
SessionHandlerFactoryImpl factory;
};
diff --git a/cpp/lib/broker/Configuration.cpp b/cpp/lib/broker/Configuration.cpp
deleted file mode 100644
index e83c359f2d..0000000000
--- a/cpp/lib/broker/Configuration.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- *
- * 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 <Configuration.h>
-#include <string.h>
-#include <config.h>
-
-using namespace qpid::broker;
-using namespace std;
-
-Configuration::Configuration() :
- daemon('d', "daemon", "Run as system daemon, detached from terminal.", false),
- trace('t', "trace", "Print incoming & outgoing frames to the console", false),
- port('p', "port", "Set the port to listen on (default=5672)", 5672),
- workerThreads("worker-threads", "Set the number of worker threads to use (default=5).", 5),
- maxConnections("max-connections", "Set the maximum number of connections the broker can accept (default=500).", 500),
- connectionBacklog("connection-backlog", "Set the connection backlog for the servers socket (default=10)", 10),
- store('s', "store", "Set the message store module to use (default='' which implies no store)", ""),
- stagingThreshold("staging-threshold", "Set the message size threshold above which messages will be written to disk as they arrive (default=5,000,000)", 5000000),
- help("help", "Print usage information", false),
- version("version", "Print version information", false)
-{
- options.push_back(&daemon);
- options.push_back(&trace);
- options.push_back(&port);
- options.push_back(&workerThreads);
- options.push_back(&maxConnections);
- options.push_back(&connectionBacklog);
- options.push_back(&store);
- options.push_back(&stagingThreshold);
- options.push_back(&help);
- options.push_back(&version);
-}
-
-Configuration::~Configuration(){}
-
-void Configuration::parse(char const *progName, int argc, char** argv){
- programName = progName;
- int position = 1;
- while(position < argc){
- bool matched(false);
- for(op_iterator i = options.begin(); i < options.end() && !matched; i++){
- matched = (*i)->parse(position, argv, argc);
- }
- if(!matched) {
- throw BadOptionException(
- std::string("Unrecognised option: ")+argv[position]);
- }
- }
-}
-
-void Configuration::usage(){
- std::cout << "Usage: " << programName << " [OPTION]..." << std::endl
- << "Start the Qpid AMQP broker daemon." << std::endl << std::endl
- << "Options:" << std::endl;
- for(op_iterator i = options.begin(); i < options.end(); i++){
- (*i)->print(std::cout);
- }
-
- std::cout << std::endl << "Report bugs to <" << PACKAGE_BUGREPORT << ">."
- << std::endl;
-}
-
-bool Configuration::isHelp() const {
- return help.getValue();
-}
-
-bool Configuration::isVersion() const {
- return version.getValue();
-}
-
-bool Configuration::isDaemon() const {
- return daemon.getValue();
-}
-
-bool Configuration::isTrace() const {
- return trace.getValue();
-}
-
-int Configuration::getPort() const {
- return port.getValue();
-}
-
-int Configuration::getWorkerThreads() const {
- return workerThreads.getValue();
-}
-
-int Configuration::getMaxConnections() const {
- return maxConnections.getValue();
-}
-
-int Configuration::getConnectionBacklog() const {
- return connectionBacklog.getValue();
-}
-
-const std::string& Configuration::getStore() const {
- return store.getValue();
-}
-
-long Configuration::getStagingThreshold() const {
- return stagingThreshold.getValue();
-}
-
-
-Configuration::Option::Option(const char _flag, const string& _name, const string& _desc) :
- flag(string("-") + _flag), name("--" +_name), desc(_desc) {}
-
-Configuration::Option::Option(const string& _name, const string& _desc) :
- flag(""), name("--" + _name), desc(_desc) {}
-
-Configuration::Option::~Option(){}
-
-bool Configuration::Option::match(const string& arg){
- return flag == arg || name == arg;
-}
-
-bool Configuration::Option::parse(int& i, char** argv, int argc){
- const string arg(argv[i]);
- if(match(arg)){
- if(needsValue()){
- if(++i < argc) setValue(argv[i]);
- else throw ParseException("Argument " + arg + " requires a value!");
- }else{
- setValue("");
- }
- i++;
- return true;
- }else{
- return false;
- }
-}
-
-void Configuration::Option::print(ostream& out) const {
- out << " ";
- if(flag.length() > 0){
- out << flag << ", ";
- } else {
- out << " ";
- }
- out << name;
- if(needsValue()) out << " <value>";
- out << std::endl;
- out << " " << desc << std::endl;
-}
-
-
-// String Option:
-
-Configuration::StringOption::StringOption(const char _flag, const string& _name, const string& _desc, const string _value) :
- Option(_flag,_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::StringOption::StringOption(const string& _name, const string& _desc, const string _value) :
- Option(_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::StringOption::~StringOption(){}
-
-const string& Configuration::StringOption::getValue() const {
- return value;
-}
-
-bool Configuration::StringOption::needsValue() const {
- return true;
-}
-
-void Configuration::StringOption::setValue(const std::string& _value){
- value = _value;
-}
-
-// Int Option:
-
-Configuration::IntOption::IntOption(const char _flag, const string& _name, const string& _desc, const int _value) :
- Option(_flag,_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::IntOption::IntOption(const string& _name, const string& _desc, const int _value) :
- Option(_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::IntOption::~IntOption(){}
-
-int Configuration::IntOption::getValue() const {
- return value;
-}
-
-bool Configuration::IntOption::needsValue() const {
- return true;
-}
-
-void Configuration::IntOption::setValue(const std::string& _value){
- value = atoi(_value.c_str());
-}
-
-// Long Option:
-
-Configuration::LongOption::LongOption(const char _flag, const string& _name, const string& _desc, const long _value) :
- Option(_flag,_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::LongOption::LongOption(const string& _name, const string& _desc, const long _value) :
- Option(_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::LongOption::~LongOption(){}
-
-long Configuration::LongOption::getValue() const {
- return value;
-}
-
-bool Configuration::LongOption::needsValue() const {
- return true;
-}
-
-void Configuration::LongOption::setValue(const std::string& _value){
- value = atol(_value.c_str());
-}
-
-// Bool Option:
-
-Configuration::BoolOption::BoolOption(const char _flag, const string& _name, const string& _desc, const bool _value) :
- Option(_flag,_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::BoolOption::BoolOption(const string& _name, const string& _desc, const bool _value) :
- Option(_name,_desc), defaultValue(_value), value(_value) {}
-
-Configuration::BoolOption::~BoolOption(){}
-
-bool Configuration::BoolOption::getValue() const {
- return value;
-}
-
-bool Configuration::BoolOption::needsValue() const {
- return false;
-}
-
-void Configuration::BoolOption::setValue(const std::string& /*not required*/){
- //BoolOptions have no value. The fact that the option is specified
- //implies the value is true.
- value = true;
-}
diff --git a/cpp/lib/broker/Configuration.h b/cpp/lib/broker/Configuration.h
deleted file mode 100644
index 15f2117f5e..0000000000
--- a/cpp/lib/broker/Configuration.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _Configuration_
-#define _Configuration_
-
-#include <cstdlib>
-#include <iostream>
-#include <vector>
-#include <Exception.h>
-
-namespace qpid {
-namespace broker {
-class Configuration{
-
- class Option {
- const std::string flag;
- const std::string name;
- const std::string desc;
-
- bool match(const std::string& arg);
-
- protected:
- virtual bool needsValue() const = 0;
- virtual void setValue(const std::string& value) = 0;
-
- public:
- Option(const char flag, const std::string& name, const std::string& desc);
- Option(const std::string& name, const std::string& desc);
- virtual ~Option();
-
- bool parse(int& i, char** argv, int argc);
- void print(std::ostream& out) const;
- };
-
- class IntOption : public Option{
- const int defaultValue;
- int value;
- public:
- IntOption(char flag, const std::string& name, const std::string& desc, const int value = 0);
- IntOption(const std::string& name, const std::string& desc, const int value = 0);
- virtual ~IntOption();
-
- int getValue() const;
- virtual bool needsValue() const;
- virtual void setValue(const std::string& value);
- virtual void setValue(int _value) { value = _value; }
- };
-
- class LongOption : public Option{
- const long defaultValue;
- int value;
- public:
- LongOption(char flag, const std::string& name, const std::string& desc, const long value = 0);
- LongOption(const std::string& name, const std::string& desc, const long value = 0);
- virtual ~LongOption();
-
- long getValue() const;
- virtual bool needsValue() const;
- virtual void setValue(const std::string& value);
- virtual void setValue(int _value) { value = _value; }
- };
-
- class StringOption : public Option{
- const std::string defaultValue;
- std::string value;
- public:
- StringOption(char flag, const std::string& name, const std::string& desc, const std::string value = "");
- StringOption(const std::string& name, const std::string& desc, const std::string value = "");
- virtual ~StringOption();
-
- const std::string& getValue() const;
- virtual bool needsValue() const;
- virtual void setValue(const std::string& value);
- };
-
- class BoolOption : public Option{
- const bool defaultValue;
- bool value;
- public:
- BoolOption(char flag, const std::string& name, const std::string& desc, const bool value = 0);
- BoolOption(const std::string& name, const std::string& desc, const bool value = 0);
- virtual ~BoolOption();
-
- bool getValue() const;
- virtual bool needsValue() const;
- virtual void setValue(const std::string& value);
- virtual void setValue(bool _value) { value = _value; }
- };
-
- BoolOption daemon;
- BoolOption trace;
- IntOption port;
- IntOption workerThreads;
- IntOption maxConnections;
- IntOption connectionBacklog;
- StringOption store;
- LongOption stagingThreshold;
- BoolOption help;
- BoolOption version;
- char const *programName;
-
- typedef std::vector<Option*>::iterator op_iterator;
- std::vector<Option*> options;
-
- public:
-
- struct BadOptionException : public qpid::Exception {
- BadOptionException(const std::string& msg)
- : qpid::Exception(msg) {}
- };
-
-
- class ParseException : public Exception {
- public:
- ParseException(const std::string& msg) : Exception(msg) {}
- };
-
-
- Configuration();
- ~Configuration();
-
- void parse(char const*, int argc, char** argv);
-
- bool isHelp() const;
- bool isVersion() const;
- bool isDaemon() const;
- bool isTrace() const;
- int getPort() const;
- int getWorkerThreads() const;
- int getMaxConnections() const;
- int getConnectionBacklog() const;
- const std::string& getStore() const;
- long getStagingThreshold() const;
-
- void setHelp(bool b) { help.setValue(b); }
- void setVersion(bool b) { version.setValue(b); }
- void setDaemon(bool b) { daemon.setValue(b); }
- void setTrace(bool b) { trace.setValue(b); }
- void setPort(int i) { port.setValue(i); }
- void setWorkerThreads(int i) { workerThreads.setValue(i); }
- void setMaxConnections(int i) { maxConnections.setValue(i); }
- void setConnectionBacklog(int i) { connectionBacklog.setValue(i); }
- void setStore(const std::string& s) { store.setValue(s); }
- void setStagingThreshold(long l) { stagingThreshold.setValue(l); }
-
- void usage();
-};
-}
-}
-
-
-#endif
diff --git a/cpp/lib/broker/Makefile.am b/cpp/lib/broker/Makefile.am
index b093d13ea9..dfc0315902 100644
--- a/cpp/lib/broker/Makefile.am
+++ b/cpp/lib/broker/Makefile.am
@@ -24,8 +24,6 @@ libqpidbroker_la_SOURCES = \
BrokerMessage.h \
BrokerQueue.cpp \
BrokerQueue.h \
- Configuration.cpp \
- Configuration.h \
ConnectionToken.h \
Consumer.h \
Content.h \
diff --git a/cpp/lib/common/CommonOptions.cpp b/cpp/lib/common/CommonOptions.cpp
new file mode 100644
index 0000000000..8efb3a6baa
--- /dev/null
+++ b/cpp/lib/common/CommonOptions.cpp
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed 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 "CommonOptions.h"
+
+namespace qpid {
+
+const int CommonOptions::DEFAULT_PORT=5672;
+
+CommonOptions::CommonOptions() : trace(false), port(DEFAULT_PORT) {}
+
+void CommonOptions::addTo(po::options_description& desc)
+{
+ using namespace po;
+ desc.add_options()
+ ("trace,t", optValue(trace), "Enable debug tracing" )
+ ("port,p", optValue(port,"PORT"), "Use PORT for AMQP connections.");
+}
+
+} // namespace qpid
+
diff --git a/cpp/lib/common/CommonOptions.h b/cpp/lib/common/CommonOptions.h
new file mode 100644
index 0000000000..2a4b9798cd
--- /dev/null
+++ b/cpp/lib/common/CommonOptions.h
@@ -0,0 +1,91 @@
+#ifndef QPID_COMMONOPTIONS_H
+#define QPID_COMMONOPTIONS_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 <boost/program_options.hpp>
+#include <boost/format.hpp>
+
+namespace qpid {
+
+/**@Qpid extensions to boost::program_options */
+namespace program_options {
+
+using namespace boost::program_options;
+
+/** @internal Normally only constructed by optValue() */
+template <class T>
+class OptionValue : public typed_value<T> {
+ public:
+ OptionValue(T& value, const std::string& arg)
+ : typed_value<T>(&value), argName(arg) {}
+ std::string name() const { return argName; }
+ private:
+ std::string argName;
+};
+
+/**
+ * Like boost::program_options::value() with more convenient signature
+ * for updating a value by reference and nicer help formatting.
+ *
+ *@param value displayed as default in help, updated from options.
+ * Must support ostream << operator.
+ *@param arg name for arguments in help.
+ *
+ *@see CommonOptions.cpp for example of use.
+ */
+template<class T>
+value_semantic* optValue(T& value, const char* arg) {
+ std::string val(boost::lexical_cast<std::string>(value));
+ std::string argName(
+ val.empty() ? std::string(arg) :
+ (boost::format("%s (=%s) ") % arg % val).str());
+ return new OptionValue<T>(value, argName);
+}
+
+/**
+ * Like boost::program_options::bool_switch but takes reference, not pointer.
+ */
+inline value_semantic* optValue(bool& value) { return bool_switch(&value); }
+
+} // namespace program_options
+
+namespace po=program_options; // Convenience alias.
+
+/**
+ * Common options for client and broker
+ */
+struct CommonOptions {
+ static const int DEFAULT_PORT;
+
+ CommonOptions();
+
+ bool trace;
+ int port;
+
+ /** Add members to program_options to be updated */
+ void addTo(po::options_description&);
+};
+
+} // namespace qpid
+
+#endif /*!QPID_COMMONOPTIONS_H*/
diff --git a/cpp/lib/common/Exception.cpp b/cpp/lib/common/Exception.cpp
index 0161518011..64d88af1b4 100644
--- a/cpp/lib/common/Exception.cpp
+++ b/cpp/lib/common/Exception.cpp
@@ -19,10 +19,16 @@
*
*/
-#include <Exception.h>
+#include "Exception.h"
+#include <cerrno>
namespace qpid {
+std::string strError(int err) {
+ char buf[512];
+ return std::string(strerror_r(err, buf, sizeof(buf)));
+}
+
Exception::Exception() throw() {}
Exception::Exception(const std::string& str) throw() : whatStr(str) {}
diff --git a/cpp/lib/common/Exception.h b/cpp/lib/common/Exception.h
index f35d427bb0..4e26ad42e3 100644
--- a/cpp/lib/common/Exception.h
+++ b/cpp/lib/common/Exception.h
@@ -29,6 +29,10 @@
namespace qpid
{
+
+/** Get the error message for error number err. */
+std::string strError(int err);
+
/**
* Exception base class for all Qpid exceptions.
*/
diff --git a/cpp/lib/common/Makefile.am b/cpp/lib/common/Makefile.am
index fe05498b97..e90dacb605 100644
--- a/cpp/lib/common/Makefile.am
+++ b/cpp/lib/common/Makefile.am
@@ -44,13 +44,14 @@ framing = framing
gen = $(srcdir)/../../gen
lib_LTLIBRARIES = libqpidcommon.la
-libqpidcommon_la_LIBADD = \
- $(APR_LIBS) \
- $(LIB_DLOPEN) \
- $(LIB_CLOCK_GETTIME)
+libqpidcommon_la_LIBADD = \
+ $(APR_LIBS) \
+ $(LIB_DLOPEN) \
+ $(LIB_CLOCK_GETTIME) \
+ -lboost_program_options
-libqpidcommon_la_LDFLAGS = \
- -version-info \
+libqpidcommon_la_LDFLAGS = \
+ -version-info \
$(LIBTOOL_VERSION_INFO_ARG)
libqpidcommon_la_SOURCES = \
@@ -72,12 +73,13 @@ libqpidcommon_la_SOURCES = \
$(framing)/ProtocolVersionException.cpp \
$(framing)/Value.cpp \
$(gen)/AMQP_ClientProxy.cpp \
- $(gen)/AMQP_HighestVersion.h \
+ $(gen)/AMQP_HighestVersion.h \
$(gen)/AMQP_MethodVersionMap.cpp \
$(gen)/AMQP_ServerProxy.cpp \
Exception.cpp \
ExceptionHolder.cpp \
QpidError.cpp \
+ CommonOptions.cpp \
sys/Runnable.cpp \
sys/Time.cpp
@@ -109,6 +111,7 @@ nobase_pkginclude_HEADERS = \
ExceptionHolder.h \
QpidError.h \
SharedObject.h \
+ CommonOptions.cpp \
sys/Acceptor.h \
sys/AtomicCount.h \
sys/Module.h \
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am
index 40398eb2c9..42b86f98e6 100644
--- a/cpp/src/Makefile.am
+++ b/cpp/src/Makefile.am
@@ -1,14 +1,16 @@
AM_CXXFLAGS = $(WARNING_CFLAGS)
-INCLUDES = \
- -I$(top_srcdir)/gen \
- -I$(top_srcdir)/lib/broker \
- -I$(top_srcdir)/lib/common \
- -I$(top_srcdir)/lib/common/framing \
+
+INCLUDES = \
+ -I$(top_srcdir)/gen \
+ -I$(top_srcdir)/lib/broker \
+ -I$(top_srcdir)/lib/common \
+ -I$(top_srcdir)/lib/common/framing \
-I$(top_srcdir)/lib/common/sys
-LDADD = \
- ../lib/broker/libqpidbroker.la \
- ../lib/common/libqpidcommon.la
+LDADD = \
+ ../lib/broker/libqpidbroker.la \
+ ../lib/common/libqpidcommon.la \
+ -lboost_program_options
sbin_PROGRAMS = qpidd
qpidd_SOURCES = qpidd.cpp
diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp
index 9f658ebf74..532636602e 100644
--- a/cpp/src/qpidd.cpp
+++ b/cpp/src/qpidd.cpp
@@ -19,62 +19,92 @@
*
*/
#include <Broker.h>
-#include <Configuration.h>
#include <signal.h>
#include <iostream>
#include <memory>
-#include <cerrno>
#include <config.h>
#include <unistd.h>
-static char const* programName = "qpidd";
+using namespace qpid;
using namespace qpid::broker;
using namespace qpid::sys;
+using namespace std;
-Broker::shared_ptr broker;
+/** Command line options */
+struct QpiddOptions : public Broker::Options
+{
+ bool help;
+ bool version;
+ bool daemon;
+ po::options_description desc;
+
+ QpiddOptions() :
+ help(false), version(false), daemon(false), desc("Options")
+ {
+ using namespace po;
+ desc.add_options()
+ ("daemon,d", optValue(daemon), "Run as a daemon");
+ Broker::Options::addTo(desc);
+ desc.add_options()
+ ("help,h", optValue(help), "Print help message")
+ ("version,v", optValue(version), "Print version information");
+ }
+
+ void parse(int argc, char* argv[]) {
+ po::variables_map vm;
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+ };
+
+ void usage(std::ostream& out) const {
+ out << "Usage: qpidd [OPTIONS]" << endl
+ << "Start the Qpid AMQP broker." << endl << endl
+ << desc << endl;
+ };
+};
+
+std::ostream& operator<<(std::ostream& out, const QpiddOptions& config) {
+ config.usage(out); return out;
+}
+
+Broker::shared_ptr brokerPtr;
void handle_signal(int /*signal*/){
- std::cerr << "Shutting down..." << std::endl;
- broker->shutdown();
+ if (brokerPtr) {
+ cerr << "Shutting down..." << endl;
+ brokerPtr->shutdown();
+ }
}
-int main(int argc, char** argv)
+int main(int argc, char* argv[])
{
- Configuration config;
+ QpiddOptions config;
try {
- config.parse(programName, argc, argv);
-
- if(config.isHelp()){
- config.usage();
- }else if(config.isVersion()){
- std::cout << programName << " (" << PACKAGE_NAME << ") version "
- << PACKAGE_VERSION << std::endl;
- }else{
- broker = Broker::create(config);
+ config.parse(argc, argv);
+ if(config.help) {
+ config.usage(cout);
+ }
+ else if (config.version) {
+ cout << "qpidd (" << PACKAGE_NAME << ") version "
+ << PACKAGE_VERSION << endl;
+ }
+ else {
+ brokerPtr=Broker::create(config);
signal(SIGINT, handle_signal);
- if (config.isDaemon()) {
- // Detach & run as daemon.
- int chdirRoot = 0; // 0 means chdir to root.
- int closeStd = 0; // 0 means close stdin/out/err
- if (daemon(chdirRoot, closeStd) < 0) {
- char buf[512];
-
- std::cerr << "Failed to detach as daemon: "
- << strerror_r(errno, buf, sizeof(buf))
- << std::endl;;
- return 1;
- }
+ if (config.daemon) {
+ if (daemon(0, 0) < 0) // daemon(nochdir, noclose)
+ throw QPID_ERROR(
+ INTERNAL_ERROR,
+ "Failed to detach as daemon: "+ strError(errno));
}
- broker->run();
+ brokerPtr->run();
}
return 0;
}
- catch (const Configuration::BadOptionException& e) {
- std::cerr << e.what() << std::endl << std::endl;
- config.usage();
- } catch(const std::exception& e) {
- std::cerr << e.what() << std::endl;
+ catch(const exception& e) {
+ cerr << "Error: " << e.what() << endl
+ << "Type 'qpidd --help' for usage." << endl;
}
return 1;
}
diff --git a/cpp/tests/ConfigurationTest.cpp b/cpp/tests/ConfigurationTest.cpp
deleted file mode 100644
index 3a1d5ba85d..0000000000
--- a/cpp/tests/ConfigurationTest.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *
- * 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 <Configuration.h>
-#include <qpid_test_plugin.h>
-#include <iostream>
-
-using namespace std;
-using namespace qpid::broker;
-
-class ConfigurationTest : public CppUnit::TestCase
-{
- CPPUNIT_TEST_SUITE(ConfigurationTest);
- CPPUNIT_TEST(testIsHelp);
- CPPUNIT_TEST(testPortLongForm);
- CPPUNIT_TEST(testPortShortForm);
- CPPUNIT_TEST(testStore);
- CPPUNIT_TEST(testStagingThreshold);
- CPPUNIT_TEST(testVarious);
- CPPUNIT_TEST_SUITE_END();
-
- public:
-
- void testIsHelp()
- {
- Configuration conf;
- char* argv[] = {"ignore", "--help"};
- conf.parse("ignore", 2, argv);
- CPPUNIT_ASSERT(conf.isHelp());
- }
-
- void testPortLongForm()
- {
- Configuration conf;
- char* argv[] = {"ignore", "--port", "6789"};
- conf.parse("ignore", 3, argv);
- CPPUNIT_ASSERT_EQUAL(6789, conf.getPort());
- }
-
- void testPortShortForm()
- {
- Configuration conf;
- char* argv[] = {"ignore", "-p", "6789"};
- conf.parse("ignore", 3, argv);
- CPPUNIT_ASSERT_EQUAL(6789, conf.getPort());
- }
-
- void testStore()
- {
- Configuration conf;
- char* argv[] = {"ignore", "--store", "my-store-module.so"};
- conf.parse("ignore", 3, argv);
- std::string expected("my-store-module.so");
- CPPUNIT_ASSERT_EQUAL(expected, conf.getStore());
- }
-
- void testStagingThreshold()
- {
- Configuration conf;
- char* argv[] = {"ignore", "--staging-threshold", "123456789"};
- conf.parse("ignore", 3, argv);
- long expected = 123456789;
- CPPUNIT_ASSERT_EQUAL(expected, conf.getStagingThreshold());
- }
-
- void testVarious()
- {
- Configuration conf;
- char* argv[] = {"ignore", "-t", "--worker-threads", "10"};
- conf.parse("ignore", 4, argv);
- CPPUNIT_ASSERT_EQUAL(5672, conf.getPort());//default
- CPPUNIT_ASSERT_EQUAL(10, conf.getWorkerThreads());
- CPPUNIT_ASSERT(conf.isTrace());
- CPPUNIT_ASSERT(!conf.isHelp());
- }
-};
-
-// Make this test suite a plugin.
-CPPUNIT_PLUGIN_IMPLEMENT();
-CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurationTest);
-
diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am
index 7764d79721..7f6de0d28e 100644
--- a/cpp/tests/Makefile.am
+++ b/cpp/tests/Makefile.am
@@ -29,7 +29,6 @@ client_tests = \
broker_tests = \
AccumulatedAckTest \
ChannelTest \
- ConfigurationTest \
ExchangeTest \
HeadersExchangeTest \
InMemoryContentTest \
@@ -66,6 +65,9 @@ unit_tests = \
noinst_PROGRAMS = $(client_tests)
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+
TESTS_ENVIRONMENT = \
VALGRIND=$(VALGRIND) \
abs_builddir='$(abs_builddir)' \
@@ -80,7 +82,6 @@ DISTCLEANFILES=gen.mk
include gen.mk
-abs_builddir = @abs_builddir@
extra_libs = $(CPPUNIT_LIBS)
lib_client = $(abs_builddir)/../lib/client/libqpidclient.la
lib_common = $(abs_builddir)/../lib/common/libqpidcommon.la