]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[client] Stub files for a client added.
authorTomek <tomasz.mrugalski@gmail.com>
Wed, 19 Jul 2017 14:57:31 +0000 (16:57 +0200)
committerTomek Mrugalski <tomasz@isc.org>
Mon, 18 Nov 2019 19:26:54 +0000 (03:26 +0800)
12 files changed:
src/bin/client/Makefile.am
src/bin/client/clnt_cfg_mgr.cc [new file with mode: 0644]
src/bin/client/clnt_cfg_mgr.h [new file with mode: 0644]
src/bin/client/clnt_config.cc [new file with mode: 0644]
src/bin/client/clnt_config.h [new file with mode: 0644]
src/bin/client/clnt_process.cc [new file with mode: 0644]
src/bin/client/clnt_process.h [new file with mode: 0644]
src/bin/client/d_controller.cc [deleted file]
src/bin/client/d_controller.h [deleted file]
src/bin/client/executor.cc [new file with mode: 0644]
src/bin/client/executor.h [new file with mode: 0644]
src/bin/client/main.cc

index 48c0d8d1ceb45f20a5914e28848dc36a11cedd7d..246d740fae31c46d26fc54012b4f5ab418afcc4c 100644 (file)
@@ -9,7 +9,7 @@ if USE_STATIC_LINK
 AM_LDFLAGS = -static
 endif
 
-CLEANFILES = 
+CLEANFILES =
 man_MANS = kea-client.8
 
 DISTCLEANFILES = $(man_MANS)
@@ -37,15 +37,22 @@ noinst_LTLIBRARIES = libclient.la
 libclnt_la_SOURCES  =
 libclnt_la_SOURCES += main.cc
 libclnt_la_SOURCES += client_interface.h client_interface.cc
+libclnt_la_SOURCES += executor.cc executor.h
+libclnt_la_SOURCES += clnt_process.cc clnt_process.h
+libclnt_la_SOURCES += clnt_cfg_mgr.cc clnt_cfg_mgr.h
+libclnt_la_SOURCES += clnt_config.cc clnt_config.h
 
 sbin_PROGRAMS = kea-client
 
+kea_client_SOURCES = main.cc
+
 kea_client_LDADD  = libclnt.la
 
 kea_client_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
 kea_client_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
 kea_client_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
 kea_client_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+kea_client_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
 kea_client_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
 kea_client_LDADD += $(BOOST_LIBS)
 
@@ -70,7 +77,6 @@ kea_client_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS)
 
 
 kea_clntdir = $(pkgdatadir)
-kea_clnt_DATA = dhcp6.spec
 
 if GENERATE_PARSER
 
diff --git a/src/bin/client/clnt_cfg_mgr.cc b/src/bin/client/clnt_cfg_mgr.cc
new file mode 100644 (file)
index 0000000..afadddb
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Paublic
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <client/clnt_cfg_mgr.h>
+#include <client/clnt_config.h>
+#include <cc/data.h>
+
+using namespace isc::data;
+
+namespace isc {
+namespace client {
+
+ClntCfgMgr::ClntCfgMgr()
+  :DCfgMgrBase(process::DCfgContextBasePtr(new ClntConfig())) {
+}
+
+std::string
+ClntCfgMgr::getConfigSummary(const uint32_t selection) {
+  return ("not-implemented");
+}
+
+isc::data::ConstElementPtr
+ClntCfgMgr::parse(isc::data::ConstElementPtr config, bool check_only) {
+    return (ConstElementPtr(new MapElement()));
+}
+
+isc::dhcp::ParserPtr
+ClntCfgMgr::createConfigParser(const std::string&,
+                               const isc::data::Element::Position& pos) {
+    return (isc::dhcp::ParserPtr());
+}
+
+process::DCfgContextBasePtr
+ClntCfgMgr::createNewContext() {
+  return (process::DCfgContextBasePtr(new ClntConfig()));
+}
+
+void ClntCfgMgr::ensureCurrentAllocated() {
+
+}
+
+};
+};
+
diff --git a/src/bin/client/clnt_cfg_mgr.h b/src/bin/client/clnt_cfg_mgr.h
new file mode 100644 (file)
index 0000000..d6c9f7a
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef CLNT_CFG_MGR_H
+#define CLNT_CFG_MGR_H
+
+#include <client/clnt_config.h>
+#include <cc/data.h>
+#include <hooks/hooks_config.h>
+#include <process/d_cfg_mgr.h>
+#include <process/base_cfg_mgr.h>
+#include <boost/pointer_cast.hpp>
+
+namespace isc {
+namespace client {
+
+class ClntCfgMgr : public process::DCfgMgrBase {
+public:
+
+    /// @brief Constructor.
+    ClntCfgMgr();
+
+    /// @brief Destructor
+    virtual ~ClntCfgMgr() { }
+
+    /// @brief Convenience method that returns the Control Agent configuration
+    /// context.
+    ///
+    /// @return returns a pointer to the configuration context.
+    ClntConfigPtr getCtrlAgentCfgContext() {
+        return (boost::dynamic_pointer_cast<ClntConfig>(getContext()));
+    }
+
+    /// @brief Returns configuration summary in the textual format.
+    ///
+    /// @param selection Bitfield which describes the parts of the configuration
+    /// to be returned. This parameter is ignored for the Control Agent.
+    ///
+    /// @return Summary of the configuration in the textual format.
+    virtual std::string getConfigSummary(const uint32_t selection);
+
+protected:
+
+    virtual void ensureCurrentAllocated();
+
+    /// @brief Parses configuration of the Control Agent.
+    ///
+    /// @param config Pointer to a configuration specified for the agent.
+    /// @param check_only Boolean flag indicating if this method should
+    /// only verify correctness of the provided conifiguration.
+    /// @return Pointer to a result of configuration parsing.
+    virtual isc::data::ConstElementPtr
+    parse(isc::data::ConstElementPtr config, bool check_only);
+
+    /// @brief This is no longer used.
+    ///
+    /// @throw NotImplemented
+    /// @return nothing, always throws
+    virtual isc::dhcp::ParserPtr
+    createConfigParser(const std::string&,
+                       const isc::data::Element::Position& pos);
+
+    /// @brief Creates a new, blank CtrlAgentCfgContext context.
+    ///
+    ///
+    /// This method is used at the beginning of configuration process to
+    /// create a fresh, empty copy of a CtrlAgentCfgContext. This new context
+    /// will be populated during the configuration process and will replace the
+    /// existing context provided the configuration process completes without
+    /// error.
+    ///
+    /// @return Returns a DCfgContextBasePtr to the new context instance.
+    virtual process::DCfgContextBasePtr createNewContext();
+};
+
+};
+};
+
+#endif
diff --git a/src/bin/client/clnt_config.cc b/src/bin/client/clnt_config.cc
new file mode 100644 (file)
index 0000000..14e169d
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <client/clnt_cfg_mgr.h>
+#include <cc/data.h>
+
+using namespace isc::data;
+
+namespace isc {
+namespace client {
+
+ClntConfig::ClntConfig() {
+
+}
+
+isc::data::ElementPtr ClntConfig::toElement() const {
+    ElementPtr map(new MapElement());
+    return (map);
+}
+
+std::string ClntConfig::getConfigSummary(const uint32_t selection) const {
+  return ("not-impl");
+}
+
+};
+};
diff --git a/src/bin/client/clnt_config.h b/src/bin/client/clnt_config.h
new file mode 100644 (file)
index 0000000..97872d2
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef CLNT_CONFIG_H
+#define CLNT_CONFIG_H
+
+#include <process/d_cfg_mgr.h>
+
+namespace isc {
+namespace client {
+
+class ClntConfig;
+typedef boost::shared_ptr<ClntConfig> ClntConfigPtr;
+
+class ClntConfig : public process::DCfgContextBase {
+public:
+  ClntConfig();
+
+  virtual process::BaseConfigPtr clone() const {
+      return (process::BaseConfigPtr(new ClntConfig(*this)));
+  }
+
+  virtual isc::data::ElementPtr toElement() const;
+
+  virtual std::string getConfigSummary(const uint32_t selection) const;
+};
+
+
+};
+};
+
+#endif
diff --git a/src/bin/client/clnt_process.cc b/src/bin/client/clnt_process.cc
new file mode 100644 (file)
index 0000000..7dba352
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <client/clnt_process.h>
+#include <client/clnt_cfg_mgr.h>
+#include <cc/command_interpreter.h>
+#include <process/d_cfg_mgr.h>
+
+using namespace isc::client;
+using namespace isc::config;
+
+ClntProcess::ClntProcess(const char* name,
+                         const asiolink::IOServicePtr& io_service)
+  :DProcessBase(name, io_service, process::DCfgMgrBasePtr(new ClntCfgMgr())) {
+
+}
+
+void ClntProcess::init() {
+
+}
+
+void ClntProcess::run() {
+    std::cout << "Running...." << std::endl;
+    while (true) {
+        std::cout << ".";
+        sleep(1);
+    }
+}
+
+isc::data::ConstElementPtr
+ClntProcess::configure(isc::data::ConstElementPtr config_set,
+                       bool check_only) {
+    return (createAnswer(3, "not implemented"));
+}
+
+isc::data::ConstElementPtr 
+ClntProcess::shutdown(isc::data::ConstElementPtr args) {
+    return (createAnswer(3, "not implemented"));
+}
+
+ClntProcess::~ClntProcess() {
+}
+
diff --git a/src/bin/client/clnt_process.h b/src/bin/client/clnt_process.h
new file mode 100644 (file)
index 0000000..2ee5759
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef CLNT_PROCESS_H
+#define CLNT_PROCESS_H
+
+#include <process/d_process.h>
+
+namespace isc {
+namespace client {
+
+
+class ClntProcess : public process::DProcessBase {
+
+ public:
+    ClntProcess(const char* nane, const asiolink::IOServicePtr& io_service);
+
+    virtual void init();
+
+    virtual void run();
+
+    virtual isc::data::ConstElementPtr
+    configure(isc::data::ConstElementPtr config_set,
+              bool check_only = false);
+
+    /// @brief Initiates the process's shutdown process. 
+    /// 
+    /// This is last step in the shutdown event callback chain, that is 
+    /// intended to notify the process it is to begin its shutdown process.
+    ///
+    /// @param args an Element set of shutdown arguments (if any) that are
+    /// supported by the process derivation. 
+    /// 
+    /// @return an Element that contains the results of argument processing,
+    /// consisting of an integer status value (0 means successful, 
+    /// non-zero means failure), and a string explanation of the outcome. 
+    ///  
+    /// @throw DProcessBaseError if an operational error is encountered.
+    virtual isc::data::ConstElementPtr 
+    shutdown(isc::data::ConstElementPtr args);
+
+    virtual ~ClntProcess();
+};
+
+};
+};
+
+#endif
diff --git a/src/bin/client/d_controller.cc b/src/bin/client/d_controller.cc
deleted file mode 100644 (file)
index 6f31a83..0000000
+++ /dev/null
@@ -1,687 +0,0 @@
-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include <config.h>
-#include <cc/command_interpreter.h>
-#include <cfgrpt/config_report.h>
-#include <dhcpsrv/cfgmgr.h>
-#include <exceptions/exceptions.h>
-#include <log/logger.h>
-#include <log/logger_support.h>
-#include <process/d_log.h>
-#include <process/d_controller.h>
-
-#ifdef HAVE_MYSQL
-#include <dhcpsrv/mysql_lease_mgr.h>
-#endif
-#ifdef HAVE_PGSQL
-#include <dhcpsrv/pgsql_lease_mgr.h>
-#endif
-#ifdef HAVE_CQL
-#include <dhcpsrv/cql_lease_mgr.h>
-#endif
-#include <dhcpsrv/memfile_lease_mgr.h>
-
-#include <sstream>
-#include <unistd.h>
-
-using namespace isc::data;
-using namespace isc::config;
-
-namespace isc {
-namespace process {
-
-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),
-      verbose_(false), check_only_(false), spec_file_name_(""),
-      io_service_(new isc::asiolink::IOService()),
-      io_signal_queue_() {
-}
-
-void
-DControllerBase::setController(const DControllerBasePtr& controller) {
-    if (controller_) {
-        // This shouldn't happen, but let's make sure it can't be done.
-        // It represents a programmatic error.
-        isc_throw (DControllerBaseError,
-                "Multiple controller instances attempted.");
-    }
-
-    controller_ = controller;
-}
-
-ConstElementPtr
-DControllerBase::parseFile(const std::string&) {
-    ConstElementPtr elements;
-    return (elements);
-}
-
-void
-DControllerBase::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());
-        // rethrow it with an empty message
-        isc_throw(InvalidUsage, "");
-    }
-
-    setProcName(bin_name_);
-
-    if (isCheckOnly()) {
-        checkConfigOnly();
-        return;
-    }
-
-    // It is important that we set a default logger name because this name
-    // will be used when the user doesn't provide the logging configuration
-    // in the Kea configuration file.
-    isc::dhcp::CfgMgr::instance().setDefaultLoggerName(bin_name_);
-
-    // Logger's default configuration depends on whether we are in the
-    // verbose mode or not. CfgMgr manages the logger configuration so
-    // the verbose mode is set for CfgMgr.
-    isc::dhcp::CfgMgr::instance().setVerbose(verbose_);
-
-    // 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.
-        Daemon::loggerInit(bin_name_.c_str(), verbose_);
-    }
-
-    try {
-        createPIDFile();
-    } catch (const dhcp::DaemonPIDExists& ex) {
-        LOG_FATAL(dctl_logger, DCTL_ALREADY_RUNNING)
-                  .arg(bin_name_).arg(ex.what());
-        isc_throw (LaunchError, "Launch Failed: " << ex.what());
-    } catch (const std::exception& ex) {
-        LOG_FATAL(dctl_logger, DCTL_PID_FILE_ERROR)
-                  .arg(app_name_).arg(ex.what());
-        isc_throw (LaunchError, "Launch failed: " << ex.what());
-    }
-
-    // Log the starting of the service.
-    LOG_INFO(dctl_logger, DCTL_STARTING)
-        .arg(app_name_).arg(getpid()).arg(VERSION);
-    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(app_name_).arg(ex.what());
-        isc_throw (ProcessInitError,
-                   "Application Process initialization failed: " << ex.what());
-    }
-
-    LOG_DEBUG(dctl_logger, isc::log::DBGLVL_START_SHUT, DCTL_STANDALONE)
-        .arg(app_name_);
-
-    // Step 3 is to load configuration from file.
-    int rcode;
-    ConstElementPtr comment = 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 configuration file: "
-                   << comment->stringValue());
-    }
-
-    // Everything is clear for launch, so start the application's
-    // event loop.
-    try {
-        // Now that we have a proces, we can set up signal handling.
-        initSignalHandling();
-        runProcess();
-    } catch (const std::exception& ex) {
-        LOG_FATAL(dctl_logger, DCTL_PROCESS_FAILED)
-                  .arg(app_name_).arg(ex.what());
-        isc_throw (ProcessRunError,
-                   "Application process event loop failed: " << ex.what());
-    }
-
-    // All done, so bail out.
-    LOG_INFO(dctl_logger, DCTL_SHUTDOWN)
-        .arg(app_name_).arg(getpid()).arg(VERSION);
-}
-
-void
-DControllerBase::checkConfigOnly() {
-    try {
-        // We need to initialize logging, in case any error
-        // messages are to be printed.
-        // This is just a test, so we don't care about lockfile.
-        setenv("KEA_LOCKFILE_DIR", "none", 0);
-        isc::dhcp::CfgMgr::instance().setDefaultLoggerName(bin_name_);
-        isc::dhcp::CfgMgr::instance().setVerbose(verbose_);
-        Daemon::loggerInit(bin_name_.c_str(), verbose_);
-
-        // Check the syntax first.
-        std::string config_file = getConfigFile();
-        if (config_file.empty()) {
-            // Basic sanity check: file name must not be empty.
-            isc_throw(InvalidUsage, "JSON configuration file not specified");
-        }
-        ConstElementPtr whole_config = parseFile(config_file);
-        if (!whole_config) {
-            // No fallback to fromJSONFile
-            isc_throw(InvalidUsage, "No configuration found");
-        }
-        if (verbose_) {
-            std::cerr << "Syntax check OK" << std::endl;
-        }
-
-        // Check the logic next.
-        ConstElementPtr module_config;
-        module_config = whole_config->get(getAppName());
-        if (!module_config) {
-            isc_throw(InvalidUsage, "Config file " << config_file <<
-                      " does not include '" << getAppName() << "' entry");
-        }
-
-        // Get an application process object.
-        initProcess();
-
-        ConstElementPtr answer = checkConfig(module_config);
-        int rcode = 0;
-        answer = parseAnswer(rcode, answer);
-        if (rcode != 0) {
-            isc_throw(InvalidUsage, "Error encountered: "
-                      << answer->stringValue());
-        }
-    } catch (const VersionMessage&) {
-        throw;
-    } catch (const InvalidUsage&) {
-        throw;
-    } catch (const std::exception& ex) {
-        isc_throw(InvalidUsage, "Syntax check failed with: " << ex.what());
-    }
-    return;
-}
-
-void
-DControllerBase::parseArgs(int argc, char* argv[])
-{
-    // Iterate over the given command line options. If its a stock option
-    // ("c" or "d") handle it here.  If its a valid custom option, then
-    // invoke customOption.
-    int ch;
-    opterr = 0;
-    optind = 1;
-    std::string opts("dvVWc:t:" + getCustomOpts());
-    while ((ch = getopt(argc, argv, opts.c_str())) != -1) {
-        switch (ch) {
-        case 'd':
-            // Enables verbose logging.
-            verbose_ = true;
-            break;
-
-        case 'v':
-            // gather Kea version and throw so main() can catch and return
-            // rather than calling exit() here which disrupts gtest.
-            isc_throw(VersionMessage, getVersion(false));
-            break;
-
-        case 'V':
-            // gather Kea version and throw so main() can catch and return
-            // rather than calling exit() here which disrupts gtest.
-            isc_throw(VersionMessage, getVersion(true));
-            break;
-
-        case 'W':
-            // gather Kea config report and throw so main() can catch and
-            // return rather than calling exit() here which disrupts gtest.
-            isc_throw(VersionMessage, isc::detail::getConfigReport());
-            break;
-
-        case 'c':
-        case 't':
-            // config file name
-            if (optarg == NULL) {
-                isc_throw(InvalidUsage, "configuration file name missing");
-            }
-
-            setConfigFile(optarg);
-
-            if (ch == 't') {
-                check_only_ = 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");
-    }
-}
-
-bool
-DControllerBase::customOption(int /* option */, char* /*optarg*/)
-{
-    // Default implementation returns false.
-    return (false);
-}
-
-void
-DControllerBase::initProcess() {
-    LOG_DEBUG(dctl_logger, isc::log::DBGLVL_START_SHUT, DCTL_INIT_PROCESS)
-        .arg(app_name_);
-
-    // Invoke virtual method to instantiate the application process.
-    try {
-        process_.reset(createProcess());
-    } catch (const std::exception& ex) {
-        isc_throw(DControllerBaseError, std::string("createProcess failed: ")
-                  + ex.what());
-    }
-
-    // This is pretty unlikely, but will test for it just to be safe..
-    if (!process_) {
-        isc_throw(DControllerBaseError, "createProcess returned NULL");
-    }
-
-    // Invoke application's init method (Note this call should throw
-    // DProcessBaseError if it fails).
-    process_->init();
-}
-
-ConstElementPtr
-DControllerBase::configFromFile() {
-    // Rollback any previous staging configuration. For D2, only a
-    // logger configuration is used here.
-    isc::dhcp::CfgMgr::instance().rollback();
-    // Will hold configuration.
-    ConstElementPtr module_config;
-    // Will receive configuration result.
-    ConstElementPtr answer;
-    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.");
-        }
-
-        // If parseFile returns an empty pointer, then pass the file onto the
-        // original JSON parser.
-        ConstElementPtr whole_config = parseFile(config_file);
-        if (!whole_config) {
-            // Read contents of the file and parse it as JSON
-            whole_config = Element::fromJSONFile(config_file, true);
-        }
-
-        // Let's configure logging before applying the configuration,
-        // so we can log things during configuration process.
-
-        // Temporary storage for logging configuration
-        isc::dhcp::SrvConfigPtr storage =
-            isc::dhcp::CfgMgr::instance().getStagingCfg();
-
-        // Get 'Logging' element from the config and use it to set up
-        // logging. If there's no such element, we'll just pass NULL.
-        Daemon::configureLogger(whole_config->get("Logging"), storage);
-
-        // 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.");
-        }
-
-        answer = updateConfig(module_config);
-        int rcode = 0;
-        parseAnswer(rcode, answer);
-        if (!rcode) {
-            // Configuration successful, so apply the logging configuration
-            // to log4cplus.
-            isc::dhcp::CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
-            isc::dhcp::CfgMgr::instance().commit();
-        }
-
-    } catch (const std::exception& ex) {
-        // Rollback logging configuration.
-        isc::dhcp::CfgMgr::instance().rollback();
-        // build an error result
-        ConstElementPtr error = createAnswer(COMMAND_ERROR,
-                 std::string("Configuration parsing failed: ") + ex.what());
-        return (error);
-    }
-
-    return (answer);
-}
-
-
-void
-DControllerBase::runProcess() {
-    LOG_DEBUG(dctl_logger, isc::log::DBGLVL_START_SHUT, DCTL_RUN_PROCESS)
-        .arg(app_name_);
-    if (!process_) {
-        // This should not be possible.
-        isc_throw(DControllerBaseError, "Process not initialized");
-    }
-
-    // Invoke the application process's run method. This may throw
-    // DProcessBaseError
-    process_->run();
-}
-
-// Instance method for handling new config
-ConstElementPtr
-DControllerBase::updateConfig(ConstElementPtr new_config) {
-    return (process_->configure(new_config, false));
-}
-
-// Instance method for checking new config
-ConstElementPtr
-DControllerBase::checkConfig(ConstElementPtr new_config) {
-    return (process_->configure(new_config, true));
-}
-
-ConstElementPtr
-DControllerBase::configGetHandler(const std::string&,
-                                  ConstElementPtr /*args*/) {
-    ConstElementPtr config = process_->getCfgMgr()->getContext()->toElement();
-
-    return (createAnswer(COMMAND_SUCCESS, config));
-}
-
-ConstElementPtr
-DControllerBase::configWriteHandler(const std::string&,
-                                    ConstElementPtr args) {
-    std::string filename;
-
-    if (args) {
-        if (args->getType() != Element::map) {
-            return (createAnswer(COMMAND_ERROR, "Argument must be a map"));
-        }
-        ConstElementPtr filename_param = args->get("filename");
-        if (filename_param) {
-            if (filename_param->getType() != Element::string) {
-                return (createAnswer(COMMAND_ERROR,
-                                     "passed parameter 'filename' "
-                                     "is not a string"));
-            }
-            filename = filename_param->stringValue();
-        }
-    }
-
-    if (filename.empty()) {
-        // filename parameter was not specified, so let's use
-        // whatever we remember
-        filename = getConfigFile();
-        if (filename.empty()) {
-            return (createAnswer(COMMAND_ERROR,
-                                 "Unable to determine filename."
-                                 "Please specify filename explicitly."));
-        }
-    }
-
-
-    // Ok, it's time to write the file.
-    size_t size = 0;
-    ElementPtr cfg = process_->getCfgMgr()->getContext()->toElement();
-
-    // Logging storage is messed up in CA. During its configuration (see
-    // DControllerBase::configFromFile() it calls Daemon::configureLogger()
-    // that stores the logging info in isc::dhcp::CfgMgr::getStagingCfg().
-    // This is later moved to getCurrentCfg() when the configuration is
-    // commited. All control-agent specific configuration is stored in
-    // a structure accessible by process_->getCfgMgr()->getContext(). Note
-    // logging information is not stored there.
-    //
-    // As a result, we need to extract the CA configuration from one
-    // place and logging from another.
-    ConstElementPtr loginfo = isc::dhcp::CfgMgr::instance().getCurrentCfg()->toElement();
-    if (loginfo) {
-        // If there was a config stored in dhcp::CfgMgr, try to get Logging info from it.
-        loginfo = loginfo->get("Logging");
-    }
-    if (loginfo) {
-        // If there is some logging information, add it to our config.
-        cfg->set("Logging", loginfo);
-    }
-
-    try {
-        size = writeConfigFile(filename, cfg);
-    } catch (const isc::Exception& ex) {
-        return (createAnswer(COMMAND_ERROR,
-                             std::string("Error during write-config:")
-                             + ex.what()));
-    }
-    if (size == 0) {
-        return (createAnswer(COMMAND_ERROR,
-                             "Error writing configuration to " + filename));
-    }
-
-    // Ok, it's time to return the successful response.
-    ElementPtr params = Element::createMap();
-    params->set("size", Element::create(static_cast<long long>(size)));
-    params->set("filename", Element::create(filename));
-
-    return (createAnswer(CONTROL_RESULT_SUCCESS, "Configuration written to "
-                         + filename + " successful", params));
-}
-
-ConstElementPtr
-DControllerBase::configTestHandler(const std::string&, ConstElementPtr args) {
-    const int status_code = COMMAND_ERROR; // 1 indicates an error
-    ConstElementPtr module_config;
-    std::string app_name = getAppName();
-    std::string message;
-
-    // Command arguments are expected to be:
-    // { "Module": { ... }, "Logging": { ... } }
-    // The Logging component is technically optional. If it's not supplied
-    // logging will revert to default logging.
-    if (!args) {
-        message = "Missing mandatory 'arguments' parameter.";
-    } else {
-      module_config = args->get(app_name);
-        if (!module_config) {
-            message = "Missing mandatory '" + app_name + "' parameter.";
-        } else if (module_config->getType() != Element::map) {
-            message = "'" + app_name + "' parameter expected to be a map.";
-        }
-    }
-
-    if (!message.empty()) {
-        // Something is amiss with arguments, return a failure response.
-        ConstElementPtr result = isc::config::createAnswer(status_code,
-                                                           message);
-        return (result);
-    }
-
-    // We are starting the configuration process so we should remove any
-    // staging configuration that has been created during previous
-    // configuration attempts.
-    isc::dhcp::CfgMgr::instance().rollback();
-
-    // Now we check the server proper.
-    return (checkConfig(module_config));
-}
-
-ConstElementPtr
-DControllerBase::versionGetHandler(const std::string&, ConstElementPtr) {
-    ConstElementPtr answer;
-
-    // For version-get put the extended version in arguments
-    ElementPtr extended = Element::create(getVersion(true));
-    ElementPtr arguments = Element::createMap();
-    arguments->set("extended", extended);
-    answer = createAnswer(COMMAND_SUCCESS, getVersion(false), arguments);
-    return (answer);
-}
-
-ConstElementPtr
-DControllerBase::buildReportHandler(const std::string&, ConstElementPtr) {
-    return (createAnswer(COMMAND_SUCCESS, isc::detail::getConfigReport()));
-}
-
-ConstElementPtr
-DControllerBase::shutdownHandler(const std::string&, ConstElementPtr args) {
-    // Shutdown is universal.  If its not that, then try it as
-    // a custom command supported by the derivation.  If that
-    // doesn't pan out either, than send to it the application
-    // as it may be supported there.
-    return (shutdownProcess(args));
-}
-
-ConstElementPtr
-DControllerBase::shutdownProcess(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.
-    LOG_WARN(dctl_logger, DCTL_NOT_RUNNING).arg(app_name_);
-    return (createAnswer(COMMAND_SUCCESS, "Process has not been initialized"));
-}
-
-void
-DControllerBase::initSignalHandling() {
-    /// @todo block everything we don't handle
-
-    // Create our signal queue.
-    io_signal_queue_.reset(new IOSignalQueue(io_service_));
-
-    // Install the on-receipt handler
-    util::SignalSet::setOnReceiptHandler(boost::bind(&DControllerBase::
-                                                     osSignalHandler,
-                                                     this, _1));
-    // Register for the signals we wish to handle.
-    signal_set_.reset(new util::SignalSet(SIGHUP,SIGINT,SIGTERM));
-}
-
-bool
-DControllerBase::osSignalHandler(int signum) {
-    // Create a IOSignal to propagate the signal to IOService.
-    io_signal_queue_->pushSignal(signum, boost::bind(&DControllerBase::
-                                                     ioSignalHandler,
-                                                     this, _1));
-    return (true);
-}
-
-void
-DControllerBase::ioSignalHandler(IOSignalId sequence_id) {
-    // Pop the signal instance off the queue.  This should make us
-    // the only one holding it, so when we leave it should be freed.
-    // (note that popSignal will throw if signal is not found, which
-    // in turn will caught, logged, and swallowed by IOSignal callback
-    // invocation code.)
-    IOSignalPtr io_signal = io_signal_queue_->popSignal(sequence_id);
-
-    // Now call virtual signal processing method.
-    processSignal(io_signal->getSignum());
-}
-
-void
-DControllerBase::processSignal(int signum) {
-    switch (signum) {
-        case SIGHUP:
-        {
-            LOG_INFO(dctl_logger, DCTL_CFG_FILE_RELOAD_SIGNAL_RECVD)
-                     .arg(signum).arg(getConfigFile());
-            int rcode;
-            ConstElementPtr comment = parseAnswer(rcode, configFromFile());
-            if (rcode != 0) {
-                LOG_ERROR(dctl_logger, DCTL_CFG_FILE_RELOAD_ERROR)
-                          .arg(comment->stringValue());
-            }
-
-            break;
-        }
-
-        case SIGINT:
-        case SIGTERM:
-        {
-            LOG_DEBUG(dctl_logger, isc::log::DBGLVL_START_SHUT,
-                      DCTL_SHUTDOWN_SIGNAL_RECVD).arg(signum);
-            ElementPtr arg_set;
-            shutdownHandler(SHUT_DOWN_COMMAND, arg_set);
-            break;
-        }
-
-        default:
-            LOG_WARN(dctl_logger, DCTL_UNSUPPORTED_SIGNAL).arg(signum);
-            break;
-    }
-}
-
-void
-DControllerBase::usage(const std::string & text)
-{
-    if (text != "") {
-        std::cerr << "Usage error: " << text << std::endl;
-    }
-
-    std::cerr << "Usage: " << bin_name_ <<  std::endl
-              << "  -v: print version number and exit" << std::endl
-              << "  -V: print extended version information and exit"
-              << std::endl
-              << "  -W: display the configuration report and exit"
-              << std::endl
-              << "  -d: optional, verbose output " << std::endl
-              << "  -c <config file name> : mandatory,"
-              << " specify name of configuration file" << std::endl
-              << "  -t <config file name> : check the"
-              << " configuration file and exit" << std::endl;
-
-    // add any derivation specific usage
-    std::cerr << getUsageText() << std::endl;
-}
-
-DControllerBase::~DControllerBase() {
-}
-
-// Refer to config_report so it will be embedded in the binary
-const char* const* d2_config_report = isc::detail::config_report;
-
-std::string
-DControllerBase::getVersion(bool extended) {
-    std::stringstream tmp;
-
-    tmp << VERSION;
-    if (extended) {
-        tmp << std::endl << EXTENDED_VERSION << std::endl;
-        tmp << "linked with:" << std::endl;
-        tmp << isc::log::Logger::getVersion() << std::endl;
-        tmp << getVersionAddendum();
-    }
-
-    return (tmp.str());
-}
-
-}; // namespace isc::process
-
-}; // namespace isc
diff --git a/src/bin/client/d_controller.h b/src/bin/client/d_controller.h
deleted file mode 100644 (file)
index 63d00c8..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef D_CONTROLLER_H
-#define D_CONTROLLER_H
-
-#include <asiolink/io_service.h>
-#include <cc/data.h>
-#include <dhcpsrv/daemon.h>
-#include <exceptions/exceptions.h>
-#include <log/logger_support.h>
-#include <process/d_log.h>
-#include <process/d_process.h>
-#include <process/io_service_signal.h>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/noncopyable.hpp>
-
-#include <string>
-#include <set>
-
-namespace isc {
-namespace process {
-
-/// @brief Exception thrown when the command line is invalid.
-/// Can be used to transmit negative messages too.
-class InvalidUsage : public isc::Exception {
-public:
-    InvalidUsage(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) { };
-};
-
-/// @brief Exception used to convey version info upwards.
-/// Since command line argument parsing is done as part of
-/// DControllerBase::launch(), it uses this exception to propagate
-/// version information up to main(), when command line argument
-/// -v, -V or -W is given. Can be used to transmit positive messages too.
-class VersionMessage : public isc::Exception {
-public:
-    VersionMessage(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) { };
-};
-
-/// @brief Exception thrown when the controller launch fails.
-class LaunchError: public isc::Exception {
-public:
-    LaunchError (const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) { };
-};
-
-/// @brief Exception thrown when the application process fails.
-class ProcessInitError: public isc::Exception {
-public:
-    ProcessInitError (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 {
-public:
-    ProcessRunError (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:
-    DControllerBaseError (const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) { };
-};
-
-
-/// @brief Defines a shared pointer to DControllerBase.
-class DControllerBase;
-typedef boost::shared_ptr<DControllerBase> DControllerBasePtr;
-
-/// @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 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.
-/// It provides the callback handlers for command and configuration events
-/// which could be triggered by an external source.  Such sources are intended
-/// to be registered with and monitored by the controller's IOService such that
-/// the appropriate handler can be invoked.
-///
-/// DControllerBase provides dynamic configuration file reloading upon receipt
-/// of SIGHUP, and graceful shutdown upon receipt of either SIGINT or SIGTERM.
-///
-/// 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 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.
-    DControllerBase(const char* app_name, const char* bin_name);
-
-    /// @brief Destructor
-    virtual ~DControllerBase();
-
-    /// @brief returns Kea version on stdout and exit.
-    /// redeclaration/redefinition. @ref isc::dhcp::Daemon::getVersion()
-    std::string getVersion(bool extended);
-
-    /// @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. load the configuration file
-    /// 4. initialize signal handling
-    /// 5. start and wait on the application process event loop
-    /// 6. exit to the caller
-    ///
-    /// It is intended to be called from main() and be given the command line
-    /// arguments.
-    ///
-    /// This function can be run in "test mode". It prevents initialization
-    /// of module logger. This is used in unit tests which initialize logger
-    /// 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
-    /// @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.
-    /// ProcessRunError - A fatal error occurred while in the application
-    /// process event loop.
-    virtual void launch(int argc, char* argv[], const bool test_mode);
-
-    /// @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 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);
-
-    /// @brief Instance method invoked by the configuration event handler and
-    /// which processes the actual configuration check.  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
-    /// with a final rollback.
-    ///
-    /// @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 checkConfig(isc::data::ConstElementPtr
-                                                   new_config);
-
-    /// @brief Reconfigures the process from a configuration file
-    ///
-    /// By default the file is assumed to be a JSON text file whose contents
-    /// include at least:
-    ///
-    /// @code
-    ///  { "<module-name>": {<module-config>}
-    ///
-    ///   # Logging element is optional
-    ///   ,"Logging": {<logger connfig}
-    ///  }
-    ///
-    ///  where:
-    ///     module-name : is a label which uniquely identifies the
-    ///                   configuration data for this controller's application
-    ///
-    ///     module-config: a set of zero or more JSON elements which comprise
-    ///                    the application's configuration values
-    /// @endcode
-    ///
-    /// To translate the JSON content into Elements, @c parseFile() is called
-    /// first.  This virtual method provides derivations a means to parse the
-    /// file content using an alternate parser.  If it returns an empty pointer
-    /// than the JSON parsing providing by Element::fromJSONFile() is called.
-    ///
-    /// Once parsed, the method looks for the Element "Logging" and, if present
-    /// uses it to configure loging.
-    ///
-    /// It then extracts the set of configuration elements for the
-    /// module-name that matches the controller's app_name_ and passes that
-    /// set into @c updateConfig() (or @c checkConfig()).
-    ///
-    /// 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 configFromFile();
-
-    /// @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_);
-    }
-
-    /// @brief handler for version-get command
-    ///
-    /// This method handles the version-get command. It returns the basic and
-    /// extended version.
-    ///
-    /// @param command (ignored)
-    /// @param args (ignored)
-    /// @return answer with version details.
-    isc::data::ConstElementPtr
-    versionGetHandler(const std::string& command,
-                      isc::data::ConstElementPtr args);
-
-    /// @brief handler for 'build-report' command
-    ///
-    /// This method handles build-report command. It returns the output printed
-    /// by configure script which contains most compilation parameters.
-    ///
-    /// @param command (ignored)
-    /// @param args (ignored)
-    /// @return answer with build report
-    isc::data::ConstElementPtr
-    buildReportHandler(const std::string& command,
-                       isc::data::ConstElementPtr args);
-
-    /// @brief handler for config-get command
-    ///
-    /// This method handles the config-get command, which retrieves
-    /// the current configuration and returns it in response.
-    ///
-    /// @param command (ignored)
-    /// @param args (ignored)
-    /// @return current configuration wrapped in a response
-    isc::data::ConstElementPtr
-    configGetHandler(const std::string& command,
-                     isc::data::ConstElementPtr args);
-
-    /// @brief handler for config-write command
-    ///
-    /// This handle processes write-config comamnd, which writes the
-    /// current configuration to disk. This command takes one optional
-    /// parameter called filename. If specified, the current configuration
-    /// will be written to that file. If not specified, the file used during
-    /// Kea start-up will be used. To avoid any exploits, the path is
-    /// always relative and .. is not allowed in the filename. This is
-    /// a security measure against exploiting file writes remotely.
-    ///
-    /// @param command (ignored)
-    /// @param args may contain optional string argument filename
-    /// @return status of the configuration file write
-    isc::data::ConstElementPtr
-    configWriteHandler(const std::string& command,
-                       isc::data::ConstElementPtr args);
-
-    /// @brief handler for config-test command
-    ///
-    /// This method handles the config-test command, which checks
-    /// configuration specified in args parameter.
-    ///
-    /// @param command (ignored)
-    /// @param args configuration to be checked.
-    /// @return status of the command
-    isc::data::ConstElementPtr
-    configTestHandler(const std::string& command,
-                      isc::data::ConstElementPtr args);
-
-    /// @brief handler for 'shutdown' command
-    ///
-    /// This method handles shutdown command. It initiates the shutdown procedure
-    /// using CPL methods.
-    /// @param command (ignored)
-    /// @param args (ignored)
-    /// @return answer confirming that the shutdown procedure is started
-    isc::data::ConstElementPtr
-    shutdownHandler(const std::string& command,
-                    isc::data::ConstElementPtr args);
-
-protected:
-    /// @brief Virtual method that provides derivations the opportunity to
-    /// support additional command line options.  It is invoked during command
-    /// line argument parsing (see parseArgs method) if the option is not
-    /// recognized as a stock DControllerBase option.
-    ///
-    /// @param option is the option "character" from the command line, without
-    /// any prefixing hyphen(s)
-    /// @param optarg is the argument value (if one) associated with the option
-    ///
-    /// @return must return true if the option was valid, false if it is
-    /// invalid. (Note the default implementation always returns false.)
-    virtual bool customOption(int option, char *optarg);
-
-    /// @brief Abstract method that is responsible for instantiating the
-    /// application process object. It is invoked by the controller after
-    /// command line argument parsing as part of the process initialization
-    /// (see initProcess method).
-    ///
-    /// @return returns a pointer to the new process object (DProcessBase*)
-    /// or NULL if the create fails.
-    /// Note this value is subsequently wrapped in a smart pointer.
-    virtual DProcessBase* createProcess() = 0;
-
-    /// @brief Virtual method which can be used to contribute derivation
-    /// specific usage text.  It is invoked by the usage() method under
-    /// invalid usage conditions.
-    ///
-    /// @return returns the desired text.
-    virtual const std::string getUsageText() const {
-        return ("");
-    }
-
-    /// @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 "c", "d", ..., during command
-    /// line interpretation.
-    ///
-    /// @return returns a string containing the custom option letters.
-    virtual const std::string getCustomOpts() const {
-        return ("");
-    }
-
-    /// @brief Check the configuration
-    ///
-    /// Called by @c launch() when @c check_only_ mode is enabled
-    /// @throw VersionMessage when successful but a message should be displayed
-    /// @throw InvalidUsage when an error was detected
-    void checkConfigOnly();
-
-    /// @brief Application-level signal processing method.
-    ///
-    /// This method is the last step in processing a OS signal occurrence.  It
-    /// is invoked when an IOSignal's internal timer callback is executed by
-    /// IOService.  It currently supports the following signals as follows:
-    /// -# SIGHUP - instigates reloading the configuration file
-    /// -# SIGINT - instigates a graceful shutdown
-    /// -# SIGTERM - instigates a graceful shutdown
-    /// If it receives any other signal, it will issue a debug statement and
-    /// discard it.
-    /// Derivations wishing to support additional signals could override this
-    /// method with one that: processes the signal if it is one of additional
-    /// signals, otherwise invoke this method (DControllerBase::processSignal())
-    /// with the signal value.
-    /// @todo Provide a convenient way for derivations to register additional
-    /// signals.
-    virtual void processSignal(int signum);
-
-    /// @brief Supplies whether or not verbose logging is enabled.
-    ///
-    /// @return returns true if verbose logging is enabled.
-    bool isVerbose() const {
-        return (verbose_);
-    }
-
-    /// @brief Method for enabling or disabling verbose logging.
-    ///
-    /// @param value is the new value to assign the flag.
-    void setVerbose(bool value) {
-        verbose_ = value;
-    }
-
-    /// @brief Supplies whether or not check only mode is enabled.
-    ///
-    /// @return returns true if check only is enabled.
-    bool isCheckOnly() const {
-        return (check_only_);
-    }
-
-    /// @brief Method for enabling or disabling check only mode.
-    ///
-    /// @todo this method and @c setVerbose are currently not used.
-    ///
-    /// @param value is the new value to assign the flag.
-    void setCheckOnly(bool value) {
-        check_only_ = value;
-    }
-
-    /// @brief Getter for fetching the controller's IOService
-    ///
-    /// @return returns a pointer reference to the IOService.
-    asiolink::IOServicePtr& getIOService() {
-        return (io_service_);
-    }
-
-    /// @brief Getter for fetching the name of the controller's config spec
-    /// file.
-    ///
-    /// @return returns the file name string.
-    const std::string getSpecFileName() const {
-        return (spec_file_name_);
-    }
-
-    /// @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) {
-        spec_file_name_ = spec_file_name;
-    }
-
-    /// @brief Static getter which returns the singleton instance.
-    ///
-    /// @return returns a pointer reference to the private singleton instance
-    /// member.
-    static DControllerBasePtr& getController() {
-        return (controller_);
-    }
-
-    /// @brief Static setter which sets the singleton instance.
-    ///
-    /// @param controller is a pointer to the singleton instance.
-    ///
-    /// @throw throws DControllerBase error if an attempt is made to set the
-    /// instance a second time.
-    static void setController(const DControllerBasePtr& controller);
-
-    /// @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.
-    /// It handles stock options directly, and passes any custom options into
-    /// the customOption method.  Currently there are only some stock options
-    /// -c/t for specifying the configuration file, -d for verbose logging,
-    /// and -v/V/W for version reports.
-    ///
-    /// @param argc  is the number of command line arguments supplied
-    /// @param argv  is the array of string (char *) command line arguments
-    ///
-    /// @throw InvalidUsage when there are usage errors.
-    /// @throw VersionMessage if the -v, -V or -W arguments is given.
-    void parseArgs(int argc, char* argv[]);
-
-
-    ///@brief Parse a given file into Elements
-    ///
-    /// This method provides a means for deriving classes to use alternate
-    /// parsing mechanisms to parse configuration files into the corresponding
-    /// isc::data::Elements. The elements produced must be equivalent to those
-    /// which would be produced by the original JSON parsing.  Implementations
-    /// should throw when encountering errors.
-    ///
-    /// The default implementation returns an empty pointer, signifying to
-    /// callers that they should submit the file to the original parser.
-    ///
-    /// @param file_name pathname of the file to parse
-    ///
-    /// @return pointer to the elements created
-    ///
-    virtual isc::data::ConstElementPtr parseFile(const std::string& file_name);
-
-    ///@brief Parse text into Elements
-    ///
-    /// This method provides a means for deriving classes to use alternate
-    /// parsing mechanisms to parse configuration text into the corresponding
-    /// isc::data::Elements. The elements produced must be equivalent to those
-    /// which would be produced by the original JSON parsing.  Implementations
-    /// should throw when encountering errors.
-    ///
-    /// The default implementation returns an empty pointer, signifying to
-    /// callers that they should submit the text to the original parser.
-    ///
-    /// @param input text to parse
-    ///
-    /// @return pointer to the elements created
-    ///
-    virtual isc::data::ConstElementPtr parseText(const std::string& input) {
-        static_cast<void>(input); // just tu shut up the unused parameter warning
-        isc::data::ConstElementPtr elements;
-        return (elements);
-    }
-
-    /// @brief Instantiates the application process and then initializes it.
-    /// This is the second step taken during launch, following successful
-    /// command line parsing. It is used to invoke the derivation-specific
-    /// implementation of createProcess, following by an invoking of the
-    /// newly instantiated process's init method.
-    ///
-    /// @throw throws DControllerBaseError or indirectly DProcessBaseError
-    /// if there is a failure creating or initializing the application process.
-    void initProcess();
-
-    /// @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,
-    /// and session establishment (if not stand-alone).
-    /// The process event loop is expected to only return upon application
-    /// shutdown either in response to the shutdown command or due to an
-    /// unrecoverable error.
-    ///
-    // @throw throws DControllerBaseError or indirectly DProcessBaseError
-    void runProcess();
-
-    /// @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
-    /// to begin its shutdown process.
-    ///
-    /// Note, it is assumed that the process of shutting down is neither
-    /// instantaneous nor synchronous.  This method does not "block" waiting
-    /// 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.
-    ///
-    /// @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.
-    ///
-    /// @param args is a set of derivation-specific arguments (if any)
-    /// for the shutdown command.
-    isc::data::ConstElementPtr shutdownProcess(isc::data::ConstElementPtr args);
-
-    /// @brief Initializes signal handling
-    ///
-    /// This method configures the controller to catch and handle signals.
-    /// It instantiates an IOSignalQueue, registers @c osSignalHandler() as
-    /// the SignalSet "on-receipt" handler, and lastly instantiates a SignalSet
-    /// which listens for SIGHUP, SIGINT, and SIGTERM.
-    void initSignalHandling();
-
-    /// @brief Handler for processing OS-level signals
-    ///
-    /// This method is installed as the SignalSet "on-receipt" handler. Upon
-    /// invocation, it uses the controller's IOSignalQueue to schedule an
-    /// IOSignal with for the given signal value.
-    ///
-    /// @param signum OS signal value (e.g. SIGINT, SIGUSR1 ...) to received
-    ///
-    /// @return SignalSet "on-receipt" handlers are required to return a
-    /// boolean indicating if the OS signal has been processed (true) or if it
-    /// should be saved for deferred processing (false).  Currently this
-    /// method processes all received signals, so it always returns true.
-    bool osSignalHandler(int signum);
-
-    /// @brief Handler for processing IOSignals
-    ///
-    /// This method is supplied as the callback when IOSignals are scheduled.
-    /// It fetches the IOSignal for the given sequence_id and then invokes
-    /// the virtual method, @c processSignal() passing it the signal value
-    /// obtained from the IOSignal.  This allows derivations to supply a
-    /// custom signal processing method, while ensuring IOSignalQueue
-    /// integrity.
-    ///
-    /// @param sequence_id id of the IOSignal instance "received"
-    void ioSignalHandler(IOSignalId sequence_id);
-
-    /// @brief Fetches the current process
-    ///
-    /// @return a pointer to the current process instance.
-    DProcessBasePtr getProcess() {
-        return (process_);
-    }
-
-    /// @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);
-
-    /// @brief Fetches text containing additional version specifics
-    ///
-    /// This method is provided so derivations can append any additional
-    /// desired information such as library dependencies to the extended
-    /// version text returned when DControllerBase::getVersion(true) is
-    /// invoked.
-    /// @return a string containing additonal version info
-    virtual std::string getVersionAddendum() { return (""); }
-
-private:
-    /// @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 executable name. It is also used to
-    /// establish the logger name.
-    std::string bin_name_;
-
-    /// @brief Indicates if the verbose logging mode is enabled.
-    bool verbose_;
-
-    /// @brief Indicates if the check only mode for the configuration
-    /// is enabled (usually specified by the command line -t argument).
-    bool check_only_;
-
-    /// @brief The absolute file name of the JSON spec file.
-    std::string spec_file_name_;
-
-    /// @brief Pointer to the instance of the process.
-    ///
-    /// This is required for config and command handlers to gain access to
-    /// the process
-    DProcessBasePtr process_;
-
-    /// @brief Shared pointer to an IOService object, used for ASIO operations.
-    asiolink::IOServicePtr io_service_;
-
-    /// @brief Queue for propagating caught signals to the IOService.
-    IOSignalQueuePtr io_signal_queue_;
-
-    /// @brief Singleton instance value.
-    static DControllerBasePtr controller_;
-
-// DControllerTest is named a friend class to facilitate unit testing while
-// leaving the intended member scopes intact.
-friend class DControllerTest;
-};
-
-}; // namespace isc::process
-}; // namespace isc
-
-#endif
diff --git a/src/bin/client/executor.cc b/src/bin/client/executor.cc
new file mode 100644 (file)
index 0000000..359b224
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <client/executor.h>
+#include <client/clnt_process.h>
+#include <cc/command_interpreter.h>
+
+using namespace isc::process;
+
+namespace isc {
+namespace client {
+
+const char* Executor::name_("kea-client");
+
+Executor::Executor()
+    : DControllerBase(name_, name_) {
+}
+
+DControllerBasePtr&
+Executor::instance() {
+    // If the instance hasn't been created yet, create it.  Note this method
+    // must use the base class singleton instance methods.
+    if (!getController()) {
+        DControllerBasePtr controller_ptr(new Executor());
+        setController(controller_ptr);
+    }
+
+    return (getController());
+}
+
+DProcessBase* Executor::createProcess() {
+    // Instantiate and return an instance of the D2 application process. Note
+    // that the process is passed the controller's io_service.
+    return (new ClntProcess(getAppName().c_str(), getIOService()));
+}
+
+
+isc::data::ConstElementPtr
+Executor::parseFile(const std::string& file_name) {
+    return (config::createAnswer(3, "sorry, not implemented"));
+}
+
+};
+};
diff --git a/src/bin/client/executor.h b/src/bin/client/executor.h
new file mode 100644 (file)
index 0000000..2207e30
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef CLNT_EXECUTOR_H
+#define CLNT_EXECUTOR_H
+
+
+// One of the client requirements is to keep its footprint small. We can't use
+// the DControllerBase until the mess with its dependencies is sorted out.
+// See all the crap in libkea_process_la_LIBADD in src/lib/process/Makefile.am
+// and make your own opinion.
+#include <process/d_controller.h>
+
+namespace isc {
+namespace client {
+
+/// @brief Process Controller for the client process
+/// 
+/// This class is the client specific derivation of DControllerBase. It
+/// creates and manages an instance of the client application process,
+/// D2Process.
+///
+/// @todo Currently, this class provides only the minimum required specialized
+/// behavior to run the client service. It may very well expand as the
+/// service implementation evolves.  Some thought was given to making
+/// DControllerBase a templated class but the labor savings versus the
+/// potential number of virtual methods which may be overridden didn't seem
+/// worth the clutter at this point.
+class Executor : public process::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 process::DControllerBasePtr& instance();
+
+    /// @brief Destructor.
+    virtual ~Executor() {}
+
+    static const char* name_;
+
+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 process::DProcessBase* createProcess();
+
+    ///@brief Parse a given file into Elements
+    ///
+    /// Uses bison parsing to parse a JSON configuration file into an
+    /// a element map.
+    ///
+    /// @param file_name pathname of the file to parse
+    ///
+    /// @return pointer to the map of elements created
+    /// @throw BadValue if the file is empty
+    virtual isc::data::ConstElementPtr parseFile(const std::string& file_name);
+
+    /// @brief Constructor is declared private to maintain the integrity of
+    /// the singleton instance.
+    Executor();
+};
+
+}; // namespace isc::d2
+}; // namespace isc
+
+#endif
index d724bad66fb7271deb07e58ed2da468fd474a7ad..296fb1edbd14f50adb8287a82bedcc2fac0495f2 100644 (file)
@@ -5,7 +5,8 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #include <config.h>
-#include <client/clnt_controller.h>
+#include <client/executor.h>
+#include <client/clnt_config.h>
 #include <exceptions/exceptions.h>
 
 #include <iostream>
@@ -25,8 +26,12 @@ int main(int argc, char* argv[]) {
     // Launch the controller passing in command line arguments.
     // Exit program with the controller's return code.
     try  {
+
+        //ClntConfig cfg;
+        //std::cout << cfg.toElement()->str() << std::endl;
+
         // Instantiate/fetch the client application controller singleton.
-        DControllerBasePtr& controller = ClntController::instance();
+        DControllerBasePtr& controller = Executor::instance();
 
         // 'false' value disables test mode.
         controller->launch(argc, argv, false);