diff options
author | Alan Conway <aconway@apache.org> | 2008-01-14 14:55:46 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2008-01-14 14:55:46 +0000 |
commit | 1de1c47ea1a106a5c37d9b0d32e37a0f15a74819 (patch) | |
tree | 4c2aef89fbba6e18f29a62558e415e4714b94137 /qpid/cpp/src/qpidd.cpp | |
parent | 3cb1b0afd5306b0b579e91d47856e21b71d4c51b (diff) | |
download | qpid-python-1de1c47ea1a106a5c37d9b0d32e37a0f15a74819.tar.gz |
Apply patch from QPID-732 by Ted Ross.
The attached patch provides support for plugin modules in the C++ broker.
- Plugins are supported (--load <lib>, --load-dir <dir> options provided)
- Command options may be extended by plugins.
- A workaround was added to make config-file parsing tolerant of unregistered options.
- Store-specific options were removed so they can be supplied by a plugin
- A pre-log facility was introduced so log messages can be generated prior to the initialization of the logging module.
File-by-file details:
M cpp/src/qpidd.cpp
Added support for loadable plugin modules. This involves a
two-phased handling of command line/config options. Phase-1
determines which modules to load and phase-2 is based on all of
the command-line options supplied by qpidd and the loaded
plugins.
M cpp/src/Makefile.am
Added dependency for boost_filesystem library.
M cpp/src/qpid/Plugin.h
Added 'earlyInitialize' method. Plugins are now initialized at
two points: earlyInitialize is called prior to broker
initialization and initialize is called at the end of broker
init. This allows modules like the store to be hooked in early
and other modules to be able to assume that the broker target is
fully functional.
M cpp/src/qpid/cluster/ClusterPlugin.cpp
Added stub for the new pure-virtual earlyInitialize method.
M cpp/src/qpid/Options.h
M cpp/src/qpid/Options.cpp
Added 'allowUnknown' option in the parse method. This is needed
in phase-1 command processing when there are options for
not-yet-loaded plugin modules.
Because the stable version of boost does not permit 'allowUnknown'
for config files, a workaround has been implemented in this module
to pre-filter the config file text removing lines that represent
unknown options.
M cpp/src/qpid/broker/Broker.h
M cpp/src/qpid/broker/Broker.cpp
Removed all store-specific command options. Updated logic to
allow the store to be a plugin module.
M cpp/src/qpid/broker/DtxManager.h
M cpp/src/qpid/broker/DtxManager.cpp
M cpp/src/qpid/broker/QueueRegistry.h
M cpp/src/qpid/broker/QueueRegistry.cpp
Changed API to these classes such that the store is no longer
supplied in the constructor but is supplied later, before any
operations are called for.
M cpp/src/qpid/broker/MessageStoreModule.h
M cpp/src/qpid/broker/MessageStoreModule.cpp
This module is still needed to provide "exception transfer"
service. It was changed to not load the store module but rather
use the already-loaded plugin store.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@611823 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src/qpidd.cpp')
-rw-r--r-- | qpid/cpp/src/qpidd.cpp | 85 |
1 files changed, 78 insertions, 7 deletions
diff --git a/qpid/cpp/src/qpidd.cpp b/qpid/cpp/src/qpidd.cpp index 00fa8d8d21..1081805c03 100644 --- a/qpid/cpp/src/qpidd.cpp +++ b/qpid/cpp/src/qpidd.cpp @@ -27,6 +27,7 @@ #include "qpid/Plugin.h" #include "qpid/sys/Shlib.h" #include "config.h" +#include <boost/filesystem/operations.hpp> #include <boost/filesystem/path.hpp> #include <iostream> #include <fstream> @@ -36,7 +37,23 @@ using namespace qpid; using namespace qpid::broker; using namespace qpid::sys; +using namespace qpid::log; using namespace std; +namespace fs=boost::filesystem; + +struct ModuleOptions : public qpid::Options { + string loadDir; + vector<string> load; + bool noLoad; + ModuleOptions() : qpid::Options("Module options"), loadDir("/usr/lib/qpidd"), noLoad(false) + { + addOptions() + ("load-dir", optValue(loadDir, "DIR"), "Load all modules from this directory") + ("load", optValue(load, "FILE"), "Specifies additional module(s) to be loaded") + ("no-modules", optValue(noLoad), "Don't load any modules"); + } +}; + struct DaemonOptions : public qpid::Options { bool daemon; @@ -57,12 +74,14 @@ struct DaemonOptions : public qpid::Options { struct QpiddOptions : public qpid::Options { CommonOptions common; + ModuleOptions module; Broker::Options broker; DaemonOptions daemon; qpid::log::Options log; QpiddOptions() : qpid::Options("Options"), common("", "/etc/qpidd.conf") { add(common); + add(module); add(broker); add(daemon); add(log); @@ -79,6 +98,23 @@ struct QpiddOptions : public qpid::Options { }; }; +// BootstrapOptions is a minimal subset of options used for a pre-parse +// of the command line to discover which plugin modules need to be loaded. +// The pre-parse is necessary because plugin modules may supply their own +// set of options. CommonOptions is needed to properly support loading +// from a configuration file. +struct BootstrapOptions : public qpid::Options { + CommonOptions common; + ModuleOptions module; + qpid::log::Options log; + + BootstrapOptions() : qpid::Options("Options"), common("", "/etc/qpidd.conf") { + add(common); + add(module); + add(log); + } +}; + // Globals shared_ptr<Broker> brokerPtr; auto_ptr<QpiddOptions> options; @@ -108,24 +144,59 @@ struct QpiddDaemon : public Daemon { void tryShlib(const char* libname) { try { Shlib shlib(libname); + QPID_LOG (info, "Loaded Module: " << libname); + } + catch (const exception& e) {} +} + +void loadModuleDir (string dirname, bool isDefault) +{ + fs::path dirPath (dirname); + + if (!fs::exists (dirPath)) + { + if (isDefault) + return; + throw Exception ("Directory not found: " + dirname); } - catch (const exception& e) { - // TODO aconway 2007-07-09: Should log failures as INFO - // at least, but we try shlibs before logging is configured. + + fs::directory_iterator endItr; + for (fs::directory_iterator itr (dirPath); itr != endItr; ++itr) + { + if (!fs::is_directory(*itr) && + itr->string().find (".so") == itr->string().length() - 3) + tryShlib (itr->string().data()); } } int main(int argc, char* argv[]) { - try { - // Load optional modules - tryShlib("libqpidcluster.so.0"); + try + { + { + BootstrapOptions bootOptions; + string defaultPath (bootOptions.module.loadDir); + + // Parse only the common, load, and log options to see which modules need + // to be loaded. Once the modules are loaded, the command line will + // be re-parsed with all of the module-supplied options. + bootOptions.parse (argc, argv, bootOptions.common.config, true); + qpid::log::Logger::instance().configure(bootOptions.log, argv[0]); + if (!bootOptions.module.noLoad) { + for (vector<string>::iterator iter = bootOptions.module.load.begin(); + iter != bootOptions.module.load.end(); + iter++) + tryShlib (iter->data()); + + bool isDefault = defaultPath == bootOptions.module.loadDir; + loadModuleDir (bootOptions.module.loadDir, isDefault); + } + } // Parse options options.reset(new QpiddOptions()); options->parse(argc, argv, options->common.config); - qpid::log::Logger::instance().configure(options->log, argv[0]); // Options that just print information. if(options->common.help || options->common.version) { |