Browse Source

[master] Merge branch 'trac3401'

D2 now supports with-kea-config switch.
Thomas Markwalder 11 years ago
parent
commit
004f6cec32

+ 11 - 3
src/bin/d2/Makefile.am

@@ -50,12 +50,12 @@ BUILT_SOURCES = spec_config.h d2_messages.h d2_messages.cc
 pkglibexec_PROGRAMS = b10-dhcp-ddns
 
 b10_dhcp_ddns_SOURCES  = main.cc
+b10_dhcp_ddns_SOURCES += d_process.h
+b10_dhcp_ddns_SOURCES += d_controller.cc d_controller.h
+b10_dhcp_ddns_SOURCES += d_cfg_mgr.cc d_cfg_mgr.h
 b10_dhcp_ddns_SOURCES += d2_asio.h
 b10_dhcp_ddns_SOURCES += d2_log.cc d2_log.h
 b10_dhcp_ddns_SOURCES += d2_process.cc d2_process.h
-b10_dhcp_ddns_SOURCES += d_controller.cc d_controller.h
-b10_dhcp_ddns_SOURCES += d2_controller.cc d2_controller.h
-b10_dhcp_ddns_SOURCES += d_cfg_mgr.cc d_cfg_mgr.h
 b10_dhcp_ddns_SOURCES += d2_config.cc d2_config.h
 b10_dhcp_ddns_SOURCES += d2_cfg_mgr.cc d2_cfg_mgr.h
 b10_dhcp_ddns_SOURCES += d2_queue_mgr.cc d2_queue_mgr.h
@@ -69,6 +69,14 @@ b10_dhcp_ddns_SOURCES += nc_remove.cc nc_remove.h
 b10_dhcp_ddns_SOURCES += nc_trans.cc nc_trans.h
 b10_dhcp_ddns_SOURCES += state_model.cc state_model.h
 
+if CONFIG_BACKEND_BUNDY
+b10_dhcp_ddns_SOURCES += bundy_d2_controller.cc bundy_d2_controller.h
+else
+if CONFIG_BACKEND_JSON
+b10_dhcp_ddns_SOURCES += d2_controller.cc d2_controller.h
+endif
+endif
+
 nodist_b10_dhcp_ddns_SOURCES = d2_messages.h d2_messages.cc
 EXTRA_DIST += d2_messages.mes
 

+ 294 - 0
src/bin/d2/bundy_d2_controller.cc

@@ -0,0 +1,294 @@
+// Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <d2/bundy_d2_controller.h>
+#include <d2/d2_process.h>
+#include <d2/spec_config.h>
+
+#include <sstream>
+
+namespace isc {
+namespace d2 {
+
+/// @brief Defines the application name, this is passed into base class
+/// it may be used to locate configuration data and appears in log statement.
+const char* D2Controller::d2_app_name_ = "DHCP-DDNS";
+
+/// @brief Defines the executable name. This is passed into the base class
+const char* D2Controller::d2_bin_name_ = "b10-dhcp-ddns";
+
+DControllerBasePtr&
+D2Controller::instance() {
+    // If the instance hasn't been created yet, create it.  Note this method
+    // must use the base class singleton instance methods.  The base class
+    // must have access to the singleton in order to use it within BUNDY
+    // static function callbacks.
+    if (!getController()) {
+        DControllerBasePtr controller_ptr(new D2Controller());
+        setController(controller_ptr);
+    }
+
+    return (getController());
+}
+
+DProcessBase* D2Controller::createProcess() {
+    // Instantiate and return an instance of the D2 application process. Note
+    // that the process is passed the controller's io_service.
+    return (new D2Process(getAppName().c_str(), getIOService()));
+}
+
+D2Controller::D2Controller()
+    : DControllerBase(d2_app_name_, d2_bin_name_) {
+    // set the spec file either from the environment or
+    // use the production value.
+    if (getenv("B10_FROM_BUILD")) {
+        setSpecFileName(std::string(getenv("B10_FROM_BUILD")) +
+            "/src/bin/d2/dhcp-ddns.spec");
+    } else {
+        setSpecFileName(D2_SPECFILE_LOCATION);
+    }
+}
+
+D2Controller::~D2Controller() {
+}
+
+void
+D2Controller::launch(int argc, char* argv[], const bool test_mode) {
+    // Step 1 is to parse the command line arguments.
+    try {
+        parseArgs(argc, argv);
+    } catch (const InvalidUsage& ex) {
+        usage(ex.what());
+        throw; // rethrow it
+    }
+
+    // Do not initialize logger here if we are running unit tests. It would
+    // replace an instance of unit test specific logger.
+    if (!test_mode) {
+        // Now that we know what the mode flags are, we can init logging.
+        // If standalone is enabled, do not buffer initial log messages
+        isc::log::initLogger(getBinName(),
+                             (isVerbose() ? isc::log::DEBUG : isc::log::INFO),
+                             isc::log::MAX_DEBUG_LEVEL, NULL, true);
+    }
+
+    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_STARTING)
+              .arg(getAppName()).arg(getpid());
+    try {
+        // Step 2 is to create and initialize the application process object.
+        initProcess();
+    } catch (const std::exception& ex) {
+        LOG_FATAL(dctl_logger, DCTL_INIT_PROCESS_FAIL)
+                  .arg(getAppName()).arg(ex.what());
+        isc_throw (ProcessInitError,
+                   "Application Process initialization failed: " << ex.what());
+    }
+
+    // Next we connect to Bundy.
+    try {
+        establishSession();
+    } catch (const std::exception& ex) {
+        LOG_FATAL(dctl_logger, DCTL_SESSION_FAIL).arg(ex.what());
+        isc_throw (SessionStartError,
+                   "Session start up failed: " << ex.what());
+    }
+
+    // Everything is clear for launch, so start the application's
+    // event loop.
+    try {
+        runProcess();
+    } catch (const std::exception& ex) {
+        LOG_FATAL(dctl_logger, DCTL_PROCESS_FAILED)
+                  .arg(getAppName()).arg(ex.what());
+        isc_throw (ProcessRunError,
+                   "Application process event loop failed: " << ex.what());
+    }
+
+    // Disconnect from Bundy.
+    try {
+        disconnectSession();
+    } catch (const std::exception& ex) {
+        LOG_ERROR(dctl_logger, DCTL_DISCONNECT_FAIL)
+                  .arg(getAppName()).arg(ex.what());
+        isc_throw (SessionEndError, "Session end failed: " << ex.what());
+    }
+
+    // All done, so bail out.
+    LOG_INFO(dctl_logger, DCTL_STOPPING).arg(getAppName());
+}
+
+void
+D2Controller::parseArgs(int argc, char* argv[])
+{
+    // Iterate over the given command line options. If its a stock option
+    // ("s" or "v") handle it here.  If its a valid custom option, then
+    // invoke customOption.
+    int ch;
+    opterr = 0;
+    optind = 1;
+    std::string opts(":v" + getCustomOpts());
+    while ((ch = getopt(argc, argv, opts.c_str())) != -1) {
+        switch (ch) {
+        case 'v':
+            // Enables verbose logging.
+            setVerbose(true);
+            break;
+
+        case '?': {
+            // We hit an invalid option.
+            isc_throw(InvalidUsage, "unsupported option: ["
+                      << static_cast<char>(optopt) << "] "
+                      << (!optarg ? "" : optarg));
+
+            break;
+            }
+
+        default:
+            // We hit a valid custom option
+            if (!customOption(ch, optarg)) {
+                // This would be a programmatic error.
+                isc_throw(InvalidUsage, " Option listed but implemented?: ["
+                          << static_cast<char>(ch) << "] "
+                          << (!optarg ? "" : optarg));
+            }
+            break;
+        }
+    }
+
+    // There was too much information on the command line.
+    if (argc > optind) {
+        isc_throw(InvalidUsage, "extraneous command line information");
+    }
+}
+
+void
+D2Controller::establishSession() {
+    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CCSESSION_STARTING)
+              .arg(getAppName()).arg(getSpecFileName());
+
+    // Create the BIND10 command control session with the our IOService.
+    cc_session_ = SessionPtr(new isc::cc::Session(
+                             getIOService()->get_io_service()));
+
+    // Create the BIND10 config session with the stub configuration handler.
+    // This handler is internally invoked by the constructor and on success
+    // the constructor updates the current session with the configuration that
+    // had been committed in the previous session. If we do not install
+    // the dummy handler, the previous configuration would be lost.
+    config_session_ = ModuleCCSessionPtr(new isc::config::ModuleCCSession(
+                                         getSpecFileName(), *cc_session_,
+                                         dummyConfigHandler, 
+                                         DControllerBase::commandHandler,
+                                         false));
+    // Enable configuration even processing.
+    config_session_->start();
+
+    // We initially create ModuleCCSession() with a dummy configHandler, as
+    // the session module is too eager to send partial configuration.
+    // Replace the dummy config handler with the real handler.
+    config_session_->setConfigHandler(DControllerBase::configHandler);
+
+    // Call the real configHandler with the full configuration retrieved
+    // from the config session.
+    isc::data::ConstElementPtr answer = configHandler(
+                                            config_session_->getFullConfig());
+
+    // Parse the answer returned from the configHandler.  Log the error but
+    // keep running. This provides an opportunity for the user to correct
+    // the configuration dynamically.
+    int ret = 0;
+    isc::data::ConstElementPtr comment = isc::config::parseAnswer(ret, answer);
+    if (ret) {
+        LOG_ERROR(dctl_logger, DCTL_CONFIG_LOAD_FAIL)
+                  .arg(getAppName()).arg(comment->str());
+    }
+}
+
+void D2Controller::disconnectSession() {
+    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CCSESSION_ENDING)
+              .arg(getAppName());
+
+    // Destroy the BIND10 config session.
+    if (config_session_) {
+        config_session_.reset();
+    }
+
+    // Destroy the BIND10 command and control session.
+    if (cc_session_) {
+        cc_session_->disconnect();
+        cc_session_.reset();
+    }
+}
+
+isc::data::ConstElementPtr
+D2Controller::dummyConfigHandler(isc::data::ConstElementPtr) {
+    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CONFIG_STUB)
+             .arg(getController()->getAppName());
+    return (isc::config::createAnswer(0, "Configuration accepted."));
+}
+
+isc::data::ConstElementPtr
+D2Controller::updateConfig(isc::data::ConstElementPtr new_config) {
+    if (!config_session_) {
+        // That should never happen as we install config_handler
+        // after we instantiate the server.
+        isc::data::ConstElementPtr answer =
+            isc::config::createAnswer(1, "Configuration rejected,"
+                                              " Session has not started.");
+        return (answer);
+    }
+
+    // Let's get the existing configuration.
+    isc::data::ConstElementPtr full_config = config_session_->getFullConfig();
+
+    // The configuration passed to this handler function is partial.
+    // In other words, it just includes the values being modified.
+    // In the same time, there may be dependencies between various
+    // configuration parsers. For example: the option value can
+    // be set if the definition of this option is set. If someone removes
+    // an existing option definition then the partial configuration that
+    // removes that definition is triggered while a relevant option value
+    // may remain configured. This eventually results in the
+    // configuration being in the inconsistent state.
+    // In order to work around this problem we need to merge the new
+    // configuration with the existing (full) configuration.
+
+    // Let's create a new object that will hold the merged configuration.
+    boost::shared_ptr<isc::data::MapElement>
+                            merged_config(new isc::data::MapElement());
+
+    // Merge an existing and new configuration.
+    merged_config->setValue(full_config->mapValue());
+    isc::data::merge(merged_config, new_config);
+
+    // Send the merged configuration to the application.
+    return (getProcess()->configure(merged_config));
+}
+
+
+void
+D2Controller::usage(const std::string & text)
+{
+    if (text != "") {
+        std::cerr << "Usage error: " << text << std::endl;
+    }
+
+    std::cerr << "Usage: " << getBinName() <<  std::endl;
+    std::cerr << "  -v: verbose output" << std::endl;
+    std::cerr << getUsageText() << std::endl;
+}
+
+
+}; // namespace isc::d2
+}; // namespace isc

+ 230 - 0
src/bin/d2/bundy_d2_controller.h

@@ -0,0 +1,230 @@
+// Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef BUNDY_D2_CONTROLLER_H
+#define BUNDY_D2_CONTROLLER_H
+
+#include <cc/data.h>
+#include <cc/session.h>
+#include <config/ccsession.h>
+#include <d2/d2_asio.h>
+#include <d2/d2_log.h>
+#include <d2/d_controller.h>
+#include <d2/d_process.h>
+#include <exceptions/exceptions.h>
+#include <log/logger_support.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+
+
+namespace isc {
+namespace d2 {
+
+/// @brief Exception thrown when the session start up fails.
+class SessionStartError: public isc::Exception {
+public:
+    SessionStartError (const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) { };
+};
+
+/// @brief Exception thrown when the session end fails.
+class SessionEndError: public isc::Exception {
+public:
+    SessionEndError (const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) { };
+};
+
+/// @brief Defines a shared pointer to a Session.
+typedef boost::shared_ptr<isc::cc::Session> SessionPtr;
+
+/// @brief Defines a shared pointer to a ModuleCCSession.
+typedef boost::shared_ptr<isc::config::ModuleCCSession> ModuleCCSessionPtr;
+
+/// @brief Bundy-integrated Process Controller for D2 Process 
+/// This class is the DHCP-DDNS specific derivation of DControllerBase which
+/// is managed by BUNDY. It creates and manages an instance of the DHCP-DDNS 
+/// application process, D2Process.
+///
+/// D2 will be constructed with this class if the project is configured with
+/// --with-kea-config=BUNDY
+class D2Controller : public DControllerBase {
+public:
+    /// @brief Static singleton instance method. This method returns the
+    /// base class singleton instance member.  It instantiates the singleton
+    /// and sets the base class instance member upon first invocation.
+    ///
+    /// @return returns the pointer reference to the singleton instance.
+    static DControllerBasePtr& instance();
+
+    /// @brief Destructor.
+    virtual ~D2Controller();
+
+    /// @brief Defines the application name, this is passed into base class
+    /// and appears in log statements.
+    static const char* d2_app_name_;
+
+    /// @brief Defines the executable name. This is passed into the base class
+    /// by convention this should match the BUNDY module name.
+    static const char* d2_bin_name_;
+
+    /// @brief Acts as the primary entry point into the controller execution
+    /// and provides the outermost application control logic:
+    ///
+    /// 1. parse command line arguments
+    /// 2. instantiate and initialize the application process
+    /// 3. establish BUNDY session(s) if in integrated mode
+    /// 4. start and wait on the application process event loop
+    /// 5. upon event loop completion, disconnect from BUNDY (if needed)
+    /// 6. exit to the caller
+    ///
+    /// It is intended to be called from main() and be given the command line
+    /// arguments. Note this method is deliberately not virtual to ensure the
+    /// proper sequence of events occur.
+    ///
+    /// This function can be run in the test mode. It prevents initialization
+    /// of D2 module logger. This is used in unit tests which initialize logger
+    /// in their main function. Such logger uses environmental variables to
+    /// control severity, verbosity etc. Reinitialization of logger by this
+    /// function would replace unit tests specific logger configuration with
+    /// this suitable for D2 running as a bind10 module.
+    ///
+    /// @param argc  is the number of command line arguments supplied
+    /// @param argv  is the array of string (char *) command line arguments
+    /// @param test_mode is a bool value which indicates if
+    /// @c DControllerBase::launch should be run in the test mode (if true).
+    /// This parameter doesn't have default value to force test implementers to
+    /// enable test mode explicitly.
+    ///
+    /// @throw throws one of the following exceptions:
+    /// InvalidUsage - Indicates invalid command line.
+    /// ProcessInitError  - Failed to create and initialize application
+    /// process object.
+    /// SessionStartError  - Could not connect to BUNDY (integrated mode only).
+    /// ProcessRunError - A fatal error occurred while in the application
+    /// process event loop.
+    /// SessionEndError - Could not disconnect from BUNDY (integrated mode
+    /// only).
+    virtual void launch(int argc, char* argv[], const bool test_mode);
+
+    /// @brief A dummy configuration handler that always returns success.
+    ///
+    /// This configuration handler does not perform configuration
+    /// parsing and always returns success. A dummy handler should
+    /// be installed using \ref isc::config::ModuleCCSession ctor
+    /// to get the initial configuration. This initial configuration
+    /// comprises values for only those elements that were modified
+    /// the previous session. The D2 configuration parsing can't be
+    /// used to parse the initial configuration because it may need the
+    /// full configuration to satisfy dependencies between the
+    /// various configuration values. Installing the dummy handler
+    /// that guarantees to return success causes initial configuration
+    /// to be stored for the session being created and that it can
+    /// be later accessed with \ref isc::config::ConfigData::getFullConfig.
+    ///
+    /// @param new_config new configuration.
+    ///
+    /// @return success configuration status.
+    static isc::data::ConstElementPtr
+    dummyConfigHandler(isc::data::ConstElementPtr new_config);
+
+    /// @brief Instance method invoked by the configuration event handler and
+    /// which processes the actual configuration update.  Provides behavioral
+    /// path for both integrated and stand-alone modes. The current
+    /// implementation will merge the configuration update into the existing
+    /// configuration and then invoke the application process' configure method.
+    ///
+    /// @todo This implementation is will evolve as the D2 configuration
+    /// management task is implemented (trac #2957).
+    ///
+    /// @param  new_config is the new configuration
+    ///
+    /// @return returns an Element that contains the results of configuration
+    /// update composed of an integer status value (0 means successful,
+    /// non-zero means failure), and a string explanation of the outcome.
+    virtual isc::data::ConstElementPtr
+    updateConfig(isc::data::ConstElementPtr new_config);
+
+protected:
+    /// @brief Processes the command line arguments. It is the first step
+    /// taken after the controller has been launched.  It combines the stock
+    /// list of options with those returned by getCustomOpts(), and uses
+    /// cstdlib's getopt to loop through the command line.  The stock options
+    /// It handles stock options directly, and passes any custom options into
+    /// the customOption method.  Currently there are only two stock options
+    /// -s for stand alone mode, and -v for verbose logging.
+    ///
+    /// @param argc  is the number of command line arguments supplied
+    /// @param argv  is the array of string (char *) command line arguments
+    ///
+    /// @throw throws InvalidUsage when there are usage errors.
+    void parseArgs(int argc, char* argv[]);
+
+    /// @brief Establishes connectivity with BUNDY.  This method is used
+    /// invoked during launch, if running in integrated mode, following
+    /// successful process initialization.  It is responsible for establishing
+    /// the BUNDY control and config sessions. During the session creation,
+    /// it passes in the controller's IOService and the callbacks for command
+    /// directives and config events.  Lastly, it will invoke the onConnect
+    /// method providing the derivation an opportunity to execute any custom
+    /// logic associated with session establishment.
+    ///
+    /// @throw the BUNDY framework may throw std::exceptions.
+    void establishSession();
+
+    /// @brief Terminates connectivity with BUNDY. This method is invoked
+    /// in integrated mode after the application event loop has exited. It
+    /// first calls the onDisconnect method providing the derivation an
+    /// opportunity to execute custom logic if needed, and then terminates the
+    /// BUNDY config and control sessions.
+    ///
+    /// @throw the BUNDY framework may throw std:exceptions.
+    void disconnectSession();
+
+    /// @brief Prints the program usage text to std error.
+    ///
+    /// @param text is a string message which will preceded the usage text.
+    /// This is intended to be used for specific usage violation messages.
+    void usage(const std::string& text);
+
+private:
+    /// @brief Creates an instance of the DHCP-DDNS specific application
+    /// process.  This method is invoked during the process initialization
+    /// step of the controller launch.
+    ///
+    /// @return returns a DProcessBase* to the application process created.
+    /// Note the caller is responsible for destructing the process. This
+    /// is handled by the base class, which wraps this pointer with a smart
+    /// pointer.
+    virtual DProcessBase* createProcess();
+
+    /// @brief Helper session object that represents raw connection to msgq.
+    SessionPtr cc_session_;
+
+    /// @brief Session that receives configuration and commands.
+    ModuleCCSessionPtr config_session_;
+
+    /// @brief Constructor is declared private to maintain the integrity of
+    /// the singleton instance.
+    D2Controller();
+
+    // DControllerTest is named a friend class to facilitate unit testing while
+    // leaving the intended member scopes intact.
+    friend class DControllerTest;
+};
+
+}; // namespace isc::d2
+}; // namespace isc
+
+#endif

+ 63 - 34
src/bin/d2/d2.dox

@@ -52,39 +52,45 @@ base are shown in the following class diagram:
 - isc::d2::DControllerBase - provides all of the services necessary to manage
 an application process class derived from isc::d2::DProcess. These services include:
     - Command line argument handling
-    - Process instantiation and initialization
+    - Process instantiation and initialization0
     - Support for stand-alone execution
-    - Support for integrated operation as a BIND10 module (session management
+    - Support for integrated operation as a BUNDY module (session management
       and event handling)
     - Process event loop invocation and shutdown
-    .
-    It creates and manages an instance of isc::d2::DProcessBase.  The CPL is designed
-    for asynchronous event processing applications.  It is constructed to use ASIO
-    library for IO processing.  DControllerBase own an isc::asiolink::io_service instance and it pas    ses this into the @c DProcessBase constructor and it is this
-    service that is used drivel the process's event loop.
-
-    @c DControllerBase also provides the ability to operate one of two modes:
-    "stand-alone" mode or "managed" mode.  In stand-alone mode, the controller has
-    no IO of it's own, thus there is two-way control communication between the application and the outside world.
-
-    In "managed mode" the controller creates a BIND10 Session, allowing it to
-    participate as a BIND10 module and therefore receive control commands such as
-    configuration updates, status requests, and shutdown.  BIND10 modules are
-    required to supply two callbacks: one for configuration events and one for
-    command events. @c DControllerBase supplies these callbacks which largely
-    pass the information through to its @c DProcessBase instance.  The key aspect
-    to take from this is that the controller handles the interface for receiving
-    asynchronous commands and the invokes the appropriate services in the process's
-    interface.
-
-    @todo DControllerBase does yet support reading the configuration from a
-    command line argument. It's command line argument processing can be very easily
-    extended to do so.
-
-    @todo At the time of this writing Kea is being separated from the BIND10
-    framework.  As such, use of the BIND10 Session will be removed but could
-    readily be replaced with an authenticated socket connection for receiving and
-    responding to directives asynchronously.
+
+    It creates and manages an instance of isc::d2::DProcessBase.  The CPL is
+    designed for asynchronous event processing applications.  It is constructed
+    to use ASIO library for IO processing.  @c DControllerBase owns an
+    isc::asiolink::IOService instance and it passes this into the @c
+    DProcessBase constructor. It is this @c IOService that is used to drive the
+    process's event loop.  The controller is designed to provide any interfaces
+    between the process it controls and the outside world.
+
+    @c DControllerBase provides configuration for its process via a JSON file
+    specified as a mandatory command line argument. The file structure is
+    expected be as follows:
+
+    { "<module-name>": {<module-config>} }
+
+    where:
+        - module-name : is a label which uniquely identifies the
+        configuration data for the (i.e. the controlled process.)
+        It is the value returned by @ref
+        isc::d2::DControllerBase::getAppName()
+
+        - module-config: a set of zero or more JSON elements which comprise
+        application's configuration values.  Element syntax is governed
+        by those elements supported in isc::cc.
+
+    The file may contain an arbitrary number of other modules.
+
+    @todo DControllerBase will soon support dynamic reloading of the
+    configuration file upon receipt of the SIGHUP signal, and graceful
+    shutdown upon receipt of either SIGTERM or SIGINT.
+
+    @todo Eventually, some sort of secure socket interface which supports remote
+    control operations such as configuration changes or status reporting will
+    likely be implemented.
 
 - isc::d2::DProcessBase - defines an asynchronous-event processor (i.e.
 application) which provides a uniform interface to:
@@ -105,10 +111,10 @@ information or "context".  It provides a single enclosure for the storage of
 configuration parameters or any other information that needs to accessible
 within a given context.
 
-The following sequence diagram shows how a configuration update, received
-asynchronously through the session command channel, moves through the CPL:
+The following sequence diagram shows how a configuration from file moves
+through the CPL layer:
 
-@image html config_sequence.svg "CPL Configuration Update Sequence"
+@image html config_from_file_sequence.svg "CPL Configuration From File Sequence"
 
 The CPL classes will likely move into a common library.
 
@@ -122,6 +128,29 @@ in the diagram below:
 - isc::d2::D2Controller - entry point for running D2, it processes command line
 options, starts and controls the application process, @c D2Process.
 
+Currently there are two implementations of D2Controller selected through the
+configuration script switch, "--with-kea-config":
+
+-# --with-kea-config=JSON - The implementation is contained in isc/d2/d2_controller.*.  This form allows D2 to run as a stand-alone process configured via JSON
+text file specified as a command line argument.  The file content is described
+in isc/d2/dhcp-ddns.spec, unit tests are in
+isc/d2/tests/bundy_d2_controller_unittests.cc.  As of Kea 0.9, this form will
+be the default form.
+-# --with-kea-config=BUNDY - The implementation is contained in
+isc/d2/bundy_d2_controller.*, unit tests are in isc/d2/tests/d2_controller_unittests.cc and d_controller_unittests.cc  This form allows D2 to run as a Bundy
+module. It creates a BUNDY Session, allowing it to receive control commands
+such as configuration updates, status requests, and shutdown.  BUNDY modules
+are required to supply two callbacks: one for configuration events and one for
+command events.  This form of D2Controller supplies these callbacks which
+largely pass the information through to its @c D2Process instance.   If the
+controller cannot establish a BUNDY session it will exit with a fatal error.
+
+The configuration switch determines which of two forms and tests are compiled
+and they are mutually exclusive.
+
+@note The inclusion of the BUNDY form should be considered temporary. Long range
+planning should be based on the JSON form.
+
 - isc::d2::D2Process - creates and manages D2's primary resources and implements
 the main event loop described in @ref d2EventLoop.
 
@@ -294,7 +323,7 @@ D2's design addresses this by calling for two types of transactions: one for
 adding entries and one for removing them, each with their own state model.
 The transaction classes are shown in the following diagram:
 
-@image html trans_classes.svg "NameChangeTransaction Derviations"
+@image html trans_classes.svg "NameChangeTransaction Derivations"
 
 - isc::d2::NameAddTransaction - carries out a @c NameChangeRequest to add entries
 - isc::d2::NameRemoveTransaction - carries out a @c NameChangeRequest to remove entries

+ 5 - 8
src/bin/d2/d2_controller.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -22,19 +22,16 @@ namespace isc {
 namespace d2 {
 
 /// @brief Defines the application name, this is passed into base class
-/// and appears in log statements.
-const char* D2Controller::d2_app_name_ = "DHCP-DDNS";
+/// it may be used to locate configuration data and appears in log statement.
+const char* D2Controller::d2_app_name_ = "DhcpDdns";
 
 /// @brief Defines the executable name. This is passed into the base class
-/// by convention this should match the BIND10 module name.
 const char* D2Controller::d2_bin_name_ = "b10-dhcp-ddns";
 
 DControllerBasePtr&
 D2Controller::instance() {
     // If the instance hasn't been created yet, create it.  Note this method
-    // must use the base class singleton instance methods.  The base class
-    // must have access to the singleton in order to use it within BIND10
-    // static function callbacks.
+    // must use the base class singleton instance methods.
     if (!getController()) {
         DControllerBasePtr controller_ptr(new D2Controller());
         setController(controller_ptr);
@@ -51,7 +48,7 @@ DProcessBase* D2Controller::createProcess() {
 
 D2Controller::D2Controller()
     : DControllerBase(d2_app_name_, d2_bin_name_) {
-    // set the BIND10 spec file either from the environment or
+    // set the spec file either from the environment or
     // use the production value.
     if (getenv("B10_FROM_BUILD")) {
         setSpecFileName(std::string(getenv("B10_FROM_BUILD")) +

+ 2 - 2
src/bin/d2/d2_controller.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -47,7 +47,7 @@ public:
     static const char* d2_app_name_;
 
     /// @brief Defines the executable name. This is passed into the base class
-    /// by convention this should match the BIND10 module name.
+    /// by convention this should match the executable name.
     static const char* d2_bin_name_;
 
 private:

+ 4 - 0
src/bin/d2/d2_messages.mes

@@ -37,6 +37,10 @@ This critical error message indicates that the initial application
 configuration has failed. The service will start, but will not
 process requests until the configuration has been corrected.
 
+% DCTL_CONFIG_FILE_LOAD_FAIL %1 configuration could not be loaded from file: %2
+This fatal error message indicates that the application attempted to load its
+initial configuration from file and has failed. The service will exit.
+
 % DCTL_CONFIG_START parsing new configuration: %1
 A debug message indicating that the application process has received an
 updated configuration and has passed it to its configuration manager

+ 78 - 179
src/bin/d2/d_controller.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -14,6 +14,7 @@
 
 
 #include <d2/d2_log.h>
+#include <config/ccsession.h>
 #include <d2/d_controller.h>
 #include <exceptions/exceptions.h>
 #include <log/logger_support.h>
@@ -27,12 +28,11 @@ DControllerBasePtr DControllerBase::controller_;
 
 // Note that the constructor instantiates the controller's primary IOService.
 DControllerBase::DControllerBase(const char* app_name, const char* bin_name)
-    : app_name_(app_name), bin_name_(bin_name), stand_alone_(false),
+    : app_name_(app_name), bin_name_(bin_name),
       verbose_(false), spec_file_name_(""),
       io_service_(new isc::asiolink::IOService()){
 }
 
-
 void
 DControllerBase::setController(const DControllerBasePtr& controller) {
     if (controller_) {
@@ -47,6 +47,7 @@ DControllerBase::setController(const DControllerBasePtr& controller) {
 
 void
 DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
+
     // Step 1 is to parse the command line arguments.
     try {
         parseArgs(argc, argv);
@@ -59,11 +60,7 @@ DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
     // replace an instance of unit test specific logger.
     if (!test_mode) {
         // Now that we know what the mode flags are, we can init logging.
-        // If standalone is enabled, do not buffer initial log messages
-        isc::log::initLogger(bin_name_,
-                             ((verbose_ && stand_alone_)
-                              ? isc::log::DEBUG : isc::log::INFO),
-                             isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone_);
+        Daemon::loggerInit(bin_name_.c_str(), verbose_);
     }
 
     LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_STARTING)
@@ -78,18 +75,17 @@ DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
                    "Application Process initialization failed: " << ex.what());
     }
 
-    // Next we connect if we are running integrated.
-    if (stand_alone_) {
-        LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_STANDALONE)
-                  .arg(app_name_);
-    } else {
-        try {
-            establishSession();
-        } catch (const std::exception& ex) {
-            LOG_FATAL(dctl_logger, DCTL_SESSION_FAIL).arg(ex.what());
-            isc_throw (SessionStartError,
-                       "Session start up failed: " << ex.what());
-        }
+    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_STANDALONE).arg(app_name_);
+
+    // Step 3 is to load configuration from file.
+    int rcode;
+    isc::data::ConstElementPtr comment
+        = isc::config::parseAnswer(rcode, configFromFile());
+    if (rcode != 0) {
+        LOG_FATAL(dctl_logger, DCTL_CONFIG_FILE_LOAD_FAIL)
+                  .arg(app_name_).arg(comment->stringValue());
+        isc_throw (ProcessInitError, "Could Not load configration file: "
+                   << comment->stringValue());
     }
 
     // Everything is clear for launch, so start the application's
@@ -103,22 +99,10 @@ DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
                    "Application process event loop failed: " << ex.what());
     }
 
-    // If running integrated, disconnect.
-    if (!stand_alone_) {
-        try {
-            disconnectSession();
-        } catch (const std::exception& ex) {
-            LOG_ERROR(dctl_logger, DCTL_DISCONNECT_FAIL)
-                      .arg(app_name_).arg(ex.what());
-            isc_throw (SessionEndError, "Session end failed: " << ex.what());
-        }
-    }
-
     // All done, so bail out.
     LOG_INFO(dctl_logger, DCTL_STOPPING).arg(app_name_);
 }
 
-
 void
 DControllerBase::parseArgs(int argc, char* argv[])
 {
@@ -128,7 +112,7 @@ DControllerBase::parseArgs(int argc, char* argv[])
     int ch;
     opterr = 0;
     optind = 1;
-    std::string opts(":vs" + getCustomOpts());
+    std::string opts("vc:" + getCustomOpts());
     while ((ch = getopt(argc, argv, opts.c_str())) != -1) {
         switch (ch) {
         case 'v':
@@ -136,9 +120,13 @@ DControllerBase::parseArgs(int argc, char* argv[])
             verbose_ = true;
             break;
 
-        case 's':
-            // Enables stand alone or "BINDLESS" operation.
-            stand_alone_ = true;
+        case 'c':
+            // config file name
+            if (optarg == NULL) {
+                isc_throw(InvalidUsage, "configuration file name missing");
+            }
+
+            Daemon::init(optarg);
             break;
 
         case '?': {
@@ -197,52 +185,41 @@ DControllerBase::initProcess() {
     process_->init();
 }
 
-void
-DControllerBase::establishSession() {
-    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CCSESSION_STARTING)
-              .arg(app_name_).arg(spec_file_name_);
-
-    // Create the BIND10 command control session with the our IOService.
-    cc_session_ = SessionPtr(new isc::cc::Session(
-                             io_service_->get_io_service()));
-
-    // Create the BIND10 config session with the stub configuration handler.
-    // This handler is internally invoked by the constructor and on success
-    // the constructor updates the current session with the configuration that
-    // had been committed in the previous session. If we do not install
-    // the dummy handler, the previous configuration would be lost.
-    config_session_ = ModuleCCSessionPtr(new isc::config::ModuleCCSession(
-                                         spec_file_name_, *cc_session_,
-                                         dummyConfigHandler, commandHandler,
-                                         false));
-    // Enable configuration even processing.
-    config_session_->start();
-
-    // We initially create ModuleCCSession() with a dummy configHandler, as
-    // the session module is too eager to send partial configuration.
-    // Replace the dummy config handler with the real handler.
-    config_session_->setConfigHandler(configHandler);
-
-    // Call the real configHandler with the full configuration retrieved
-    // from the config session.
-    isc::data::ConstElementPtr answer = configHandler(
-                                            config_session_->getFullConfig());
-
-    // Parse the answer returned from the configHandler.  Log the error but
-    // keep running. This provides an opportunity for the user to correct
-    // the configuration dynamically.
-    int ret = 0;
-    isc::data::ConstElementPtr comment = isc::config::parseAnswer(ret, answer);
-    if (ret) {
-        LOG_ERROR(dctl_logger, DCTL_CONFIG_LOAD_FAIL)
-                  .arg(app_name_).arg(comment->str());
+isc::data::ConstElementPtr
+DControllerBase::configFromFile() {
+    isc::data::ConstElementPtr module_config;
+
+    try {
+        std::string config_file = getConfigFile();
+        if (config_file.empty()) {
+            // Basic sanity check: file name must not be empty.
+            isc_throw(BadValue, "JSON configuration file not specified. Please "
+                                "use -c command line option.");
+        }
+
+        // Read contents of the file and parse it as JSON
+        isc::data::ConstElementPtr whole_config =
+            isc::data::Element::fromJSONFile(config_file, true);
+
+        // Extract derivation-specific portion of the configuration.
+        module_config = whole_config->get(getAppName());
+        if (!module_config) {
+            isc_throw(BadValue, "Config file " << config_file <<
+                                " does not include '" <<
+                                 getAppName() << "' entry.");
+        }
+    } catch (const std::exception& ex) {
+        // build an error result
+        isc::data::ConstElementPtr error =
+            isc::config::createAnswer(1,
+                std::string("Configuration parsing failed: ") + ex.what());
+        return (error);
     }
 
-    // Lastly, call onConnect. This allows deriving class to execute custom
-    // logic predicated by session connect.
-    onSessionConnect();
+    return (updateConfig(module_config));
 }
 
+
 void
 DControllerBase::runProcess() {
     LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_RUN_PROCESS).arg(app_name_);
@@ -256,105 +233,14 @@ DControllerBase::runProcess() {
     process_->run();
 }
 
-void DControllerBase::disconnectSession() {
-    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CCSESSION_ENDING)
-              .arg(app_name_);
-
-    // Call virtual onDisconnect. Allows deriving class to execute custom
-    // logic prior to session loss.
-    onSessionDisconnect();
-
-    // Destroy the BIND10 config session.
-    if (config_session_) {
-        config_session_.reset();
-    }
-
-    // Destroy the BIND10 command and control session.
-    if (cc_session_) {
-        cc_session_->disconnect();
-        cc_session_.reset();
-    }
-}
-
-isc::data::ConstElementPtr
-DControllerBase::dummyConfigHandler(isc::data::ConstElementPtr) {
-    LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CONFIG_STUB)
-             .arg(controller_->getAppName());
-    return (isc::config::createAnswer(0, "Configuration accepted."));
-}
-
-isc::data::ConstElementPtr
-DControllerBase::configHandler(isc::data::ConstElementPtr new_config) {
-
-    LOG_DEBUG(dctl_logger, DBGLVL_COMMAND, DCTL_CONFIG_UPDATE)
-              .arg(controller_->getAppName()).arg(new_config->str());
-
-    // Invoke the instance method on the controller singleton.
-    return (controller_->updateConfig(new_config));
-}
-
-// Static callback which invokes non-static handler on singleton
-isc::data::ConstElementPtr
-DControllerBase::commandHandler(const std::string& command,
-                                isc::data::ConstElementPtr args) {
-
-    LOG_DEBUG(dctl_logger, DBGLVL_COMMAND, DCTL_COMMAND_RECEIVED)
-        .arg(controller_->getAppName()).arg(command)
-        .arg(args ? args->str() : "(no args)");
-
-    // Invoke the instance method on the controller singleton.
-    return (controller_->executeCommand(command, args));
-}
-
+// Instance method for handling new config
 isc::data::ConstElementPtr
 DControllerBase::updateConfig(isc::data::ConstElementPtr new_config) {
-    isc::data::ConstElementPtr full_config;
-    if (stand_alone_) {
-        // @todo Until there is a configuration manager to provide retrieval
-        // we'll just assume the incoming config is the full configuration set.
-        // It may also make more sense to isolate the controller from the
-        // configuration manager entirely. We could do something like
-        // process_->getFullConfig() here for stand-alone mode?
-        full_config = new_config;
-    } else {
-        if (!config_session_) {
-            // That should never happen as we install config_handler
-            // after we instantiate the server.
-            isc::data::ConstElementPtr answer =
-                    isc::config::createAnswer(1, "Configuration rejected,"
-                                              " Session has not started.");
-            return (answer);
-        }
-
-        // Let's get the existing configuration.
-        full_config = config_session_->getFullConfig();
-    }
-
-    // The configuration passed to this handler function is partial.
-    // In other words, it just includes the values being modified.
-    // In the same time, there may be dependencies between various
-    // configuration parsers. For example: the option value can
-    // be set if the definition of this option is set. If someone removes
-    // an existing option definition then the partial configuration that
-    // removes that definition is triggered while a relevant option value
-    // may remain configured. This eventually results in the
-    // configuration being in the inconsistent state.
-    // In order to work around this problem we need to merge the new
-    // configuration with the existing (full) configuration.
-
-    // Let's create a new object that will hold the merged configuration.
-    boost::shared_ptr<isc::data::MapElement>
-                            merged_config(new isc::data::MapElement());
-
-    // Merge an existing and new configuration.
-    merged_config->setValue(full_config->mapValue());
-    isc::data::merge(merged_config, new_config);
-
-    // Send the merged configuration to the application.
-    return (process_->configure(merged_config));
+    return (process_->configure(new_config));
 }
 
 
+// Instance method for executing commands
 isc::data::ConstElementPtr
 DControllerBase::executeCommand(const std::string& command,
                             isc::data::ConstElementPtr args) {
@@ -364,7 +250,7 @@ DControllerBase::executeCommand(const std::string& command,
     // as it may be supported there.
     isc::data::ConstElementPtr answer;
     if (command.compare(SHUT_DOWN_COMMAND) == 0) {
-        answer = shutdown(args);
+        answer = shutdownProcess(args);
     } else {
         // It wasn't shutdown, so may be a custom controller command.
         int rcode = 0;
@@ -390,10 +276,10 @@ DControllerBase::customControllerCommand(const std::string& command,
 }
 
 isc::data::ConstElementPtr
-DControllerBase::shutdown(isc::data::ConstElementPtr args) {
+DControllerBase::shutdownProcess(isc::data::ConstElementPtr args) {
     if (process_) {
         return (process_->shutdown(args));
-    } 
+    }
 
     // Not really a failure, but this condition is worth noting. In reality
     // it should be pretty hard to cause this.
@@ -408,11 +294,12 @@ DControllerBase::usage(const std::string & text)
         std::cerr << "Usage error: " << text << std::endl;
     }
 
-    std::cerr << "Usage: " << bin_name_ <<  std::endl;
-    std::cerr << "  -v: verbose output" << std::endl;
-    std::cerr << "  -s: stand-alone mode (don't connect to BIND10)"
-              << std::endl;
+    std::cerr << "Usage: " << bin_name_ <<  std::endl
+              << "  -c <config file name> : mandatory,"
+              <<   " specifies name of configuration file " << std::endl
+              << "  -v: optional, verbose output " << std::endl;
 
+    // add any derivation specific usage
     std::cerr << getUsageText() << std::endl;
 }
 
@@ -420,4 +307,16 @@ DControllerBase::~DControllerBase() {
 }
 
 }; // namespace isc::d2
+
+// Provide an implementation until we figure out a better way to do this.
+void
+dhcp::Daemon::loggerInit(const char* log_name, bool verbose) {
+    setenv("B10_LOCKFILE_DIR_FROM_BUILD", "/tmp", 1);
+    setenv("B10_LOGGER_ROOT", log_name, 0);
+    setenv("B10_LOGGER_SEVERITY", (verbose ? "DEBUG":"INFO"), 0);
+    setenv("B10_LOGGER_DBGLEVEL", "99", 0);
+    setenv("B10_LOGGER_DESTINATION",  "stdout", 0);
+    isc::log::initLogger();
+}
+
 }; // namespace isc

+ 87 - 208
src/bin/d2/d_controller.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -16,11 +16,10 @@
 #define D_CONTROLLER_H
 
 #include <cc/data.h>
-#include <cc/session.h>
-#include <config/ccsession.h>
 #include <d2/d2_asio.h>
 #include <d2/d2_log.h>
 #include <d2/d_process.h>
+#include <dhcpsrv/daemon.h>
 #include <exceptions/exceptions.h>
 #include <log/logger_support.h>
 
@@ -31,10 +30,6 @@
 namespace isc {
 namespace d2 {
 
-/// @brief DControllerBase launch exit status values.  Upon service shutdown
-/// normal or otherwise, the Controller's launch method will return one of
-/// these values.
-
 /// @brief Exception thrown when the command line is invalid.
 class InvalidUsage : public isc::Exception {
 public:
@@ -49,13 +44,6 @@ public:
         isc::Exception(file, line, what) { };
 };
 
-/// @brief Exception thrown when the session start up fails.
-class SessionStartError: public isc::Exception {
-public:
-    SessionStartError (const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) { };
-};
-
 /// @brief Exception thrown when the application process encounters an
 /// operation in its event loop (i.e. run method).
 class ProcessRunError: public isc::Exception {
@@ -64,14 +52,6 @@ public:
         isc::Exception(file, line, what) { };
 };
 
-/// @brief Exception thrown when the session end fails.
-class SessionEndError: public isc::Exception {
-public:
-    SessionEndError (const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) { };
-};
-
-
 /// @brief Exception thrown when the controller encounters an operational error.
 class DControllerBaseError : public isc::Exception {
 public:
@@ -84,47 +64,33 @@ public:
 class DControllerBase;
 typedef boost::shared_ptr<DControllerBase> DControllerBasePtr;
 
-/// @brief Defines a shared pointer to a Session.
-typedef boost::shared_ptr<isc::cc::Session> SessionPtr;
-
-/// @brief Defines a shared pointer to a ModuleCCSession.
-typedef boost::shared_ptr<isc::config::ModuleCCSession> ModuleCCSessionPtr;
-
-
 /// @brief Application Controller
 ///
 /// DControllerBase is an abstract singleton which provides the framework and
 /// services for managing an application process that implements the
-/// DProcessBase interface.  It allows the process to run either in
-/// integrated mode as a BIND10 module or stand-alone. It coordinates command
-/// line argument parsing, process instantiation and initialization, and runtime
-/// control through external command and configuration event handling.
+/// DProcessBase interface.  It runs the process like a stand-alone, command
+/// line driven executable, which must be supplied a configuration file at
+/// startup. It coordinates command line argument parsing, process
+/// instantiation and initialization, and runtime control through external
+/// command and configuration event handling.
 /// It creates the IOService instance which is used for runtime control
 /// events and passes the IOService into the application process at process
-/// creation.  In integrated mode it is responsible for establishing BIND10
-/// session(s) and passes this IOService into the session creation method(s).
-/// It also provides the callback handlers for command and configuration events
-/// received from the external framework (aka BIND10).  For example, when
-/// running in integrated mode and a user alters the configuration with the
-/// bindctl tool, BIND10 will emit a configuration message which is sensed by
-/// the controller's IOService. The IOService in turn invokes the configuration
-/// callback, DControllerBase::configHandler().  If the user issues a command
-/// such as shutdown via bindctl,  BIND10 will emit a command message, which is
-/// sensed by controller's IOService which invokes the command callback,
-/// DControllerBase::commandHandler().
+/// creation.
+/// It provides the callback handlers for command and configuration events
+/// which could be triggered by an external source.  Such sources are intended
+/// to be registed with and monitored by the controller's IOService such that
+/// the appropriate handler can be invoked.
 ///
 /// NOTE: Derivations must supply their own static singleton instance method(s)
 /// for creating and fetching the instance. The base class declares the instance
-/// member in order for it to be available for BIND10 callback functions. This
-/// would not be required if BIND10 supported instance method callbacks.
-class DControllerBase : public boost::noncopyable {
+/// member in order for it to be available for static callback functions.
+class DControllerBase : public dhcp::Daemon {
 public:
     /// @brief Constructor
     ///
     /// @param app_name is display name of the application under control. This
     /// name appears in log statements.
-    /// @param bin_name is the name of the application executable. Typically
-    /// this matches the BIND10 module name.
+    /// @param bin_name is the name of the application executable.
     DControllerBase(const char* app_name, const char* bin_name);
 
     /// @brief Destructor
@@ -135,21 +101,17 @@ public:
     ///
     /// 1. parse command line arguments
     /// 2. instantiate and initialize the application process
-    /// 3. establish BIND10 session(s) if in integrated mode
+    /// 3. load the configuration file
     /// 4. start and wait on the application process event loop
-    /// 5. upon event loop completion, disconnect from BIND10 (if needed)
-    /// 6. exit to the caller
+    /// 5. exit to the caller
     ///
     /// It is intended to be called from main() and be given the command line
-    /// arguments. Note this method is deliberately not virtual to ensure the
-    /// proper sequence of events occur.
+    /// arguments.
     ///
-    /// This function can be run in the test mode. It prevents initialization
+    /// This function can be run in "test mode". It prevents initialization
     /// of D2 module logger. This is used in unit tests which initialize logger
-    /// in their main function. Such logger uses environmental variables to
-    /// control severity, verbosity etc. Reinitialization of logger by this
-    /// function would replace unit tests specific logger configuration with
-    /// this suitable for D2 running as a bind10 module.
+    /// in their main function. Such a logger uses environmental variables to
+    /// control severity, verbosity etc.
     ///
     /// @param argc  is the number of command line arguments supplied
     /// @param argv  is the array of string (char *) command line arguments
@@ -162,77 +124,50 @@ public:
     /// InvalidUsage - Indicates invalid command line.
     /// ProcessInitError  - Failed to create and initialize application
     /// process object.
-    /// SessionStartError  - Could not connect to BIND10 (integrated mode only).
     /// ProcessRunError - A fatal error occurred while in the application
     /// process event loop.
-    /// SessionEndError - Could not disconnect from BIND10 (integrated mode
-    /// only).
-    void launch(int argc, char* argv[], const bool test_mode);
+    virtual void launch(int argc, char* argv[], const bool test_mode);
 
-    /// @brief A dummy configuration handler that always returns success.
-    ///
-    /// This configuration handler does not perform configuration
-    /// parsing and always returns success. A dummy handler should
-    /// be installed using \ref isc::config::ModuleCCSession ctor
-    /// to get the initial configuration. This initial configuration
-    /// comprises values for only those elements that were modified
-    /// the previous session. The D2 configuration parsing can't be
-    /// used to parse the initial configuration because it may need the
-    /// full configuration to satisfy dependencies between the
-    /// various configuration values. Installing the dummy handler
-    /// that guarantees to return success causes initial configuration
-    /// to be stored for the session being created and that it can
-    /// be later accessed with \ref isc::config::ConfigData::getFullConfig.
+    /// @brief Instance method invoked by the configuration event handler and
+    /// which processes the actual configuration update.  Provides behavioral
+    /// path for both integrated and stand-alone modes. The current
+    /// implementation will merge the configuration update into the existing
+    /// configuration and then invoke the application process' configure method.
     ///
-    /// @param new_config new configuration.
+    /// @param  new_config is the new configuration
     ///
-    /// @return success configuration status.
-    static isc::data::ConstElementPtr
-    dummyConfigHandler(isc::data::ConstElementPtr new_config);
+    /// @return returns an Element that contains the results of configuration
+    /// update composed of an integer status value (0 means successful,
+    /// non-zero means failure), and a string explanation of the outcome.
+    virtual isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr
+                                                    new_config);
 
-    /// @brief A callback for handling all incoming configuration updates.
-    ///
-    /// As a pointer to this method is used as a callback in ASIO for
-    /// ModuleCCSession, it has to be static.  It acts as a wrapper around
-    /// the virtual instance method, updateConfig.
+    /// @brief Reconfigures the process from a configuration file
     ///
-    /// @param new_config textual representation of the new configuration
-    ///
-    /// @return status of the config update
-    static isc::data::ConstElementPtr
-    configHandler(isc::data::ConstElementPtr new_config);
-
-    /// @brief A callback for handling all incoming commands.
+    /// By default the file is assumed to be a JSON text file whose contents
+    /// include at least:
     ///
-    /// As a pointer to this method is used as a callback in ASIO for
-    /// ModuleCCSession, it has to be static.  It acts as a wrapper around
-    /// the virtual instance method, executeCommand.
+    /// @code
+    ///  { "<module-name>": {<module-config>} }
     ///
-    /// @param command textual representation of the command
-    /// @param args parameters of the command. It can be NULL pointer if no
-    /// arguments exist for a particular command.
+    ///  where:
+    ///     module-name : is a label which uniquely identifies the
+    ///                   configuration data for this controller's application
     ///
-    /// @return status of the processed command
-    static isc::data::ConstElementPtr
-    commandHandler(const std::string& command, isc::data::ConstElementPtr args);
-
-    /// @brief Instance method invoked by the configuration event handler and
-    /// which processes the actual configuration update.  Provides behavioral
-    /// path for both integrated and stand-alone modes. The current
-    /// implementation will merge the configuration update into the existing
-    /// configuration and then invoke the application process' configure method.
+    ///     module-config: a set of zero or more JSON elements which comprise
+    ///                    the application'ss configuration values
+    /// @endcode
     ///
-    /// @todo This implementation is will evolve as the D2 configuration
-    /// management task is implemented (trac #2957).
+    /// The method extracts the set of configuration elements for the
+    /// module-name which matches the controller's app_name_ and passes that
+    /// set into @c udpateConfig().
     ///
-    /// @param  new_config is the new configuration
+    /// The file may contain an arbitrary number of other modules.
     ///
     /// @return returns an Element that contains the results of configuration
     /// update composed of an integer status value (0 means successful,
     /// non-zero means failure), and a string explanation of the outcome.
-    virtual isc::data::ConstElementPtr
-    updateConfig(isc::data::ConstElementPtr new_config);
-
+    virtual isc::data::ConstElementPtr configFromFile();
 
     /// @brief Instance method invoked by the command event handler and  which
     /// processes the actual command directive.
@@ -262,8 +197,24 @@ public:
     ///   failure.
     ///   D2::COMMAND_INVALID - Command is not recognized as valid be either
     ///   the controller or the application process.
-    virtual isc::data::ConstElementPtr
-    executeCommand(const std::string& command, isc::data::ConstElementPtr args);
+    virtual isc::data::ConstElementPtr executeCommand(const std::string&
+                                                      command,
+                                                      isc::data::
+                                                      ConstElementPtr args);
+
+    /// @brief Fetches the name of the application under control.
+    ///
+    /// @return returns the controller service name string
+    std::string getAppName() const {
+        return (app_name_);
+    }
+
+    /// @brief Fetches the name of the application executable.
+    ///
+    /// @return returns the controller logger name string
+    std::string getBinName() const {
+        return (bin_name_);
+    }
 
 protected:
     /// @brief Virtual method that provides derivations the opportunity to
@@ -309,26 +260,6 @@ protected:
     virtual isc::data::ConstElementPtr customControllerCommand(
             const std::string& command, isc::data::ConstElementPtr args);
 
-    /// @brief Virtual method which is invoked after the controller successfully
-    /// establishes BIND10 connectivity.  It provides an opportunity for the
-    /// derivation to execute any custom behavior associated with session
-    /// establishment.
-    ///
-    /// Note, it is not called  when running stand-alone.
-    ///
-    /// @throw should throw a DControllerBaseError if it fails.
-    virtual void onSessionConnect(){};
-
-    /// @brief Virtual method which is invoked as the first action taken when
-    /// the controller is terminating the session(s) with BIND10.  It provides
-    /// an opportunity for the derivation to execute any custom behavior
-    /// associated with session termination.
-    ///
-    /// Note, it is not called  when running stand-alone.
-    ///
-    /// @throw should throw a DControllerBaseError if it fails.
-    virtual void onSessionDisconnect(){};
-
     /// @brief Virtual method which can be used to contribute derivation
     /// specific usage text.  It is invoked by the usage() method under
     /// invalid usage conditions.
@@ -340,7 +271,7 @@ protected:
 
     /// @brief Virtual method which returns a string containing the option
     /// letters for any custom command line options supported by the derivation.
-    /// These are added to the stock options of "s" and "v" during command
+    /// These are added to the stock options of "c" and "v" during command
     /// line interpretation.
     ///
     /// @return returns a string containing the custom option letters.
@@ -348,34 +279,6 @@ protected:
         return ("");
     }
 
-    /// @brief Fetches the name of the application under control.
-    ///
-    /// @return returns the controller service name string
-    const std::string getAppName() const {
-        return (app_name_);
-    }
-
-    /// @brief Fetches the name of the application executable.
-    ///
-    /// @return returns the controller logger name string
-    const std::string getBinName() const {
-        return (bin_name_);
-    }
-
-    /// @brief Supplies whether or not the controller is in stand alone mode.
-    ///
-    /// @return returns true if in stand alone mode, false otherwise
-    bool isStandAlone() const {
-        return (stand_alone_);
-    }
-
-    /// @brief Method for enabling or disabling stand alone mode.
-    ///
-    /// @param value is the new value to assign the flag.
-    void setStandAlone(bool value) {
-        stand_alone_ = value;
-    }
-
     /// @brief Supplies whether or not verbose logging is enabled.
     ///
     /// @return returns true if verbose logging is enabled.
@@ -397,7 +300,7 @@ protected:
         return (io_service_);
     }
 
-    /// @brief Getter for fetching the name of the controller's BIND10 spec
+    /// @brief Getter for fetching the name of the controller's config spec
     /// file.
     ///
     /// @return returns the file name string.
@@ -405,7 +308,7 @@ protected:
         return (spec_file_name_);
     }
 
-    /// @brief Setter for setting the name of the controller's BIND10 spec file.
+    /// @brief Setter for setting the name of the controller's config spec file.
     ///
     /// @param spec_file_name the file name string.
     void setSpecFileName(const std::string& spec_file_name) {
@@ -428,14 +331,13 @@ protected:
     /// instance a second time.
     static void setController(const DControllerBasePtr& controller);
 
-private:
     /// @brief Processes the command line arguments. It is the first step
     /// taken after the controller has been launched.  It combines the stock
     /// list of options with those returned by getCustomOpts(), and uses
     /// cstdlib's getopt to loop through the command line.  The stock options
     /// It handles stock options directly, and passes any custom options into
     /// the customOption method.  Currently there are only two stock options
-    /// -s for stand alone mode, and -v for verbose logging.
+    /// -c for specifying the configuration file, and -v for verbose logging.
     ///
     /// @param argc  is the number of command line arguments supplied
     /// @param argv  is the array of string (char *) command line arguments
@@ -453,18 +355,6 @@ private:
     /// if there is a failure creating or initializing the application process.
     void initProcess();
 
-    /// @brief Establishes connectivity with BIND10.  This method is used
-    /// invoked during launch, if running in integrated mode, following
-    /// successful process initialization.  It is responsible for establishing
-    /// the BIND10 control and config sessions. During the session creation,
-    /// it passes in the controller's IOService and the callbacks for command
-    /// directives and config events.  Lastly, it will invoke the onConnect
-    /// method providing the derivation an opportunity to execute any custom
-    /// logic associated with session establishment.
-    ///
-    /// @throw the BIND10 framework may throw std::exceptions.
-    void establishSession();
-
     /// @brief Invokes the application process's event loop,(DBaseProcess::run).
     /// It is called during launch only after successfully completing the
     /// requested setup: command line parsing, application initialization,
@@ -476,15 +366,6 @@ private:
     // @throw throws DControllerBaseError or indirectly DProcessBaseError
     void runProcess();
 
-    /// @brief Terminates connectivity with BIND10. This method is invoked
-    /// in integrated mode after the application event loop has exited. It
-    /// first calls the onDisconnect method providing the derivation an
-    /// opportunity to execute custom logic if needed, and then terminates the
-    /// BIND10 config and control sessions.
-    ///
-    /// @throw the BIND10 framework may throw std:exceptions.
-    void disconnectSession();
-
     /// @brief Initiates shutdown procedure.  This method is invoked
     /// by executeCommand in response to the shutdown command. It will invoke
     /// the application process's shutdown method which causes the process to
@@ -495,12 +376,19 @@ private:
     /// until the process has halted.  Rather it is used to convey the
     /// need to shutdown.  A successful return indicates that the shutdown
     /// has successfully commenced, but does not indicate that the process
-    /// has actually exited. 
+    /// has actually exited.
     ///
     /// @return returns an Element that contains the results of shutdown
     /// command composed of an integer status value (0 means successful,
     /// non-zero means failure), and a string explanation of the outcome.
-    isc::data::ConstElementPtr shutdown(isc::data::ConstElementPtr args);
+    isc::data::ConstElementPtr shutdownProcess(isc::data::ConstElementPtr args);
+
+    /// @brief Fetches the current process
+    ///
+    /// @return the a pointer to the current process instance.
+    DProcessBasePtr getProcess() {
+        return (process_);
+    }
 
     /// @brief Prints the program usage text to std error.
     ///
@@ -509,23 +397,20 @@ private:
     void usage(const std::string& text);
 
 private:
-    /// @brief Display name of the service under control. This name
-    /// appears in log statements.
+    /// @brief Name of the service under control.
+    /// This name is used as the configuration module name and appears in log
+    /// statements.
     std::string app_name_;
 
-    /// @brief Name of the service executable. By convention this matches
-    /// the BIND10 module name. It is also used to establish the logger
-    /// name.
+    /// @brief Name of the service executable.
+    /// By convention this matches the executable nam. It is also used to
+    /// establish the logger name.
     std::string bin_name_;
 
-    /// @brief Indicates if the controller stand alone mode is enabled. When
-    /// enabled, the controller will not establish connectivity with BIND10.
-    bool stand_alone_;
-
     /// @brief Indicates if the verbose logging mode is enabled.
     bool verbose_;
 
-    /// @brief The absolute file name of the BIND10 spec file.
+    /// @brief The absolute file name of the JSON spec file.
     std::string spec_file_name_;
 
     /// @brief Pointer to the instance of the process.
@@ -537,12 +422,6 @@ private:
     /// @brief Shared pointer to an IOService object, used for ASIO operations.
     IOServicePtr io_service_;
 
-    /// @brief Helper session object that represents raw connection to msgq.
-    SessionPtr cc_session_;
-
-    /// @brief Session that receives configuration and commands.
-    ModuleCCSessionPtr config_session_;
-
     /// @brief Singleton instance value.
     static DControllerBasePtr controller_;
 

+ 179 - 182
src/bin/d2/images/abstract_app_classes.svg

@@ -1,225 +1,222 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- Created with Bouml (http://bouml.free.fr/) -->
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg width="749" height="595" version="1.1" xmlns="http://www.w3.org/2000/svg">
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="733" y="357" width="3" height="225" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="627" y="579" width="109" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="623" y="353" width="110" height="226" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="678" y="366">DCfgContextBase</text>
-	<line stroke="black" stroke-opacity="1" x1="623" y1="368" x2="733" y2="368" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="627" y="381">OPTIONAL</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="627" y="394">REQUIRED</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="407">boolean_values_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="420">uint32_values_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="433">string_values_</text>
-	<line stroke="black" stroke-opacity="1" x1="623" y1="435" x2="733" y2="435" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="448">DCfgContextBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="461">~DCfgContextBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="474">getParam()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="487">getParam()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="500">getParam()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="513">getBooleanStorage()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="526">getUint32Storage()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="539">getStringStorage()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="627" y="552">clone()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="565">DCfgContextBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="578">operator =()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="179" y="15" width="3" height="511" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="35" y="523" width="147" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="31" y="11" width="148" height="512" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="105" y="24">DControllerBase</text>
-	<line stroke="black" stroke-opacity="1" x1="31" y1="26" x2="179" y2="26" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="39">app_name_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="52">bin_name_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="65">stand_alone_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="78">verbose_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="91">spec_file_name_</text>
-	<line stroke="black" stroke-opacity="1" x1="31" y1="93" x2="179" y2="93" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="106">DControllerBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="119">~DControllerBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="132">launch()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="145">dummyConfigHandler()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="158">configHandler()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="171">commandHandler()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="184">updateConfig()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="197">executeCommand()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="210">customOption()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="35" y="223">createProcess()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="236">customControllerCommand()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="249">onSessionConnect()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="262">onSessionDisconnect()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="275">getUsageText()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="288">getCustomOpts()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="301">getAppName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="314">getBinName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="327">isStandAlone()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="340">setStandAlone()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="353">isVerbose()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="366">setVerbose()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="379">getIOService()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="392">getSpecFileName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="405">setSpecFileName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="418">getController()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="431">setController()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="444">parseArgs()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="457">initProcess()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="470">establishSession()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="483">runProcess()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="496">disconnectSession()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="509">shutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="522">usage()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="420" y="119" width="3" height="213" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="324" y="329" width="99" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="320" y="115" width="100" height="214" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="370" y="128">DProcessBase</text>
-	<line stroke="black" stroke-opacity="1" x1="320" y1="130" x2="420" y2="130" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="143">app_name_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="156">shut_down_flag_</text>
-	<line stroke="black" stroke-opacity="1" x1="320" y1="158" x2="420" y2="158" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="171">DProcessBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="184">init()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="197">run()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="210">shutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="223">configure()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="236">command()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="249">~DProcessBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="262">shouldShutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="275">setShutdownFlag()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="288">getAppName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="301">getIoService()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="314">stopIOService()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="327">getCfgMgr()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="585" y="240" width="3" height="127" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="479" y="364" width="109" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="475" y="236" width="110" height="128" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="530" y="249">DCfgMgrBase</text>
-	<line stroke="black" stroke-opacity="1" x1="475" y1="251" x2="585" y2="251" />
-	<line stroke="black" stroke-opacity="1" x1="475" y1="259" x2="585" y2="259" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="272">DCfgMgrBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="285">~DCfgMgrBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="298">parseConfig()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="311">addToParseOrder()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="324">getParseOrder()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="337">getContext()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="479" y="350">createConfigParser()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="363">buildAndCommit()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="419" y="56" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="323" y="98" width="99" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="319" y="52" width="100" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="369" y="65">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="369" y="80">DProcessBasePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="319" y1="82" x2="419" y2="82" />
-	<line stroke="black" stroke-opacity="1" x1="319" y1="90" x2="419" y2="90" />
+<svg width="770" height="641" version="1.1" xmlns="http://www.w3.org/2000/svg">
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="588" y="279" width="3" height="193" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="474" y="469" width="117" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="470" y="275" width="118" height="194" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="529" y="289">DCfgMgrBase</text>
+	<line stroke="black" stroke-opacity="1" x1="470" y1="291" x2="588" y2="291" />
+	<line stroke="black" stroke-opacity="1" x1="470" y1="299" x2="588" y2="299" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="313">DCfgMgrBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="327">~DCfgMgrBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="341">parseConfig()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="355">addToParseOrder()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="369">getParseOrder()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="383">getContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="397">buildParams()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="474" y="411">createConfigParser()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="474" y="425">createNewContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="439">resetContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="453">setContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="474" y="467">buildAndCommit()</text>
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="754" y="385" width="3" height="243" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="640" y="625" width="117" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="636" y="381" width="118" height="244" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="695" y="395">DCfgContextBase</text>
+	<line stroke="black" stroke-opacity="1" x1="636" y1="397" x2="754" y2="397" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="640" y="411">OPTIONAL</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="640" y="425">REQUIRED</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="439">boolean_values_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="453">uint32_values_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="467">string_values_</text>
+	<line stroke="black" stroke-opacity="1" x1="636" y1="469" x2="754" y2="469" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="483">DCfgContextBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="497">~DCfgContextBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="511">getParam()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="525">getParam()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="539">getParam()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="553">getBooleanStorage()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="567">getUint32Storage()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="581">getStringStorage()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="640" y="595">clone()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="609">DCfgContextBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="640" y="623">operator =()</text>
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="175" y="14" width="3" height="453" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="17" y="464" width="161" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="13" y="10" width="162" height="454" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="94" y="24">DControllerBase</text>
+	<line stroke="black" stroke-opacity="1" x1="13" y1="26" x2="175" y2="26" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="40">app_name_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="54">bin_name_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="68">verbose_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="82">spec_file_name_</text>
+	<line stroke="black" stroke-opacity="1" x1="13" y1="84" x2="175" y2="84" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="98">DControllerBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="112">~DControllerBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="126">launch()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="140">updateConfig()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="154">configFromFile()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="168">executeCommand()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="182">getAppName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="196">getBinName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="210">customOption()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="17" y="224">createProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="238">customControllerCommand()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="252">getUsageText()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="266">getCustomOpts()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="280">isVerbose()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="294">setVerbose()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="308">getIOService()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="322">getSpecFileName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="336">setSpecFileName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="17" y="350">getController()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="17" y="364">setController()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="378">parseArgs()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="392">initProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="406">runProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="420">shutdownProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="434">getConfigFile()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="448">getProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="462">usage()</text>
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="274" y="165" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="198" y="209" width="79" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="194" y="161" width="80" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="234" y="175">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="234" y="191">IOServicePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="194" y1="193" x2="274" y2="193" />
+	<line stroke="black" stroke-opacity="1" x1="194" y1="201" x2="274" y2="201" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="179" y1="118" x2="236" y2="118" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="179,118 185,112 191,118 185,124" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="236" y1="160" x2="242" y2="154" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="160" x2="230" y2="154" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="118" x2="236" y2="160" />
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="426" y="148" width="3" height="229" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="322" y="374" width="107" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="318" y="144" width="108" height="230" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="372" y="158">DProcessBase</text>
+	<line stroke="black" stroke-opacity="1" x1="318" y1="160" x2="426" y2="160" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="174">app_name_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="188">shut_down_flag_</text>
+	<line stroke="black" stroke-opacity="1" x1="318" y1="190" x2="426" y2="190" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="204">DProcessBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="322" y="218">init()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="322" y="232">run()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="322" y="246">shutdown()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="322" y="260">configure()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="322" y="274">command()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="288">~DProcessBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="302">shouldShutdown()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="316">setShutdownFlag()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="330">getAppName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="344">getIoService()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="358">stopIOService()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="322" y="372">getCfgMgr()</text>
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="371" y1="114" x2="377" y2="108" />
-	<line stroke="black" stroke-opacity="1" x1="371" y1="114" x2="365" y2="108" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="371" y1="102" x2="371" y2="114" />
+	<line stroke="black" stroke-opacity="1" x1="317" y1="260" x2="236" y2="260" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="317,260 311,266 305,260 311,254" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="183" y1="34" x2="371" y2="34" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="183,34 189,28 195,34 189,40" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="213" x2="230" y2="219" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="213" x2="242" y2="219" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="260" x2="236" y2="213" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="371" y1="51" x2="377" y2="45" />
-	<line stroke="black" stroke-opacity="1" x1="371" y1="51" x2="365" y2="45" />
-	<line stroke="black" stroke-opacity="1" x1="371" y1="34" x2="371" y2="51" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="424" y="72" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="320" y="116" width="107" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="316" y="68" width="108" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="370" y="82">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="370" y="98">DProcessBasePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="316" y1="100" x2="424" y2="100" />
+	<line stroke="black" stroke-opacity="1" x1="316" y1="108" x2="424" y2="108" />
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="685" y="273">context_</text>
+	<line stroke="black" stroke-opacity="1" x1="372" y1="143" x2="378" y2="137" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="143" x2="366" y2="137" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="372" y1="120" x2="372" y2="143" />
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="381" y="48">process_</text>
+	<line stroke="black" stroke-opacity="1" x1="179" y1="39" x2="372" y2="39" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="179,39 185,33 191,39 185,45" />
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="251" y="174">io_service_</text>
+	<line stroke="black" stroke-opacity="1" x1="372" y1="67" x2="378" y2="61" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="67" x2="366" y2="61" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="39" x2="372" y2="67" />
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="535" y="155">cfg_mgr_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="382" y="63">process_</text>
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="250" y="244">io_service_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="246" y="231">io_service_</text>
 </g>
 <g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="275" y="182" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="205" y="224" width="73" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="201" y="178" width="74" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="238" y="191">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="238" y="206">IOServicePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="201" y1="208" x2="275" y2="208" />
-	<line stroke="black" stroke-opacity="1" x1="201" y1="216" x2="275" y2="216" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="246" y="156">io_service_</text>
 </g>
 <g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="571" y="163" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="479" y="205" width="95" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="475" y="159" width="96" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="523" y="172">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="523" y="187">DCfgMgrBasePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="475" y1="189" x2="571" y2="189" />
-	<line stroke="black" stroke-opacity="1" x1="475" y1="197" x2="571" y2="197" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="696" y="302">context_</text>
 </g>
 <g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="731" y="281" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="619" y="323" width="115" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="615" y="277" width="116" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="673" y="290">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="673" y="305">DCfgContextBasePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="615" y1="307" x2="731" y2="307" />
-	<line stroke="black" stroke-opacity="1" x1="615" y1="315" x2="731" y2="315" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="534" y="196">cfg_mgr_</text>
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="319" y1="282" x2="240" y2="282" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="319,282 313,288 307,282 313,276" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="747" y="311" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="625" y="355" width="125" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="621" y="307" width="126" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="684" y="321">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="684" y="337">DCfgContextBasePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="621" y1="339" x2="747" y2="339" />
+	<line stroke="black" stroke-opacity="1" x1="621" y1="347" x2="747" y2="347" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="183" y1="154" x2="241" y2="154" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="183,154 189,148 195,154 189,160" />
+	<line stroke="black" stroke-opacity="1" x1="688" y1="380" x2="693" y2="373" />
+	<line stroke="black" stroke-opacity="1" x1="688" y1="380" x2="681" y2="374" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="687" y1="359" x2="688" y2="380" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="424" y1="135" x2="525" y2="135" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="424,135 430,129 436,135 430,141" />
+	<line stroke="black" stroke-opacity="1" x1="592" y1="289" x2="686" y2="289" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="592,289 598,283 604,289 598,295" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="525" y1="158" x2="531" y2="152" />
-	<line stroke="black" stroke-opacity="1" x1="525" y1="158" x2="519" y2="152" />
-	<line stroke="black" stroke-opacity="1" x1="525" y1="135" x2="525" y2="158" />
+	<line stroke="black" stroke-opacity="1" x1="686" y1="306" x2="692" y2="300" />
+	<line stroke="black" stroke-opacity="1" x1="686" y1="306" x2="680" y2="300" />
+	<line stroke="black" stroke-opacity="1" x1="686" y1="289" x2="686" y2="306" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="675" y1="352" x2="681" y2="346" />
-	<line stroke="black" stroke-opacity="1" x1="675" y1="352" x2="669" y2="346" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="675" y1="327" x2="675" y2="352" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="574" y="205" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="474" y="249" width="103" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="470" y="201" width="104" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="522" y="215">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="522" y="231">DCfgMgrBasePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="470" y1="233" x2="574" y2="233" />
+	<line stroke="black" stroke-opacity="1" x1="470" y1="241" x2="574" y2="241" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="589" y1="247" x2="675" y2="247" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="589,247 595,241 601,247 595,253" />
+	<line stroke="black" stroke-opacity="1" x1="524" y1="274" x2="530" y2="268" />
+	<line stroke="black" stroke-opacity="1" x1="524" y1="274" x2="518" y2="268" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="524" y1="253" x2="524" y2="274" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="675" y1="276" x2="681" y2="270" />
-	<line stroke="black" stroke-opacity="1" x1="675" y1="276" x2="669" y2="270" />
-	<line stroke="black" stroke-opacity="1" x1="675" y1="247" x2="675" y2="276" />
+	<line stroke="black" stroke-opacity="1" x1="430" y1="168" x2="524" y2="168" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="430,168 436,162 442,168 436,174" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="526" y1="235" x2="531" y2="228" />
-	<line stroke="black" stroke-opacity="1" x1="526" y1="235" x2="519" y2="229" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="525" y1="209" x2="526" y2="235" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="240" y1="228" x2="234" y2="234" />
-	<line stroke="black" stroke-opacity="1" x1="240" y1="228" x2="246" y2="234" />
-	<line stroke="black" stroke-opacity="1" x1="240" y1="282" x2="240" y2="228" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="241" y1="177" x2="247" y2="171" />
-	<line stroke="black" stroke-opacity="1" x1="241" y1="177" x2="235" y2="171" />
-	<line stroke="black" stroke-opacity="1" x1="241" y1="154" x2="241" y2="177" />
+	<line stroke="black" stroke-opacity="1" x1="524" y1="200" x2="530" y2="194" />
+	<line stroke="black" stroke-opacity="1" x1="524" y1="200" x2="518" y2="194" />
+	<line stroke="black" stroke-opacity="1" x1="524" y1="168" x2="524" y2="200" />
 </g>
 </svg>

+ 83 - 0
src/bin/d2/images/config_from_file_sequence.svg

@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Bouml (http://bouml.free.fr/) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="746" height="226" version="1.1" xmlns="http://www.w3.org/2000/svg">
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="261" y="8" width="3" height="18" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="167" y="23" width="97" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="163" y="4" width="98" height="19" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="212" y="20">:DControllerBase</text>
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="488" y="8" width="3" height="18" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="402" y="23" width="89" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="398" y="4" width="90" height="19" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="443" y="20">:DProcessBase</text>
+</g>
+<g>
+	<line stroke="black" stroke-dasharray="18,6"  stroke-opacity="1" x1="214" y1="45" x2="214" y2="226" />
+</g>
+<g>
+	<line stroke="black" stroke-dasharray="18,6"  stroke-opacity="1" x1="445" y1="45" x2="445" y2="226" />
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="730" y="8" width="3" height="18" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="648" y="23" width="85" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="644" y="4" width="86" height="19" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="687" y="20">:DCfgMgrBase</text>
+</g>
+<g>
+	<line stroke="black" stroke-dasharray="18,6"  stroke-opacity="1" x1="689" y1="45" x2="689" y2="226" />
+</g>
+<g>
+	<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="440" y="175" width="10" height="28" />
+</g>
+<g>
+	<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="684" y="180" width="10" height="24" />
+</g>
+<g>
+	<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="209" y="67" width="10" height="147" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="39" y1="72" x2="209" y2="72" />
+	<polygon fill="#000000" stroke="none" points="209,72 205,68 205,76" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="451" y1="194" x2="684" y2="194" />
+	<polygon fill="#000000" stroke="none" points="684,194 680,190 680,198" />
+</g>
+<ellipse fill="black" stroke="none" cx="34.5" cy="73.5" rx="4.5" ry="4.5" />
+<g>
+	<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="215" y="99" width="10" height="24" />
+</g>
+<g>
+	<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="215" y="164" width="10" height="37" />
+</g>
+<g>
+	<path fill="none" stroke="black" stroke-opacity="1" d="M 227 165 L 244 165 L 244 172 L 227 172" />
+	<polygon fill="#000000" stroke="none" points="227,172 231,176 231,168" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="226" y1="187" x2="440" y2="187" />
+	<polygon fill="#000000" stroke="none" points="440,187 436,183 436,191" />
+</g>
+<g>
+	<path fill="none" stroke="black" stroke-opacity="1" d="M 227 100 L 244 100 L 244 107 L 227 107" />
+	<polygon fill="#000000" stroke="none" points="227,107 231,111 231,103" />
+</g>
+<g>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="591" y="191">parseConfig()</text>
+</g>
+<g>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="111" y="67">configFromFile()</text>
+</g>
+<g>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="224" y="95">getConfigFile()</text>
+</g>
+<g>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="372" y="182">configure()</text>
+</g>
+<g>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="231" y="160">updateConfig()</text>
+</g>
+</svg>

+ 0 - 94
src/bin/d2/images/config_sequence.svg

@@ -1,94 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Bouml (http://bouml.free.fr/) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg width="847" height="290" version="1.1" xmlns="http://www.w3.org/2000/svg">
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="674" y="8" width="3" height="16" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="606" y="21" width="71" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="602" y="4" width="72" height="17" />
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="638" y="18">:DCfgMgrBase</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="116" y="8" width="3" height="16" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="28" y="21" width="91" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="24" y="4" width="92" height="17" />
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="70" y="18">:ModuleCCSession</text>
-</g>
-<g>
-	<line stroke="black" stroke-dasharray="18,6"  stroke-opacity="1" x1="72" y1="45" x2="72" y2="290" />
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="469" y="8" width="3" height="16" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="397" y="21" width="75" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="393" y="4" width="76" height="17" />
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="431" y="18">:DProcessBase</text>
-</g>
-<g>
-	<line stroke="black" stroke-dasharray="18,6"  stroke-opacity="1" x1="640" y1="45" x2="640" y2="290" />
-</g>
-<g>
-	<line stroke="black" stroke-dasharray="18,6"  stroke-opacity="1" x1="433" y1="45" x2="433" y2="290" />
-</g>
-<g>
-	<line stroke="black" stroke-dasharray="18,6"  stroke-opacity="1" x1="260" y1="45" x2="260" y2="290" />
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="300" y="8" width="3" height="16" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="221" y="21" width="82" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="217" y="4" width="83" height="17" />
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="259" y="18">:DControllerBase</text>
-</g>
-<g>
-	<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="635" y="153" width="10" height="34" />
-</g>
-<g>
-	<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="255" y="62" width="10" height="125" />
-</g>
-<g>
-	<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="67" y="59" width="10" height="131" />
-</g>
-<g>
-	<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="428" y="144" width="10" height="43" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="439" y1="182" x2="635" y2="182" />
-	<polygon fill="#000000" stroke="none" points="635,182 631,178 631,186" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="78" y1="67" x2="255" y2="67" />
-	<polygon fill="#000000" stroke="none" points="255,67 251,63 251,71" />
-</g>
-<g>
-	<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="73" y="104" width="10" height="25" />
-</g>
-<g>
-	<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="261" y="95" width="10" height="84" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="272" y1="152" x2="428" y2="152" />
-	<polygon fill="#000000" stroke="none" points="428,152 424,148 424,156" />
-</g>
-<g>
-	<path fill="none" stroke="black" stroke-opacity="1" d="M 273 96 L 290 96 L 290 103 L 273 103" />
-	<polygon fill="#000000" stroke="none" points="273,103 277,107 277,99" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="84" y1="116" x2="261" y2="116" />
-	<polygon fill="#000000" stroke="none" points="84,116 88,112 88,120" />
-</g>
-<g>
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="446" y="206">parseConfig(in new_config : isc::data::ElementPtr) : isc::data::ConstElementPtr</text>
-</g>
-<g>
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="277" y="89">updateConfig(in new_config : isc::data::ConstElementPtr) : isc::data::ConstElementPtr</text>
-</g>
-<g>
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="96" y="113">getFullConfig() : ConstElementPtr</text>
-</g>
-<g>
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="281" y="145">configure(in config_set : isc::data::ConstElementPtr) : isc::data::ConstElementPtr</text>
-</g>
-<g>
-	<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="79" y="59">configHandler(in new_config : isc::data::ConstElementPtr) : isc::data::ConstElementPtr</text>
-</g>
-</svg>

+ 293 - 290
src/bin/d2/images/d2_app_classes.svg

@@ -1,342 +1,345 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- Created with Bouml (http://bouml.free.fr/) -->
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg width="755" height="774" version="1.1" xmlns="http://www.w3.org/2000/svg">
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="731" y="569" width="3" height="127" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="645" y="693" width="89" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="641" y="565" width="90" height="128" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="686" y="578">D2CfgContext</text>
-	<line stroke="black" stroke-opacity="1" x1="641" y1="580" x2="731" y2="580" />
-	<line stroke="black" stroke-opacity="1" x1="641" y1="588" x2="731" y2="588" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="601">D2CfgContext()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="614">~D2CfgContext()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="627">clone()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="640">getForwardMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="653">getReverseMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="666">getKeys()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="679">D2CfgContext()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="645" y="692">operator =()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="160" y="11" width="3" height="511" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="16" y="519" width="147" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="12" y="7" width="148" height="512" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="86" y="20">DControllerBase</text>
-	<line stroke="black" stroke-opacity="1" x1="12" y1="22" x2="160" y2="22" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="35">app_name_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="48">bin_name_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="61">stand_alone_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="74">verbose_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="87">spec_file_name_</text>
-	<line stroke="black" stroke-opacity="1" x1="12" y1="89" x2="160" y2="89" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="102">DControllerBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="115">~DControllerBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="128">launch()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="16" y="141">dummyConfigHandler()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="16" y="154">configHandler()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="16" y="167">commandHandler()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="180">updateConfig()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="193">executeCommand()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="206">customOption()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="16" y="219">createProcess()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="232">customControllerCommand()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="245">onSessionConnect()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="258">onSessionDisconnect()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="271">getUsageText()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="284">getCustomOpts()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="297">getAppName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="310">getBinName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="323">isStandAlone()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="336">setStandAlone()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="349">isVerbose()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="362">setVerbose()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="375">getIOService()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="388">getSpecFileName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="401">setSpecFileName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="16" y="414">getController()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="16" y="427">setController()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="440">parseArgs()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="453">initProcess()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="466">establishSession()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="479">runProcess()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="492">disconnectSession()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="505">shutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="16" y="518">usage()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="389" y="120" width="3" height="213" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="293" y="330" width="99" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="289" y="116" width="100" height="214" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="339" y="129">DProcessBase</text>
-	<line stroke="black" stroke-opacity="1" x1="289" y1="131" x2="389" y2="131" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="144">app_name_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="157">shut_down_flag_</text>
-	<line stroke="black" stroke-opacity="1" x1="289" y1="159" x2="389" y2="159" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="172">DProcessBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="293" y="185">init()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="293" y="198">run()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="293" y="211">shutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="293" y="224">configure()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="293" y="237">command()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="250">~DProcessBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="263">shouldShutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="276">setShutdownFlag()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="289">getAppName()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="302">getIoService()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="315">stopIOService()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="293" y="328">getCfgMgr()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="739" y="314" width="3" height="225" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="633" y="536" width="109" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="629" y="310" width="110" height="226" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="684" y="323">DCfgContextBase</text>
-	<line stroke="black" stroke-opacity="1" x1="629" y1="325" x2="739" y2="325" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="633" y="338">OPTIONAL</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="633" y="351">REQUIRED</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="364">boolean_values_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="377">uint32_values_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="390">string_values_</text>
-	<line stroke="black" stroke-opacity="1" x1="629" y1="392" x2="739" y2="392" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="405">DCfgContextBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="418">~DCfgContextBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="431">getParam()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="444">getParam()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="457">getParam()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="470">getBooleanStorage()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="483">getUint32Storage()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="496">getStringStorage()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="633" y="509">clone()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="522">DCfgContextBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="633" y="535">operator =()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="604" y="542" width="3" height="161" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="466" y="700" width="141" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="462" y="538" width="142" height="162" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="533" y="551">D2CfgMgr</text>
-	<line stroke="black" stroke-opacity="1" x1="462" y1="553" x2="604" y2="553" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="466" y="566">IPV4_REV_ZONE_SUFFIX</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="466" y="579">IPV6_REV_ZONE_SUFFIX</text>
-	<line stroke="black" stroke-opacity="1" x1="462" y1="581" x2="604" y2="581" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="466" y="594">D2CfgMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="466" y="607">~D2CfgMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="466" y="620">getD2CfgContext()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="466" y="633">matchForward()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="466" y="646">matchReverse()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="466" y="659">reverseIpAddress()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="466" y="672">reverseV4Address()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="466" y="685">reverseV6Address()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="466" y="698">createConfigParser()</text>
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="687" y1="564" x2="686" y2="545" />
-	<line stroke="black" stroke-opacity="1" x1="686" y1="540" x2="680" y2="546" />
-	<line stroke="black" stroke-opacity="1" x1="686" y1="540" x2="692" y2="545" />
-	<line stroke="black" stroke-opacity="1" x1="680" y1="546" x2="692" y2="545" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="640" y1="607" x2="634" y2="601" />
-	<line stroke="black" stroke-opacity="1" x1="640" y1="607" x2="634" y2="613" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="608" y1="607" x2="640" y2="607" />
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="418" y="470" width="3" height="291" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="260" y="758" width="161" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="256" y="466" width="162" height="292" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="337" y="479">D2Process</text>
-	<line stroke="black" stroke-opacity="1" x1="256" y1="481" x2="418" y2="481" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="260" y="494">QUEUE_RESTART_PERCENT</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="507">reconf_queue_flag_</text>
-	<line stroke="black" stroke-opacity="1" x1="256" y1="509" x2="418" y2="509" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="522">D2Process()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="535">init()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="548">run()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="561">shutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="574">configure()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="587">command()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="600">~D2Process()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="613">checkQueueStatus()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="626">reconfigureQueueMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="639">runIO()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="652">canShutdown()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="665">setReconfQueueFlag()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="678">setShutdownType()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="691">getD2CfgMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="704">getD2QueueMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="717">getD2UpdateMgr()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="730">getReconfQueueFlag()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="260" y="743">getShutdownType()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="260" y="756">getShutdownTypeStr()</text>
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="590" y="219" width="3" height="127" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="484" y="343" width="109" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="480" y="215" width="110" height="128" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="535" y="228">DCfgMgrBase</text>
-	<line stroke="black" stroke-opacity="1" x1="480" y1="230" x2="590" y2="230" />
-	<line stroke="black" stroke-opacity="1" x1="480" y1="238" x2="590" y2="238" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="484" y="251">DCfgMgrBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="484" y="264">~DCfgMgrBase()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="484" y="277">parseConfig()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="484" y="290">addToParseOrder()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="484" y="303">getParseOrder()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="484" y="316">getContext()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="484" y="329">createConfigParser()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="484" y="342">buildAndCommit()</text>
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="535" y1="537" x2="535" y2="352" />
-	<line stroke="black" stroke-opacity="1" x1="536" y1="347" x2="529" y2="352" />
-	<line stroke="black" stroke-opacity="1" x1="536" y1="347" x2="541" y2="353" />
-	<line stroke="black" stroke-opacity="1" x1="529" y1="352" x2="541" y2="353" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="339" y1="465" x2="339" y2="339" />
-	<line stroke="black" stroke-opacity="1" x1="340" y1="334" x2="333" y2="339" />
-	<line stroke="black" stroke-opacity="1" x1="340" y1="334" x2="345" y2="340" />
-	<line stroke="black" stroke-opacity="1" x1="333" y1="339" x2="345" y2="340" />
-</g>
-<g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="393" y="53" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="297" y="95" width="99" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="293" y="49" width="100" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="343" y="62">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="343" y="77">DProcessBasePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="293" y1="79" x2="393" y2="79" />
-	<line stroke="black" stroke-opacity="1" x1="293" y1="87" x2="393" y2="87" />
-</g>
-<g>
-	<line stroke="black" stroke-opacity="1" x1="461" y1="607" x2="455" y2="601" />
-	<line stroke="black" stroke-opacity="1" x1="461" y1="607" x2="455" y2="613" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="422" y1="607" x2="461" y2="607" />
-</g>
+<svg width="812" height="795" version="1.1" xmlns="http://www.w3.org/2000/svg">
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="175" y="14" width="3" height="453" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="17" y="464" width="161" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="13" y="10" width="162" height="454" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="94" y="24">DControllerBase</text>
+	<line stroke="black" stroke-opacity="1" x1="13" y1="26" x2="175" y2="26" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="40">app_name_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="54">bin_name_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="68">verbose_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="82">spec_file_name_</text>
+	<line stroke="black" stroke-opacity="1" x1="13" y1="84" x2="175" y2="84" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="98">DControllerBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="112">~DControllerBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="126">launch()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="140">updateConfig()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="154">configFromFile()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="168">executeCommand()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="182">getAppName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="196">getBinName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="210">customOption()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="17" y="224">createProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="238">customControllerCommand()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="252">getUsageText()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="266">getCustomOpts()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="280">isVerbose()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="294">setVerbose()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="308">getIOService()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="322">getSpecFileName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="336">setSpecFileName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="17" y="350">getController()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="17" y="364">setController()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="378">parseArgs()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="392">initProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="406">runProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="420">shutdownProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="434">getConfigFile()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="448">getProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="17" y="462">usage()</text>
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="629" y="261" width="3" height="193" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="515" y="451" width="117" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="511" y="257" width="118" height="194" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="570" y="271">DCfgMgrBase</text>
+	<line stroke="black" stroke-opacity="1" x1="511" y1="273" x2="629" y2="273" />
+	<line stroke="black" stroke-opacity="1" x1="511" y1="281" x2="629" y2="281" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="295">DCfgMgrBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="309">~DCfgMgrBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="323">parseConfig()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="337">addToParseOrder()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="351">getParseOrder()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="365">getContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="379">buildParams()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="515" y="393">createConfigParser()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="515" y="407">createNewContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="421">resetContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="435">setContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="515" y="449">buildAndCommit()</text>
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="796" y="361" width="3" height="243" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="682" y="601" width="117" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="678" y="357" width="118" height="244" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="737" y="371">DCfgContextBase</text>
+	<line stroke="black" stroke-opacity="1" x1="678" y1="373" x2="796" y2="373" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="682" y="387">OPTIONAL</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="682" y="401">REQUIRED</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="415">boolean_values_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="429">uint32_values_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="443">string_values_</text>
+	<line stroke="black" stroke-opacity="1" x1="678" y1="445" x2="796" y2="445" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="459">DCfgContextBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="473">~DCfgContextBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="487">getParam()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="501">getParam()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="515">getParam()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="529">getBooleanStorage()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="543">getUint32Storage()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="557">getStringStorage()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="682" y="571">clone()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="585">DCfgContextBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="682" y="599">operator =()</text>
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="134" y="554" width="3" height="103" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="46" y="654" width="91" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="42" y="550" width="92" height="104" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="88" y="564">D2Controller</text>
+	<line stroke="black" stroke-opacity="1" x1="42" y1="566" x2="134" y2="566" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="46" y="580">d2_app_name_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="46" y="594">d2_bin_name_</text>
+	<line stroke="black" stroke-opacity="1" x1="42" y1="596" x2="134" y2="596" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="46" y="610">instance()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="46" y="624">~D2Controller()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="46" y="638">createProcess()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="46" y="652">D2Controller()</text>
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="90" y1="549" x2="90" y2="473" />
+	<line stroke="black" stroke-opacity="1" x1="91" y1="468" x2="84" y2="473" />
+	<line stroke="black" stroke-opacity="1" x1="91" y1="468" x2="96" y2="474" />
+	<line stroke="black" stroke-opacity="1" x1="84" y1="473" x2="96" y2="474" />
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="274" y="165" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="198" y="209" width="79" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="194" y="161" width="80" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="234" y="175">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="234" y="191">IOServicePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="194" y1="193" x2="274" y2="193" />
+	<line stroke="black" stroke-opacity="1" x1="194" y1="201" x2="274" y2="201" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="179" y1="118" x2="236" y2="118" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="179,118 185,112 191,118 185,124" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="236" y1="160" x2="242" y2="154" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="160" x2="230" y2="154" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="118" x2="236" y2="160" />
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="424" y="153" width="3" height="229" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="320" y="379" width="107" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="316" y="149" width="108" height="230" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="370" y="163">DProcessBase</text>
+	<line stroke="black" stroke-opacity="1" x1="316" y1="165" x2="424" y2="165" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="179">app_name_</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="193">shut_down_flag_</text>
+	<line stroke="black" stroke-opacity="1" x1="316" y1="195" x2="424" y2="195" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="209">DProcessBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="320" y="223">init()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="320" y="237">run()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="320" y="251">shutdown()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="320" y="265">configure()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-style="italic" x="320" y="279">command()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="293">~DProcessBase()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="307">shouldShutdown()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="321">setShutdownFlag()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="335">getAppName()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="349">getIoService()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="363">stopIOService()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="320" y="377">getCfgMgr()</text>
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="315" y1="265" x2="236" y2="265" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="315,265 309,271 303,265 309,259" />
+</g>
+<g>
+	<line stroke="black" stroke-opacity="1" x1="236" y1="213" x2="230" y2="219" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="213" x2="242" y2="219" />
+	<line stroke="black" stroke-opacity="1" x1="236" y1="265" x2="236" y2="213" />
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="424" y="72" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="320" y="116" width="107" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="316" y="68" width="108" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="370" y="82">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="370" y="98">DProcessBasePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="316" y1="100" x2="424" y2="100" />
+	<line stroke="black" stroke-opacity="1" x1="316" y1="108" x2="424" y2="108" />
+</g>
+<g>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="448" y="468" width="3" height="313" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="276" y="778" width="175" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="272" y="464" width="176" height="314" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="360" y="478">D2Process</text>
+	<line stroke="black" stroke-opacity="1" x1="272" y1="480" x2="448" y2="480" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="276" y="494">QUEUE_RESTART_PERCENT</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="508">reconf_queue_flag_</text>
+	<line stroke="black" stroke-opacity="1" x1="272" y1="510" x2="448" y2="510" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="524">D2Process()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="538">init()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="552">run()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="566">shutdown()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="580">configure()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="594">command()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="608">~D2Process()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="622">checkQueueStatus()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="636">reconfigureQueueMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="650">runIO()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="664">canShutdown()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="678">setReconfQueueFlag()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="692">setShutdownType()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="706">getD2CfgMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="720">getD2QueueMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="734">getD2UpdateMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="748">getReconfQueueFlag()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="276" y="762">getShutdownType()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="276" y="776">getShutdownTypeStr()</text>
+</g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="343" y1="115" x2="349" y2="109" />
-	<line stroke="black" stroke-opacity="1" x1="343" y1="115" x2="337" y2="108" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="344" y1="99" x2="343" y2="115" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="148" x2="378" y2="142" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="148" x2="366" y2="142" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="372" y1="120" x2="372" y2="148" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="164" y1="30" x2="344" y2="30" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="164,30 170,24 176,30 170,36" />
+	<line stroke="black" stroke-opacity="1" x1="179" y1="39" x2="372" y2="39" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="179,39 185,33 191,39 185,45" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="344" y1="48" x2="350" y2="42" />
-	<line stroke="black" stroke-opacity="1" x1="344" y1="48" x2="338" y2="42" />
-	<line stroke="black" stroke-opacity="1" x1="344" y1="30" x2="344" y2="48" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="67" x2="378" y2="61" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="67" x2="366" y2="61" />
+	<line stroke="black" stroke-opacity="1" x1="372" y1="39" x2="372" y2="67" />
 </g>
 <g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="128" y="566" width="3" height="95" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="46" y="658" width="85" height="3" />
-	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="42" y="562" width="86" height="96" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="85" y="575">D2Controller</text>
-	<line stroke="black" stroke-opacity="1" x1="42" y1="577" x2="128" y2="577" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="46" y="590">d2_app_name_</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="46" y="603">d2_bin_name_</text>
-	<line stroke="black" stroke-opacity="1" x1="42" y1="605" x2="128" y2="605" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="46" y="618">instance()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="46" y="631">~D2Controller()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="46" y="644">createProcess()</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="46" y="657">D2Controller()</text>
+	<line stroke="black" stroke-opacity="1" x1="366" y1="463" x2="367" y2="388" />
+	<line stroke="black" stroke-opacity="1" x1="368" y1="383" x2="361" y2="388" />
+	<line stroke="black" stroke-opacity="1" x1="368" y1="383" x2="373" y2="389" />
+	<line stroke="black" stroke-opacity="1" x1="361" y1="388" x2="373" y2="389" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="87" y1="561" x2="87" y2="529" />
-	<line stroke="black" stroke-opacity="1" x1="87" y1="523" x2="81" y2="529" />
-	<line stroke="black" stroke-opacity="1" x1="87" y1="523" x2="93" y2="529" />
-	<line stroke="black" stroke-opacity="1" x1="81" y1="529" x2="93" y2="529" />
+	<line stroke="black" stroke-opacity="1" x1="271" y1="607" x2="265" y2="600" />
+	<line stroke="black" stroke-opacity="1" x1="271" y1="607" x2="264" y2="612" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="138" y1="606" x2="271" y2="607" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="255" y1="610" x2="249" y2="604" />
-	<line stroke="black" stroke-opacity="1" x1="255" y1="610" x2="249" y2="616" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="132" y1="610" x2="255" y2="610" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="649" y="539" width="3" height="243" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="499" y="779" width="153" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="495" y="535" width="154" height="244" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="572" y="549">D2CfgMgr</text>
+	<line stroke="black" stroke-opacity="1" x1="495" y1="551" x2="649" y2="551" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="499" y="565">IPV4_REV_ZONE_SUFFIX</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="499" y="579">IPV6_REV_ZONE_SUFFIX</text>
+	<line stroke="black" stroke-opacity="1" x1="495" y1="581" x2="649" y2="581" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="595">D2CfgMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="609">~D2CfgMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="623">getD2CfgContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="637">forwardUpdatesEnabled()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="651">reverseUpdatesEnabled()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="665">matchForward()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="679">matchReverse()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="499" y="693">reverseIpAddress()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="499" y="707">reverseV4Address()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" x="499" y="721">reverseV6Address()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="735">getD2Params()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="749">buildParams()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="763">createConfigParser()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="499" y="777">createNewContext()</text>
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="225" y="169">io_service_</text>
+	<line stroke="black" stroke-opacity="1" x1="573" y1="534" x2="572" y2="460" />
+	<line stroke="black" stroke-opacity="1" x1="572" y1="455" x2="566" y2="461" />
+	<line stroke="black" stroke-opacity="1" x1="572" y1="455" x2="578" y2="460" />
+	<line stroke="black" stroke-opacity="1" x1="566" y1="461" x2="578" y2="460" />
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="540" y="148">cfg_mgr_</text>
+	<line stroke="black" stroke-opacity="1" x1="494" y1="636" x2="487" y2="630" />
+	<line stroke="black" stroke-opacity="1" x1="494" y1="636" x2="488" y2="642" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="452" y1="637" x2="494" y2="636" />
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="355" y="45">process_</text>
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="788" y="629" width="3" height="151" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="694" y="777" width="97" height="3" />
+	<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="690" y="625" width="98" height="152" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="739" y="639">D2CfgContext</text>
+	<line stroke="black" stroke-opacity="1" x1="690" y1="641" x2="788" y2="641" />
+	<line stroke="black" stroke-opacity="1" x1="690" y1="649" x2="788" y2="649" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="663">D2CfgContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="677">~D2CfgContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="691">clone()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="705">getD2Params()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="719">getForwardMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="733">getReverseMgr()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="747">getKeys()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="761">D2CfgContext()</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="694" y="775">operator =()</text>
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="690" y="242">context_</text>
+	<line stroke="black" stroke-opacity="1" x1="740" y1="624" x2="739" y2="610" />
+	<line stroke="black" stroke-opacity="1" x1="739" y1="605" x2="733" y2="611" />
+	<line stroke="black" stroke-opacity="1" x1="739" y1="605" x2="745" y2="610" />
+	<line stroke="black" stroke-opacity="1" x1="733" y1="611" x2="745" y2="610" />
 </g>
 <g>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="225" y="239">io_service_</text>
+	<line stroke="black" stroke-opacity="1" x1="689" y1="678" x2="682" y2="672" />
+	<line stroke="black" stroke-opacity="1" x1="689" y1="678" x2="683" y2="684" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="653" y1="679" x2="689" y2="678" />
 </g>
 <g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="251" y="177" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="181" y="219" width="73" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="177" y="173" width="74" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="214" y="186">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="214" y="201">IOServicePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="177" y1="203" x2="251" y2="203" />
-	<line stroke="black" stroke-opacity="1" x1="177" y1="211" x2="251" y2="211" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="246" y="231">io_service_</text>
 </g>
 <g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="577" y="156" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="485" y="198" width="95" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="481" y="152" width="96" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="529" y="165">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="529" y="180">DCfgMgrBasePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="481" y1="182" x2="577" y2="182" />
-	<line stroke="black" stroke-opacity="1" x1="481" y1="190" x2="577" y2="190" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="382" y="63">process_</text>
 </g>
 <g>
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="737" y="250" width="3" height="45" />
-	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="625" y="292" width="115" height="3" />
-	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="621" y="246" width="116" height="46" />
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="679" y="259">&lt;&lt;typedef&gt;&gt;</text>
-	<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="679" y="274">DCfgContextBasePtr</text>
-	<line stroke="black" stroke-opacity="1" x1="621" y1="276" x2="737" y2="276" />
-	<line stroke="black" stroke-opacity="1" x1="621" y1="284" x2="737" y2="284" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="246" y="156">io_service_</text>
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="164" y1="139" x2="215" y2="139" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="164,139 170,133 176,139 170,145" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="736" y="285">context_</text>
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="288" y1="281" x2="215" y2="281" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="288,281 282,287 276,281 282,275" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="572" y="183">cfg_mgr_</text>
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="393" y1="136" x2="530" y2="136" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="393,136 399,130 405,136 399,142" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="788" y="294" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="666" y="338" width="125" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="662" y="290" width="126" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="725" y="304">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="725" y="320">DCfgContextBasePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="662" y1="322" x2="788" y2="322" />
+	<line stroke="black" stroke-opacity="1" x1="662" y1="330" x2="788" y2="330" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="530" y1="151" x2="536" y2="145" />
-	<line stroke="black" stroke-opacity="1" x1="530" y1="151" x2="524" y2="145" />
-	<line stroke="black" stroke-opacity="1" x1="530" y1="136" x2="530" y2="151" />
+	<line stroke="black" stroke-opacity="1" x1="728" y1="356" x2="734" y2="350" />
+	<line stroke="black" stroke-opacity="1" x1="728" y1="356" x2="722" y2="350" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="728" y1="342" x2="728" y2="356" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="531" y1="214" x2="537" y2="208" />
-	<line stroke="black" stroke-opacity="1" x1="531" y1="214" x2="525" y2="208" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="531" y1="202" x2="531" y2="214" />
+	<line stroke="black" stroke-opacity="1" x1="633" y1="271" x2="726" y2="271" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="633,271 639,265 645,271 639,277" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="681" y1="309" x2="687" y2="303" />
-	<line stroke="black" stroke-opacity="1" x1="681" y1="309" x2="675" y2="303" />
-	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="681" y1="296" x2="681" y2="309" />
+	<line stroke="black" stroke-opacity="1" x1="726" y1="289" x2="732" y2="283" />
+	<line stroke="black" stroke-opacity="1" x1="726" y1="289" x2="720" y2="283" />
+	<line stroke="black" stroke-opacity="1" x1="726" y1="271" x2="726" y2="289" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="594" y1="226" x2="680" y2="226" />
-	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="594,226 600,220 606,226 600,232" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="612" y="192" width="3" height="47" />
+	<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="512" y="236" width="103" height="3" />
+	<rect fill="#c0ffff" stroke="black" stroke-width="1" stroke-opacity="1" x="508" y="188" width="104" height="48" />
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-anchor="middle" x="560" y="202">&lt;&lt;typedef&gt;&gt;</text>
+	<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="560" y="218">DCfgMgrBasePtr</text>
+	<line stroke="black" stroke-opacity="1" x1="508" y1="220" x2="612" y2="220" />
+	<line stroke="black" stroke-opacity="1" x1="508" y1="228" x2="612" y2="228" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="680" y1="245" x2="686" y2="239" />
-	<line stroke="black" stroke-opacity="1" x1="680" y1="245" x2="674" y2="239" />
-	<line stroke="black" stroke-opacity="1" x1="680" y1="226" x2="680" y2="245" />
+	<line stroke="black" stroke-opacity="1" x1="564" y1="256" x2="569" y2="249" />
+	<line stroke="black" stroke-opacity="1" x1="564" y1="256" x2="557" y2="250" />
+	<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="563" y1="240" x2="564" y2="256" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="215" y1="223" x2="209" y2="229" />
-	<line stroke="black" stroke-opacity="1" x1="215" y1="223" x2="221" y2="229" />
-	<line stroke="black" stroke-opacity="1" x1="215" y1="281" x2="215" y2="223" />
+	<line stroke="black" stroke-opacity="1" x1="428" y1="173" x2="562" y2="173" />
+	<polygon fill="#000000" stroke="black" stroke-opacity="1" points="428,173 434,167 440,173 434,179" />
 </g>
 <g>
-	<line stroke="black" stroke-opacity="1" x1="215" y1="172" x2="221" y2="166" />
-	<line stroke="black" stroke-opacity="1" x1="215" y1="172" x2="209" y2="166" />
-	<line stroke="black" stroke-opacity="1" x1="215" y1="139" x2="215" y2="172" />
+	<line stroke="black" stroke-opacity="1" x1="562" y1="187" x2="568" y2="181" />
+	<line stroke="black" stroke-opacity="1" x1="562" y1="187" x2="556" y2="181" />
+	<line stroke="black" stroke-opacity="1" x1="562" y1="173" x2="562" y2="187" />
 </g>
 </svg>

+ 13 - 5
src/bin/d2/tests/Makefile.am

@@ -54,10 +54,9 @@ TESTS += d2_unittests
 d2_unittests_SOURCES = ../d2_asio.h
 d2_unittests_SOURCES += ../d2_log.h ../d2_log.cc
 d2_unittests_SOURCES += ../d_process.h
-d2_unittests_SOURCES += ../d_controller.cc ../d2_controller.h
-d2_unittests_SOURCES += ../d2_process.cc ../d2_process.h
-d2_unittests_SOURCES += ../d2_controller.cc ../d2_controller.h
+d2_unittests_SOURCES += ../d_controller.cc ../d_controller.h
 d2_unittests_SOURCES += ../d_cfg_mgr.cc ../d_cfg_mgr.h
+d2_unittests_SOURCES += ../d2_process.cc ../d2_process.h
 d2_unittests_SOURCES += ../d2_config.cc ../d2_config.h
 d2_unittests_SOURCES += ../d2_cfg_mgr.cc ../d2_cfg_mgr.h
 d2_unittests_SOURCES += ../d2_queue_mgr.cc ../d2_queue_mgr.h
@@ -73,8 +72,6 @@ d2_unittests_SOURCES += ../state_model.cc ../state_model.h
 d2_unittests_SOURCES += d_test_stubs.cc d_test_stubs.h
 d2_unittests_SOURCES += d2_unittests.cc
 d2_unittests_SOURCES += d2_process_unittests.cc
-d2_unittests_SOURCES += d_controller_unittests.cc
-d2_unittests_SOURCES += d2_controller_unittests.cc
 d2_unittests_SOURCES += d_cfg_mgr_unittests.cc
 d2_unittests_SOURCES += d2_cfg_mgr_unittests.cc
 d2_unittests_SOURCES += d2_queue_mgr_unittests.cc
@@ -90,6 +87,17 @@ d2_unittests_SOURCES += nc_trans_unittests.cc
 d2_unittests_SOURCES += state_model_unittests.cc
 nodist_d2_unittests_SOURCES = ../d2_messages.h ../d2_messages.cc
 
+if CONFIG_BACKEND_BUNDY
+d2_unittests_SOURCES += ../bundy_d2_controller.cc ../bundy_d2_controller.h
+d2_unittests_SOURCES += bundy_d2_controller_unittests.cc
+else
+if CONFIG_BACKEND_JSON
+d2_unittests_SOURCES += ../d2_controller.cc ../d2_controller.h
+d2_unittests_SOURCES += d2_controller_unittests.cc
+d2_unittests_SOURCES += d_controller_unittests.cc
+endif
+endif
+
 d2_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 d2_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 d2_unittests_LDADD = $(GTEST_LDADD)

+ 191 - 0
src/bin/d2/tests/bundy_d2_controller_unittests.cc

@@ -0,0 +1,191 @@
+// Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config/ccsession.h>
+#include <d_test_stubs.h>
+#include <d2/bundy_d2_controller.h>
+#include <d2/spec_config.h>
+
+#include <boost/pointer_cast.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <gtest/gtest.h>
+
+#include <config.h>
+#include <sstream>
+
+using namespace boost::posix_time;
+
+namespace isc {
+namespace d2 {
+
+/// @brief Test fixture class for testing D2Controller class. This class
+/// derives from DControllerTest and wraps a D2Controller.  Much of the
+/// underlying functionality is in the DControllerBase class which has an
+/// extensive set of unit tests that are independent of DHCP-DDNS.
+/// @TODO Currently These tests are relatively light and duplicate some of
+/// the testing done on the base class.  These tests are sufficient to ensure
+/// that D2Controller properly derives from its base class and to test the
+/// logic that is unique to D2Controller. These tests will be augmented and
+/// or new tests added as additional functionality evolves.
+/// Unlike the stub testing, there is no use of SimFailure to induce error
+/// conditions as this is production code.
+class BundyD2ControllerTest : public DControllerTest {
+public:
+    /// @brief Constructor
+    /// Note the constructor passes in the static D2Controller instance
+    /// method.
+    BundyD2ControllerTest() : DControllerTest(D2Controller::instance) {
+    }
+
+    /// @brief Destructor
+    ~BundyD2ControllerTest() {
+    }
+};
+
+/// @brief Basic Controller instantiation testing.
+/// Verifies that the controller singleton gets created and that the
+/// basic derivation from the base class is intact.
+TEST_F(BundyD2ControllerTest, basicInstanceTesting) {
+    // Verify the we can the singleton instance can be fetched and that
+    // it is the correct type.
+    DControllerBasePtr& controller = DControllerTest::getController();
+    ASSERT_TRUE(controller);
+    ASSERT_NO_THROW(boost::dynamic_pointer_cast<D2Controller>(controller));
+
+    // Verify that controller's app name is correct.
+    EXPECT_TRUE(checkAppName(D2Controller::d2_app_name_));
+
+    // Verify that controller's bin name is correct.
+    EXPECT_TRUE(checkBinName(D2Controller::d2_bin_name_));
+
+    // Verify that controller's spec file name is correct.
+    EXPECT_TRUE(checkSpecFileName(D2_SPECFILE_LOCATION));
+
+    // Verify that controller's IOService exists.
+    EXPECT_TRUE(checkIOService());
+
+    // Verify that the Process does NOT exist.
+    EXPECT_FALSE(checkProcess());
+}
+
+/// @brief Tests basic command line processing.
+/// Verifies that:
+/// 1. Standard command line options are supported.
+/// 2. Invalid options are detected.
+TEST_F(BundyD2ControllerTest, commandLineArgs) {
+    char* argv[] = { const_cast<char*>("progName"),
+                     const_cast<char*>("-v") };
+    int argc = 2;
+
+    // Verify that verbose flag is false initially.
+    EXPECT_TRUE(checkVerbose(false));
+
+    // Verify that standard options can be parsed without error.
+    EXPECT_NO_THROW(parseArgs(argc, argv));
+
+    // Verify that verbose flag is now true.
+    EXPECT_TRUE(checkVerbose(true));
+
+    // Verify that an unknown option is detected.
+    char* argv2[] = { const_cast<char*>("progName"),
+                      const_cast<char*>("-x") };
+    argc = 2;
+    EXPECT_THROW(parseArgs(argc, argv2), InvalidUsage);
+}
+
+/// @brief Tests application process creation and initialization.
+/// Verifies that the process can be successfully created and initialized.
+TEST_F(BundyD2ControllerTest, initProcessTesting) {
+    ASSERT_NO_THROW(initProcess());
+    EXPECT_TRUE(checkProcess());
+}
+
+/// @brief Configuration update event testing.
+/// This really tests just the ability of the handlers to invoke the necessary
+/// chain of methods and handle error conditions. Configuration parsing and
+/// retrieval should be tested as part of the d2 configuration management
+/// implementation.  Note that this testing calls the configuration update event
+/// callback, configHandler, directly.
+/// This test verifies that:
+/// 1. Configuration will be rejected in integrated mode when there is no
+/// session established. (This is a very contrived situation).
+/// 2. In stand-alone mode a configuration update results in successful
+/// status return.
+/// 3. That an application process error in configuration updating is handled
+/// properly.
+TEST_F(BundyD2ControllerTest, configUpdateTests) {
+    int rcode = -1;
+    isc::data::ConstElementPtr answer;
+
+    // Initialize the application process.
+    ASSERT_NO_THROW(initProcess());
+    EXPECT_TRUE(checkProcess());
+
+    // Create a configuration set using a small, valid D2 configuration.
+    isc::data::ElementPtr config_set =
+                                isc::data::Element::fromJSON(valid_d2_config);
+
+    // Configuration should be rejected as there is no session.  This is a 
+    // pretty contrived situation that shouldn't be possible other than the 
+    // handler being called directly (like this does).
+    answer = DControllerBase::configHandler(config_set);
+    isc::config::parseAnswer(rcode, answer);
+    EXPECT_EQ(1, rcode);
+}
+
+/// @brief Command execution tests.
+/// This really tests just the ability of the handler to invoke the necessary
+/// chain of methods and to handle error conditions. Note that this testing
+/// calls the command callback, commandHandler, directly.
+/// This test verifies that:
+/// 1. That an unrecognized command is detected and returns a status of
+/// d2::COMMAND_INVALID.
+/// 2. Shutdown command is recognized and returns a d2::COMMAND_SUCCESS status.
+TEST_F(BundyD2ControllerTest, executeCommandTests) {
+    int rcode = -1;
+    isc::data::ConstElementPtr answer;
+    isc::data::ElementPtr arg_set;
+
+    // Initialize the application process.
+    ASSERT_NO_THROW(initProcess());
+    EXPECT_TRUE(checkProcess());
+
+    // Verify that an unknown command returns an COMMAND_INVALID response.
+    std::string bogus_command("bogus");
+    answer = DControllerBase::commandHandler(bogus_command, arg_set);
+    isc::config::parseAnswer(rcode, answer);
+    EXPECT_EQ(COMMAND_INVALID, rcode);
+
+    // Verify that shutdown command returns COMMAND_SUCCESS response.
+    //answer = executeCommand(SHUT_DOWN_COMMAND, isc::data::ElementPtr());
+    answer = DControllerBase::commandHandler(SHUT_DOWN_COMMAND, arg_set);
+    isc::config::parseAnswer(rcode, answer);
+    EXPECT_EQ(COMMAND_SUCCESS, rcode);
+}
+
+/// @brief Tests launch with a session establishment failure.
+/// This test launches with a valid command line for integrated mode and no.
+/// Attempting to connect to BIND10 should fail, even if BIND10 is running
+/// UNLESS the test is run as root.  Launch should throw SessionStartError.
+TEST_F(BundyD2ControllerTest, launchSessionFailure) {
+    // Command line to run integrated
+    char* argv[] = { (char*)"progName" };
+    int argc = 1;
+
+    // Launch the controller in integrated mode.
+    EXPECT_THROW(launch(argc, argv), SessionStartError);
+}
+
+}; // end of isc::d2 namespace
+}; // end of isc namespace

+ 24 - 31
src/bin/d2/tests/d2_controller_unittests.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -85,21 +85,23 @@ TEST_F(D2ControllerTest, basicInstanceTesting) {
 /// 2. Invalid options are detected.
 TEST_F(D2ControllerTest, commandLineArgs) {
     char* argv[] = { const_cast<char*>("progName"),
-                     const_cast<char*>("-s"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>(DControllerTest::CFG_TEST_FILE),
                      const_cast<char*>("-v") };
-    int argc = 3;
+    int argc = 4;
 
-    // Verify that both flags are false initially.
-    EXPECT_TRUE(checkStandAlone(false));
+    // Verify that verbose flag is false initially.
     EXPECT_TRUE(checkVerbose(false));
 
     // Verify that standard options can be parsed without error.
     EXPECT_NO_THROW(parseArgs(argc, argv));
 
-    // Verify that flags are now true.
-    EXPECT_TRUE(checkStandAlone(true));
+    // Verify that verbose flag is true.
     EXPECT_TRUE(checkVerbose(true));
 
+    // Verify configuration file name is correct.
+    EXPECT_TRUE(checkConfigFileName(DControllerTest::CFG_TEST_FILE));
+
     // Verify that an unknown option is detected.
     char* argv2[] = { const_cast<char*>("progName"),
                       const_cast<char*>("-x") };
@@ -120,9 +122,13 @@ TEST_F(D2ControllerTest, initProcessTesting) {
 TEST_F(D2ControllerTest, launchNormalShutdown) {
     // command line to run standalone
     char* argv[] = { const_cast<char*>("progName"),
-                     const_cast<char*>("-s"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>(DControllerTest::CFG_TEST_FILE),
                      const_cast<char*>("-v") };
-    int argc = 3;
+    int argc = 4;
+
+    // Create a valid D2 configuration file.
+    writeFile(valid_d2_config);
 
     // Use an asiolink IntervalTimer and callback to generate the
     // shutdown invocation. (Note IntervalTimer setup is in milliseconds).
@@ -148,14 +154,10 @@ TEST_F(D2ControllerTest, launchNormalShutdown) {
 /// This really tests just the ability of the handlers to invoke the necessary
 /// chain of methods and handle error conditions. Configuration parsing and
 /// retrieval should be tested as part of the d2 configuration management
-/// implementation.  Note that this testing calls the configuration update event
-/// callback, configHandler, directly.
+/// implementation.
 /// This test verifies that:
-/// 1. Configuration will be rejected in integrated mode when there is no
-/// session established. (This is a very contrived situation).
-/// 2. In stand-alone mode a configuration update results in successful
-/// status return.
-/// 3. That an application process error in configuration updating is handled
+/// 1. A valid configuration yields a successful parse result.
+/// 2. That an application process error in configuration updating is handled
 /// properly.
 TEST_F(D2ControllerTest, configUpdateTests) {
     int rcode = -1;
@@ -169,31 +171,22 @@ TEST_F(D2ControllerTest, configUpdateTests) {
     isc::data::ElementPtr config_set =
                                 isc::data::Element::fromJSON(valid_d2_config);
 
-    // We are not stand-alone, so configuration should be rejected as there is
-    // no session.  This is a pretty contrived situation that shouldn't be
-    // possible other than the handler being called directly (like this does).
-    answer = DControllerBase::configHandler(config_set);
-    isc::config::parseAnswer(rcode, answer);
-    EXPECT_EQ(1, rcode);
-
-    // Verify that in stand alone we get a successful update result.
-    setStandAlone(true);
-    answer = DControllerBase::configHandler(config_set);
+    // Verify that given a valid config we get a successful update result.
+    answer = updateConfig(config_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(0, rcode);
 
     // Use an invalid configuration to verify parsing error return.
     std::string config = "{ \"bogus\": 1000 } ";
     config_set = isc::data::Element::fromJSON(config);
-    answer = DControllerBase::configHandler(config_set);
+    answer = updateConfig(config_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(1, rcode);
 }
 
 /// @brief Command execution tests.
 /// This really tests just the ability of the handler to invoke the necessary
-/// chain of methods and to handle error conditions. Note that this testing
-/// calls the command callback, commandHandler, directly.
+/// chain of methods and to handle error conditions.
 /// This test verifies that:
 /// 1. That an unrecognized command is detected and returns a status of
 /// d2::COMMAND_INVALID.
@@ -209,13 +202,13 @@ TEST_F(D2ControllerTest, executeCommandTests) {
 
     // Verify that an unknown command returns an COMMAND_INVALID response.
     std::string bogus_command("bogus");
-    answer = DControllerBase::commandHandler(bogus_command, arg_set);
+    answer = executeCommand(bogus_command, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_INVALID, rcode);
 
     // Verify that shutdown command returns COMMAND_SUCCESS response.
     //answer = executeCommand(SHUT_DOWN_COMMAND, isc::data::ElementPtr());
-    answer = DControllerBase::commandHandler(SHUT_DOWN_COMMAND, arg_set);
+    answer = executeCommand(SHUT_DOWN_COMMAND, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_SUCCESS, rcode);
 

+ 2 - 3
src/bin/d2/tests/d2_test.py

@@ -1,4 +1,4 @@
-# Copyright (C) 2013 Internet Systems Consortium.
+# Copyright (C) 2013-2014 Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -159,8 +159,7 @@ class TestD2Daemon(unittest.TestCase):
         print("Note: Simple test to verify that D2 server can be started.")
         # note that "-s" for stand alone is necessary in order to flush the log output
         # soon enough to catch it.
-        (returncode, output, error) = self.runCommand(["../b10-dhcp-ddns", 
-                                                       "-s", "-v"])
+        (returncode, output, error) = self.runCommand(["../b10-dhcp-ddns", "-v"])
         output_text = str(output) + str(error)
         self.assertEqual(output_text.count("DCTL_STARTING"), 1)
 

+ 77 - 57
src/bin/d2/tests/d_controller_unittests.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -76,21 +76,23 @@ TEST_F(DStubControllerTest, basicInstanceTesting) {
 /// 4. Extraneous command line information is detected.
 TEST_F(DStubControllerTest, commandLineArgs) {
 
-    // Verify that both flags are false initially.
-    EXPECT_TRUE(checkStandAlone(false));
+    // Verify that verbose flag is false initially.
     EXPECT_TRUE(checkVerbose(false));
 
     // Verify that standard options can be parsed without error.
     char* argv[] = { const_cast<char*>("progName"),
-                     const_cast<char*>("-s"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>("cfgName"),
                      const_cast<char*>("-v") };
-    int argc = 3;
+    int argc = 4;
     EXPECT_NO_THROW(parseArgs(argc, argv));
 
-    // Verify that flags are now true.
-    EXPECT_TRUE(checkStandAlone(true));
+    // Verify that verbose is true.
     EXPECT_TRUE(checkVerbose(true));
 
+    // Verify configuration file name is correct
+    EXPECT_TRUE(checkConfigFileName("cfgName"));
+
     // Verify that the custom command line option is parsed without error.
     char xopt[3] = "- ";
     xopt[1] =  *DStubController::stub_option_x_;
@@ -166,9 +168,10 @@ TEST_F(DStubControllerTest, launchInvalidUsage) {
 TEST_F(DStubControllerTest, launchProcessInitError) {
     // Command line to run integrated
     char* argv[] = { const_cast<char*>("progName"),
-                     const_cast<char*>("-s"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>(DControllerTest::CFG_TEST_FILE),
                      const_cast<char*>("-v") };
-    int argc = 3;
+    int argc = 4;
 
     // Launch the controller in stand alone mode.
     SimFailure::set(SimFailure::ftCreateProcessException);
@@ -177,13 +180,19 @@ TEST_F(DStubControllerTest, launchProcessInitError) {
 
 /// @brief Tests launch and normal shutdown (stand alone mode).
 /// This creates an interval timer to generate a normal shutdown and then
-/// launches with a valid, stand-alone command line and no simulated errors.
+/// launches with a valid, command line, with a valid configuration file
+///  and no simulated errors.
 TEST_F(DStubControllerTest, launchNormalShutdown) {
     // command line to run standalone
     char* argv[] = { const_cast<char*>("progName"),
-                     const_cast<char*>("-s"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>(DControllerTest::CFG_TEST_FILE),
                      const_cast<char*>("-v") };
-    int argc = 3;
+    int argc = 4;
+
+    // Create a non-empty, config file.  writeFile will wrap the contents
+    // with the module name for us.
+    writeFile("{}");
 
     // Use an asiolink IntervalTimer and callback to generate the
     // shutdown invocation. (Note IntervalTimer setup is in milliseconds).
@@ -205,6 +214,42 @@ TEST_F(DStubControllerTest, launchNormalShutdown) {
                 elapsed.total_milliseconds() <= 2200);
 }
 
+/// @brief Tests launch with an nonexistant configuration file.
+TEST_F(DStubControllerTest, nonexistantConfigFile) {
+    // command line to run standalone
+    char* argv[] = { const_cast<char*>("progName"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>("bogus-file"),
+                     const_cast<char*>("-v") };
+    int argc = 4;
+
+    // Record start time, and invoke launch().
+    EXPECT_THROW(launch(argc, argv), ProcessInitError);
+}
+
+/// @brief Tests launch with configuration file argument but no file name
+TEST_F(DStubControllerTest, missingConfigFileName) {
+    // command line to run standalone
+    char* argv[] = { const_cast<char*>("progName"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>("-v") };
+    int argc = 3;
+
+    // Record start time, and invoke launch().
+    EXPECT_THROW(launch(argc, argv), ProcessInitError);
+}
+
+/// @brief Tests launch with no configuration file argument
+TEST_F(DStubControllerTest, missingConfigFileArgument) {
+    // command line to run standalone
+    char* argv[] = { const_cast<char*>("progName"),
+                     const_cast<char*>("-v") };
+    int argc = 2;
+
+    // Record start time, and invoke launch().
+    EXPECT_THROW(launch(argc, argv), ProcessInitError);
+}
+
 /// @brief Tests launch with an operational error during application execution.
 /// This test creates an interval timer to generate a runtime exception during
 /// the process event loop. It launches wih a valid, stand-alone command line
@@ -212,9 +257,14 @@ TEST_F(DStubControllerTest, launchNormalShutdown) {
 TEST_F(DStubControllerTest, launchRuntimeError) {
     // command line to run standalone
     char* argv[] = { const_cast<char*>("progName"),
-                     const_cast<char*>("-s"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>(DControllerTest::CFG_TEST_FILE),
                      const_cast<char*>("-v") };
-    int argc = 3;
+    int argc = 4;
+
+    // Create a non-empty, config file.  writeFile will wrap the contents
+    // with the module name for us.
+    writeFile("{}");
 
     // Use an asiolink IntervalTimer and callback to generate the
     // shutdown invocation. (Note IntervalTimer setup is in milliseconds).
@@ -236,31 +286,14 @@ TEST_F(DStubControllerTest, launchRuntimeError) {
                 elapsed.total_milliseconds() <= 2200);
 }
 
-/// @brief Tests launch with a session establishment failure.
-/// This test launches with a valid command line for integrated mode and no.
-/// Attempting to connect to BIND10 should fail, even if BIND10 is running
-/// UNLESS the test is run as root.  Launch should throw SessionStartError.
-TEST_F(DStubControllerTest, launchSessionFailure) {
-    // Command line to run integrated
-    char* argv[] = { (char*)"progName" };
-    int argc = 1;
-
-    // Launch the controller in integrated mode.
-    EXPECT_THROW(launch(argc, argv), SessionStartError);
-}
-
 /// @brief Configuration update event testing.
 /// This really tests just the ability of the handlers to invoke the necessary
 /// chain of methods and handle error conditions. Configuration parsing and
 /// retrieval should be tested as part of the d2 configuration management
-/// implementation.  Note that this testing calls the configuration update event
-/// callback, configHandler, directly.
+/// implementation.
 /// This test verifies that:
-/// 1. Configuration will be rejected in integrated mode when there is no
-/// session established. (This is a very contrived situation).
-/// 2. In stand-alone mode a configuration update results in successful
-/// status return.
-/// 3. That an application process error in configuration updating is handled
+/// 1. That a valid configuration update results in successful status return.
+/// 2. That an application process error in configuration updating is handled
 /// properly.
 TEST_F(DStubControllerTest, configUpdateTests) {
     int rcode = -1;
@@ -275,30 +308,21 @@ TEST_F(DStubControllerTest, configUpdateTests) {
     std::string config = "{ \"test-value\": 1000 } ";
     isc::data::ElementPtr config_set = isc::data::Element::fromJSON(config);
 
-    // We are not stand-alone, so configuration should be rejected as there is
-    // no session.  This is a pretty contrived situation that shouldn't be
-    // possible other than the handler being called directly (like this does).
-    answer = DControllerBase::configHandler(config_set);
-    isc::config::parseAnswer(rcode, answer);
-    EXPECT_EQ(1, rcode);
-
-    // Verify that in stand alone we get a successful update result.
-    setStandAlone(true);
-    answer = DControllerBase::configHandler(config_set);
+    // Verify that a valid config gets a successful update result.
+    answer = updateConfig(config_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(0, rcode);
 
     // Verify that an error in process configure method is handled.
     SimFailure::set(SimFailure::ftProcessConfigure);
-    answer = DControllerBase::configHandler(config_set);
+    answer = updateConfig(config_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(1, rcode);
 }
 
 /// @brief Command execution tests.
 /// This really tests just the ability of the handler to invoke the necessary
-/// chain of methods and to handle error conditions. Note that this testing
-/// calls the command callback, commandHandler, directly.
+/// chain of methods and to handle error conditions.
 /// This test verifies that:
 /// 1. That an unrecognized command is detected and returns a status of
 /// d2::COMMAND_INVALID.
@@ -320,42 +344,38 @@ TEST_F(DStubControllerTest, executeCommandTests) {
 
     // Verify that an unknown command returns an d2::COMMAND_INVALID response.
     std::string bogus_command("bogus");
-    answer = DControllerBase::commandHandler(bogus_command, arg_set);
+    answer = executeCommand(bogus_command, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_INVALID, rcode);
 
     // Verify that shutdown command returns d2::COMMAND_SUCCESS response.
-    answer = DControllerBase::commandHandler(SHUT_DOWN_COMMAND, arg_set);
+    answer = executeCommand(SHUT_DOWN_COMMAND, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_SUCCESS, rcode);
 
     // Verify that a valid custom controller command returns
     // d2::COMMAND_SUCCESS response.
-    answer = DControllerBase::commandHandler(DStubController::
-                                             stub_ctl_command_, arg_set);
+    answer = executeCommand(DStubController::stub_ctl_command_, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_SUCCESS, rcode);
 
     // Verify that a valid custom process command returns d2::COMMAND_SUCCESS
     // response.
-    answer = DControllerBase::commandHandler(DStubProcess::
-                                             stub_proc_command_, arg_set);
+    answer = executeCommand(DStubProcess::stub_proc_command_, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_SUCCESS, rcode);
 
     // Verify that a valid custom controller command that fails returns
     // a d2::COMMAND_ERROR.
     SimFailure::set(SimFailure::ftControllerCommand);
-    answer = DControllerBase::commandHandler(DStubController::
-                                             stub_ctl_command_, arg_set);
+    answer = executeCommand(DStubController::stub_ctl_command_, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_ERROR, rcode);
 
     // Verify that a valid custom process command that fails returns
     // a d2::COMMAND_ERROR.
     SimFailure::set(SimFailure::ftProcessCommand);
-    answer = DControllerBase::commandHandler(DStubProcess::
-                                             stub_proc_command_, arg_set);
+    answer = executeCommand(DStubProcess::stub_proc_command_, arg_set);
     isc::config::parseAnswer(rcode, answer);
     EXPECT_EQ(COMMAND_ERROR, rcode);
 }

+ 6 - 1
src/bin/d2/tests/d_test_stubs.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -55,6 +55,7 @@ DStubProcess::DStubProcess(const char* name, IOServicePtr io_service)
     : DProcessBase(name, io_service, DCfgMgrBasePtr(new DStubCfgMgr())) {
 };
 
+
 void
 DStubProcess::init() {
     if (SimFailure::shouldFailOn(SimFailure::ftProcessInit)) {
@@ -140,6 +141,7 @@ const char* DStubController::stub_app_name_ = "TestService";
 /// @brief Defines the bin name used to construct the controller
 const char* DStubController::stub_bin_name_ = "TestBin";
 
+
 DControllerBasePtr&
 DStubController::instance() {
     // If the singleton hasn't been created, do it now.
@@ -217,6 +219,9 @@ DStubController::~DStubController() {
 // Initialize controller wrapper's static instance getter member.
 DControllerTest::InstanceGetter DControllerTest::instanceGetter_ = NULL;
 
+/// @brief Defines the name of the configuration file to use
+const char* DControllerTest::CFG_TEST_FILE = "d2-test-config.json";
+
 //************************** ObjectParser *************************
 
 ObjectParser::ObjectParser(const std::string& param_name,

+ 49 - 31
src/bin/d2/tests/d_test_stubs.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -25,6 +25,10 @@
 
 #include <gtest/gtest.h>
 
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
 namespace isc {
 namespace d2 {
 
@@ -293,6 +297,7 @@ public:
     /// a clean start between tests.
     virtual ~DControllerTest() {
         getController().reset();
+        static_cast<void>(unlink(CFG_TEST_FILE));
     }
 
     /// @brief Convenience method that destructs and then recreates the
@@ -361,31 +366,22 @@ public:
         return (getController()->io_service_);
     }
 
-    /// @brief Compares stand alone flag with the given value.
+    /// @brief Compares verbose flag with the given value.
     ///
     /// @param value
     ///
-    /// @return returns true if the stand alone flag is equal to the given
-    /// value.
-    bool checkStandAlone(bool value) {
-        return (getController()->isStandAlone() == value);
-    }
-
-    /// @brief Sets the controller's stand alone flag to the given value.
-    ///
-    /// @param value is the new value to assign.
-    ///
-    void setStandAlone(bool value) {
-        getController()->setStandAlone(value);
+    /// @return returns true if the verbose flag is equal to the given value.
+    bool checkVerbose(bool value) {
+        return (getController()->isVerbose() == value);
     }
 
-    /// @brief Compares verbose flag with the given value.
+    /// @brief Compares configuration file name with the given value.
     ///
-    /// @param value
+    /// @param value file name to compare against
     ///
     /// @return returns true if the verbose flag is equal to the given value.
-    bool checkVerbose(bool value) {
-        return (getController()->isVerbose() == value);
+    bool checkConfigFileName(const std::string& value) {
+        return (getController()->getConfigFile() == value);
     }
 
     /// @Wrapper to invoke the Controller's parseArgs method.  Please refer to
@@ -400,12 +396,6 @@ public:
         getController()->initProcess();
     }
 
-    /// @Wrapper to invoke the Controller's establishSession method.  Please
-    /// refer to DControllerBase::establishSession for details.
-    void establishSession() {
-        getController()->establishSession();
-    }
-
     /// @Wrapper to invoke the Controller's launch method.  Please refer to
     /// DControllerBase::launch for details.
     void launch(int argc, char* argv[]) {
@@ -413,12 +403,6 @@ public:
         getController()->launch(argc, argv, true);
     }
 
-    /// @Wrapper to invoke the Controller's disconnectSession method.  Please
-    /// refer to DControllerBase::disconnectSession for details.
-    void disconnectSession() {
-        getController()->disconnectSession();
-    }
-
     /// @Wrapper to invoke the Controller's updateConfig method.  Please
     /// refer to DControllerBase::updateConfig for details.
     isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr
@@ -437,13 +421,47 @@ public:
     /// command callback function.
     static void genShutdownCallback() {
         isc::data::ElementPtr arg_set;
-        DControllerBase::commandHandler(SHUT_DOWN_COMMAND, arg_set);
+        getController()->executeCommand(SHUT_DOWN_COMMAND, arg_set);
     }
 
     /// @brief Callback that throws an exception.
     static void genFatalErrorCallback() {
         isc_throw (DProcessBaseError, "simulated fatal error");
     }
+
+    /// @brief writes specified content to a well known file
+    ///
+    /// Writes given JSON content to CFG_TEST_FILE. It will wrap the
+    /// content within a JSON element whose name is equal to the controller's
+    /// app name or the given module name if not blank:
+    ///
+    /// @code
+    ///    { "<app_name>" : <content> }
+    /// @endcod
+    ///
+    /// suffix the content within a JSON element with the given module
+    /// name or  wrapped by a JSON
+    /// element  . Tests will
+    /// attempt to read that file.
+    ///
+    /// @param content JSON text to be written to file
+    /// @param module_name  content content to be written to file
+    void writeFile(const std::string& content,
+                   const std::string& module_name = "") {
+        std::ofstream out(CFG_TEST_FILE, std::ios::trunc);
+        ASSERT_TRUE(out.is_open());
+
+        out << "{ \"" << (!module_name.empty() ? module_name :
+                          getController()->getAppName())
+             << "\": " << std::endl;
+
+        out << content;
+        out << " } " << std::endl;
+        out.close();
+    }
+
+    /// Name of a config file used during tests
+    static const char* CFG_TEST_FILE;
 };
 
 /// @brief a collection of elements that store uint32 values