Parcourir la source

[102b] rebased

Francis Dupont il y a 8 ans
Parent
commit
e38e8d974c

+ 31 - 1
doc/guide/ctrl-channel.xml

@@ -113,6 +113,22 @@ will be sent to Kea and the responses received from Kea printed to standard outp
     <section id="commands-common">
     <section id="commands-common">
       <title>Commands Supported by Both the DHCPv4 and DHCPv6 Servers</title>
       <title>Commands Supported by Both the DHCPv4 and DHCPv6 Servers</title>
 
 
+      <section id="command-build-report">
+        <title>build-report</title>
+        <para>
+          The <emphasis>build-report</emphasis> command returns
+          on the control channel what the command line
+          <command>-W</command> argument displays, i.e. the embedded
+          content of the <filename>config.report</filename> file.
+          This command does not take any parameters.
+        </para>
+<screen>
+{
+    "command": "build-report"
+}
+</screen>
+      </section> <!-- end of command-build-report -->
+
       <section id="command-config-get">
       <section id="command-config-get">
         <title>config-get</title>
         <title>config-get</title>
 
 
@@ -315,7 +331,21 @@ will be sent to Kea and the responses received from Kea printed to standard outp
       </para>
       </para>
     </section> <!-- end of command-shutdown -->
     </section> <!-- end of command-shutdown -->
 
 
-
+      <section id="command-version-get">
+        <title>version-get</title>
+        <para>
+          The <emphasis>version-get</emphasis> command returns on the control
+          channel what the command line <command>-v</command> argument
+          displays with in arguments the extended version, i.e., what
+          the command line <command>-V</command> argument displays. This command
+          does not take any parameters.
+        </para>
+<screen>
+{
+    "command": "version-get"
+}
+</screen>
+      </section> <!-- end of command-version-get -->
 
 
     </section> <!-- end of commands supported by both servers -->
     </section> <!-- end of commands supported by both servers -->
 
 

+ 4 - 2
doc/guide/dhcp4-srv.xml

@@ -195,7 +195,7 @@ opening curly bracket (or brace). Each configuration consists of
 one or more objects. In this specific example, we have only one
 one or more objects. In this specific example, we have only one
 object, called Dhcp4. This is a simplified configuration, as usually
 object, called Dhcp4. This is a simplified configuration, as usually
 there will be additional objects, like <command>Logging</command> or
 there will be additional objects, like <command>Logging</command> or
-<command>DhcpDns</command>, but we omit them now for clarity. The Dhcp4
+<command>DhcpDdns</command>, but we omit them now for clarity. The Dhcp4
 configuration starts with the <command>"Dhcp4": {</command> line
 configuration starts with the <command>"Dhcp4": {</command> line
 and ends with the corresponding closing brace (in the above example,
 and ends with the corresponding closing brace (in the above example,
 the brace after the last comment).  Everything defined between those
 the brace after the last comment).  Everything defined between those
@@ -2475,7 +2475,7 @@ It is merely echoed by the server
      indicates that the server will use the "client identifier" for lease
      indicates that the server will use the "client identifier" for lease
      lookups and "chaddr" if the first lookup returns no results. The
      lookups and "chaddr" if the first lookup returns no results. The
      <command>false</command> means that the server will only
      <command>false</command> means that the server will only
-     use the "chaddr" to search for client"s lease. Whether the DHCID for
+     use the "chaddr" to search for client's lease. Whether the DHCID for
      DNS updates is generated from the "client identifier" or "chaddr" is
      DNS updates is generated from the "client identifier" or "chaddr" is
      controlled through the same parameter accordingly.</para>
      controlled through the same parameter accordingly.</para>
 
 
@@ -3723,12 +3723,14 @@ src/lib/dhcpsrv/cfg_host_operations.cc -->
 
 
       <para>The DHCPv4 server supports the following operational commands:
       <para>The DHCPv4 server supports the following operational commands:
         <itemizedlist>
         <itemizedlist>
+            <listitem>build-report</listitem>
             <listitem>config-get</listitem>
             <listitem>config-get</listitem>
             <listitem>config-write</listitem>
             <listitem>config-write</listitem>
             <listitem>leases-reclaim</listitem>
             <listitem>leases-reclaim</listitem>
             <listitem>list-commands</listitem>
             <listitem>list-commands</listitem>
             <listitem>set-config</listitem>
             <listitem>set-config</listitem>
             <listitem>shutdown</listitem>
             <listitem>shutdown</listitem>
+            <listitem>version-get</listitem>
         </itemizedlist>
         </itemizedlist>
          as described in <xref linkend="commands-common"/>.  In addition,
          as described in <xref linkend="commands-common"/>.  In addition,
          it supports the following statistics related commands:
          it supports the following statistics related commands:

+ 4 - 2
doc/guide/dhcp6-srv.xml

@@ -196,7 +196,7 @@ opening curly bracket (or brace). Each configuration consists of
 one or more objects. In this specific example, we have only one
 one or more objects. In this specific example, we have only one
 object, called Dhcp6. This is a simplified configuration, as usually
 object, called Dhcp6. This is a simplified configuration, as usually
 there will be additional objects, like <command>Logging</command> or
 there will be additional objects, like <command>Logging</command> or
-<command>DhcpDns</command>, but we omit them now for clarity. The Dhcp6
+<command>DhcpDdns</command>, but we omit them now for clarity. The Dhcp6
 configuration starts with the <command>"Dhcp6": {</command> line
 configuration starts with the <command>"Dhcp6": {</command> line
 and ends with the corresponding closing brace (in the above example,
 and ends with the corresponding closing brace (in the above example,
 the brace after the last comment).  Everything defined between those
 the brace after the last comment).  Everything defined between those
@@ -2892,7 +2892,7 @@ should include options from the isc option space:
     <userinput>"option-data": [
     <userinput>"option-data": [
     {
     {
         "name": "vendor-opts",
         "name": "vendor-opts",
-        "data": 4491"
+        "data": 4491
     },
     },
     {
     {
         "name": "tftp-servers",
         "name": "tftp-servers",
@@ -4131,12 +4131,14 @@ If not specified, the default value is:
 
 
       <para>The DHCPv6 server supports the following operational commands:
       <para>The DHCPv6 server supports the following operational commands:
         <itemizedlist>
         <itemizedlist>
+            <listitem>build-report</listitem>
             <listitem>config-get</listitem>
             <listitem>config-get</listitem>
             <listitem>config-write</listitem>
             <listitem>config-write</listitem>
             <listitem>leases-reclaim</listitem>
             <listitem>leases-reclaim</listitem>
             <listitem>list-commands</listitem>
             <listitem>list-commands</listitem>
             <listitem>set-config</listitem>
             <listitem>set-config</listitem>
             <listitem>shutdown</listitem>
             <listitem>shutdown</listitem>
+            <listitem>version-get</listitem>
         </itemizedlist>
         </itemizedlist>
          as described in <xref linkend="commands-common"/>.  In addition,
          as described in <xref linkend="commands-common"/>.  In addition,
          it supports the following statistics related commands:
          it supports the following statistics related commands:

+ 20 - 0
src/bin/agent/ca_controller.cc

@@ -8,6 +8,7 @@
 
 
 #include <agent/ca_controller.h>
 #include <agent/ca_controller.h>
 #include <agent/ca_process.h>
 #include <agent/ca_process.h>
+#include <agent/ca_command_mgr.h>
 #include <agent/parser_context.h>
 #include <agent/parser_context.h>
 
 
 using namespace isc::process;
 using namespace isc::process;
@@ -47,6 +48,25 @@ CtrlAgentController::parseFile(const std::string& name) {
     return (parser.parseFile(name, ParserContext::PARSER_AGENT));
     return (parser.parseFile(name, ParserContext::PARSER_AGENT));
 }
 }
 
 
+void
+CtrlAgentController::registerCommands() {
+    CtrlAgentCommandMgr::instance().registerCommand(VERSION_GET_COMMAND,
+        boost::bind(&DControllerBase::versionGetHandler, this, _1, _2));
+
+    CtrlAgentCommandMgr::instance().registerCommand(BUILD_REPORT_COMMAND,
+        boost::bind(&DControllerBase::buildReportHandler, this, _1, _2));
+
+    CtrlAgentCommandMgr::instance().registerCommand(SHUT_DOWN_COMMAND,
+        boost::bind(&DControllerBase::shutdownHandler, this, _1, _2));
+}
+
+void
+CtrlAgentController::deregisterCommands() {
+    CtrlAgentCommandMgr::instance().deregisterCommand(VERSION_GET_COMMAND);
+    CtrlAgentCommandMgr::instance().deregisterCommand(BUILD_REPORT_COMMAND);
+    CtrlAgentCommandMgr::instance().deregisterCommand(SHUT_DOWN_COMMAND);
+}
+
 CtrlAgentController::CtrlAgentController()
 CtrlAgentController::CtrlAgentController()
     : DControllerBase(agent_app_name_, agent_bin_name_) {
     : DControllerBase(agent_app_name_, agent_bin_name_) {
 }
 }

+ 17 - 2
src/bin/agent/ca_controller.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // 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
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -47,6 +47,19 @@ public:
     isc::data::ConstElementPtr
     isc::data::ConstElementPtr
     parseFile(const std::string& name);
     parseFile(const std::string& name);
 
 
+    /// @brief Register commands.
+    ///
+    /// For all commands in the commands_ set at the exception of
+    /// list-commands register the command with the generic
+    /// @ref isc::process::DControllerBase::executeCommand() handler.
+    void registerCommands();
+
+    /// @brief Deregister commands.
+    ///
+    /// For all commands in the commands_ set at the exception of
+    /// list-commands deregister the command.
+    void deregisterCommands();
+
 private:
 private:
 
 
     /// @brief Creates an instance of the Control Agent application
     /// @brief Creates an instance of the Control Agent application
@@ -64,9 +77,11 @@ private:
     /// @brief Constructor is declared private to maintain the integrity of
     /// @brief Constructor is declared private to maintain the integrity of
     /// the singleton instance.
     /// the singleton instance.
     CtrlAgentController();
     CtrlAgentController();
-
 };
 };
 
 
+// @Defines a shared pointer to CtrlAgentController
+typedef boost::shared_ptr<CtrlAgentController> CtrlAgentControllerPtr;
+
 } // namespace isc::agent
 } // namespace isc::agent
 } // namespace isc
 } // namespace isc
 
 

+ 19 - 8
src/bin/agent/ca_process.cc

@@ -6,6 +6,7 @@
 
 
 #include <config.h>
 #include <config.h>
 #include <agent/ca_process.h>
 #include <agent/ca_process.h>
+#include <agent/ca_controller.h>
 #include <agent/ca_response_creator_factory.h>
 #include <agent/ca_response_creator_factory.h>
 #include <agent/ca_log.h>
 #include <agent/ca_log.h>
 #include <asiolink/io_address.h>
 #include <asiolink/io_address.h>
@@ -47,13 +48,20 @@ CtrlAgentProcess::run() {
 
 
     try {
     try {
 
 
+        // Register commands.
+        CtrlAgentControllerPtr controller =
+            boost::dynamic_pointer_cast<CtrlAgentController>(
+                CtrlAgentController::instance());
+        controller->registerCommands();
+
         // Create response creator factory first. It will be used to generate
         // Create response creator factory first. It will be used to generate
         // response creators. Each response creator will be used to generate
         // response creators. Each response creator will be used to generate
         // answer to specific request.
         // answer to specific request.
         HttpResponseCreatorFactoryPtr rcf(new CtrlAgentResponseCreatorFactory());
         HttpResponseCreatorFactoryPtr rcf(new CtrlAgentResponseCreatorFactory());
 
 
         DCfgContextBasePtr base_ctx = getCfgMgr()->getContext();
         DCfgContextBasePtr base_ctx = getCfgMgr()->getContext();
-        CtrlAgentCfgContextPtr ctx = boost::dynamic_pointer_cast<CtrlAgentCfgContext>(base_ctx);
+        CtrlAgentCfgContextPtr ctx =
+            boost::dynamic_pointer_cast<CtrlAgentCfgContext>(base_ctx);
         if (!ctx) {
         if (!ctx) {
             isc_throw(Unexpected, "Interal logic error: bad context type");
             isc_throw(Unexpected, "Interal logic error: bad context type");
         }
         }
@@ -99,6 +107,16 @@ CtrlAgentProcess::run() {
                   "Process run method failed: " << ex.what());
                   "Process run method failed: " << ex.what());
     }
     }
 
 
+    try {
+        // Deregister commands.
+        CtrlAgentControllerPtr controller =
+            boost::dynamic_pointer_cast<CtrlAgentController>(
+                CtrlAgentController::instance());
+        controller->deregisterCommands();
+    } catch (const std::exception&) {
+        // What to do? Simply ignore...
+    }
+
     LOG_DEBUG(agent_logger, DBGLVL_START_SHUT, CTRL_AGENT_RUN_EXIT);
     LOG_DEBUG(agent_logger, DBGLVL_START_SHUT, CTRL_AGENT_RUN_EXIT);
 }
 }
 
 
@@ -118,13 +136,6 @@ CtrlAgentProcess::configure(isc::data::ConstElementPtr config_set,
     return (answer);
     return (answer);
 }
 }
 
 
-isc::data::ConstElementPtr
-CtrlAgentProcess::command(const std::string& command,
-                          isc::data::ConstElementPtr /*args*/) {
-    return (isc::config::createAnswer(COMMAND_INVALID, "Unrecognized command: "
-                                      + command));
-}
-
 
 
 CtrlAgentCfgMgrPtr
 CtrlAgentCfgMgrPtr
 CtrlAgentProcess::getCtrlAgentCfgMgr() {
 CtrlAgentProcess::getCtrlAgentCfgMgr() {

+ 0 - 20
src/bin/agent/ca_process.h

@@ -87,26 +87,6 @@ public:
     configure(isc::data::ConstElementPtr config_set,
     configure(isc::data::ConstElementPtr config_set,
               bool check_only = false);
               bool check_only = false);
 
 
-    /// @brief Processes the given command.
-    ///
-    /// This method is called to execute any custom commands supported by the
-    /// process. This method must not throw, it should catch any processing
-    /// errors and return a success or failure answer as described below.
-    ///
-    /// @param command is a string label representing the command to execute.
-    /// @param args is a set of arguments (if any) required for the given
-    /// command.
-    /// @return an Element that contains the results of command composed
-    /// of an integer status value:
-    ///
-    /// - COMMAND_SUCCESS indicates a command was successful.
-    /// - COMMAND_ERROR indicates a valid command failed execute.
-    /// - COMMAND_INVALID indicates a command is not valid.
-    ///
-    /// and a string explanation of the outcome.
-    virtual isc::data::ConstElementPtr
-    command(const std::string& command, isc::data::ConstElementPtr args);
-
     /// @brief Returns a pointer to the configuration manager.
     /// @brief Returns a pointer to the configuration manager.
     CtrlAgentCfgMgrPtr getCtrlAgentCfgMgr();
     CtrlAgentCfgMgrPtr getCtrlAgentCfgMgr();
 };
 };

+ 0 - 13
src/bin/d2/d2_process.cc

@@ -362,19 +362,6 @@ D2Process::reconfigureQueueMgr() {
     }
     }
 }
 }
 
 
-isc::data::ConstElementPtr
-D2Process::command(const std::string& command,
-                   isc::data::ConstElementPtr args) {
-    // @todo This is the initial implementation.  If and when D2 is extended
-    // to support its own commands, this implementation must change. Otherwise
-    // it should reject all commands as it does now.
-    LOG_DEBUG(d2_logger, DBGLVL_TRACE_BASIC, DHCP_DDNS_COMMAND)
-        .arg(command).arg(args ? args->str() : "(no args)");
-
-    return (isc::config::createAnswer(COMMAND_INVALID, "Unrecognized command: "
-                                      + command));
-}
-
 D2Process::~D2Process() {
 D2Process::~D2Process() {
 };
 };
 
 

+ 0 - 14
src/bin/d2/d2_process.h

@@ -161,20 +161,6 @@ public:
     configure(isc::data::ConstElementPtr config_set,
     configure(isc::data::ConstElementPtr config_set,
               bool check_only = false);
               bool check_only = false);
 
 
-    /// @brief Processes the given command.
-    ///
-    /// This method is called to execute any custom commands supported by the
-    /// process. This method must not throw, it should catch any processing
-    /// errors and return a success or failure answer as described below.
-    ///
-    /// @param command is a string label representing the command to execute.
-    /// @param args is a set of arguments (if any) required for the given
-    /// command. It can be a NULL pointer if no arguments exist for a command.
-    /// @return an Element that contains the results of command composed
-    /// of an integer status value (0 means successful, non-zero means failure),
-    /// and a string explanation of the outcome.
-    virtual isc::data::ConstElementPtr command(const std::string& command,
-                                               isc::data::ConstElementPtr args);
     /// @brief Destructor
     /// @brief Destructor
     virtual ~D2Process();
     virtual ~D2Process();
 
 

+ 0 - 29
src/bin/d2/tests/d2_controller_unittests.cc

@@ -199,35 +199,6 @@ TEST_F(D2ControllerTest, configUpdateTests) {
     EXPECT_EQ(1, rcode);
     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.
-/// 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(D2ControllerTest, 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 = 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 = executeCommand(SHUT_DOWN_COMMAND, arg_set);
-    isc::config::parseAnswer(rcode, answer);
-    EXPECT_EQ(COMMAND_SUCCESS, rcode);
-}
-
 // Tests that the original configuration is retained after a SIGHUP triggered
 // Tests that the original configuration is retained after a SIGHUP triggered
 // reconfiguration fails due to invalid config content.
 // reconfiguration fails due to invalid config content.
 TEST_F(D2ControllerTest, invalidConfigReload) {
 TEST_F(D2ControllerTest, invalidConfigReload) {

+ 0 - 14
src/bin/d2/tests/d2_process_unittests.cc

@@ -394,20 +394,6 @@ TEST_F(D2ProcessTest, badConfigureRecovery) {
     EXPECT_FALSE(getReconfQueueFlag());
     EXPECT_FALSE(getReconfQueueFlag());
 }
 }
 
 
-/// @brief Verifies basic command method behavior.
-/// @TODO IF the D2Process is extended to support extra commands this testing
-/// will need to augmented accordingly.
-TEST_F(D2ProcessTest, command) {
-    // Verify that the process will process unsupported command and
-    // return a failure response.
-    int rcode = -1;
-    string args = "{ \"arg1\": 77 } ";
-    isc::data::ElementPtr json = isc::data::Element::fromJSON(args);
-    isc::data::ConstElementPtr answer = command("bogus_command", json);
-    parseAnswer(rcode, answer);
-    EXPECT_EQ(COMMAND_INVALID, rcode);
-}
-
 /// @brief Tests shutdown command argument parsing
 /// @brief Tests shutdown command argument parsing
 /// The shutdown command supports an optional "type" argument. This test
 /// The shutdown command supports an optional "type" argument. This test
 /// checks that for valid values, the shutdown() method: sets the shutdown
 /// checks that for valid values, the shutdown() method: sets the shutdown

+ 34 - 0
src/bin/dhcp4/ctrl_dhcp4_srv.cc

@@ -15,6 +15,7 @@
 #include <dhcpsrv/cfg_db_access.h>
 #include <dhcpsrv/cfg_db_access.h>
 #include <config/command_mgr.h>
 #include <config/command_mgr.h>
 #include <stats/stats_mgr.h>
 #include <stats/stats_mgr.h>
+#include <cfgrpt/config_report.h>
 
 
 using namespace isc::data;
 using namespace isc::data;
 using namespace isc::hooks;
 using namespace isc::hooks;
@@ -206,6 +207,25 @@ ControlledDhcpv4Srv::commandSetConfigHandler(const string&,
 }
 }
 
 
 ConstElementPtr
 ConstElementPtr
+ControlledDhcpv4Srv::commandVersionGetHandler(const string&, ConstElementPtr) {
+    ElementPtr extended = Element::create(Dhcpv4Srv::getVersion(true));
+    ElementPtr arguments = Element::createMap();
+    arguments->set("extended", extended);
+    ConstElementPtr answer = isc::config::createAnswer(0,
+                                Dhcpv4Srv::getVersion(false),
+                                arguments);
+    return (answer);
+}
+
+ConstElementPtr
+ControlledDhcpv4Srv::commandBuildReportHandler(const string&,
+                                               ConstElementPtr) {
+    ConstElementPtr answer =
+        isc::config::createAnswer(0, isc::detail::getConfigReport());
+    return (answer);
+}
+
+ConstElementPtr
 ControlledDhcpv4Srv::commandLeasesReclaimHandler(const string&,
 ControlledDhcpv4Srv::commandLeasesReclaimHandler(const string&,
                                                  ConstElementPtr args) {
                                                  ConstElementPtr args) {
     int status_code = 1;
     int status_code = 1;
@@ -262,6 +282,12 @@ ControlledDhcpv4Srv::processCommand(const string& command,
         } else if (command == "config-get") {
         } else if (command == "config-get") {
             return (srv->commandConfigGetHandler(command, args));
             return (srv->commandConfigGetHandler(command, args));
 
 
+        } else if (command == "version-get") {
+            return (srv->commandVersionGetHandler(command, args));
+
+        } else if (command == "build-report") {
+            return (srv->commandBuildReportHandler(command, args));
+
         } else if (command == "leases-reclaim") {
         } else if (command == "leases-reclaim") {
             return (srv->commandLeasesReclaimHandler(command, args));
             return (srv->commandLeasesReclaimHandler(command, args));
 
 
@@ -398,6 +424,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/)
 
 
     // These are the commands always supported by the DHCPv4 server.
     // These are the commands always supported by the DHCPv4 server.
     // Please keep the list in alphabetic order.
     // Please keep the list in alphabetic order.
+    CommandMgr::instance().registerCommand("build-report",
+        boost::bind(&ControlledDhcpv4Srv::commandBuildReportHandler, this, _1, _2));
+
     CommandMgr::instance().registerCommand("config-get",
     CommandMgr::instance().registerCommand("config-get",
         boost::bind(&ControlledDhcpv4Srv::commandConfigGetHandler, this, _1, _2));
         boost::bind(&ControlledDhcpv4Srv::commandConfigGetHandler, this, _1, _2));
 
 
@@ -418,6 +447,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/)
     CommandMgr::instance().registerCommand("shutdown",
     CommandMgr::instance().registerCommand("shutdown",
         boost::bind(&ControlledDhcpv4Srv::commandShutdownHandler, this, _1, _2));
         boost::bind(&ControlledDhcpv4Srv::commandShutdownHandler, this, _1, _2));
 
 
+    CommandMgr::instance().registerCommand("version-get",
+        boost::bind(&ControlledDhcpv4Srv::commandVersionGetHandler, this, _1, _2));
+
     // Register statistic related commands
     // Register statistic related commands
     CommandMgr::instance().registerCommand("statistic-get",
     CommandMgr::instance().registerCommand("statistic-get",
         boost::bind(&StatsMgr::statisticGetHandler, _1, _2));
         boost::bind(&StatsMgr::statisticGetHandler, _1, _2));
@@ -457,6 +489,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
         CommandMgr::instance().closeCommandSocket();
         CommandMgr::instance().closeCommandSocket();
 
 
         // Deregister any registered commands (please keep in alphabetic order)
         // Deregister any registered commands (please keep in alphabetic order)
+        CommandMgr::instance().deregisterCommand("build-report");
         CommandMgr::instance().deregisterCommand("config-get");
         CommandMgr::instance().deregisterCommand("config-get");
         CommandMgr::instance().deregisterCommand("config-write");
         CommandMgr::instance().deregisterCommand("config-write");
         CommandMgr::instance().deregisterCommand("leases-reclaim");
         CommandMgr::instance().deregisterCommand("leases-reclaim");
@@ -469,6 +502,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
         CommandMgr::instance().deregisterCommand("statistic-remove-all");
         CommandMgr::instance().deregisterCommand("statistic-remove-all");
         CommandMgr::instance().deregisterCommand("statistic-reset");
         CommandMgr::instance().deregisterCommand("statistic-reset");
         CommandMgr::instance().deregisterCommand("statistic-reset-all");
         CommandMgr::instance().deregisterCommand("statistic-reset-all");
+        CommandMgr::instance().deregisterCommand("version-get");
 
 
     } catch (...) {
     } catch (...) {
         // Don't want to throw exceptions from the destructor. The server
         // Don't want to throw exceptions from the destructor. The server

+ 25 - 0
src/bin/dhcp4/ctrl_dhcp4_srv.h

@@ -187,6 +187,31 @@ private:
     commandSetConfigHandler(const std::string& command,
     commandSetConfigHandler(const std::string& command,
                             isc::data::ConstElementPtr args);
                             isc::data::ConstElementPtr args);
 
 
+    /// @brief handler for processing 'version-get' command
+    ///
+    /// This handler processes version-get command, which returns
+    /// over the control channel the -v and -V command line arguments.
+    /// @param command (parameter ignored)
+    /// @param args (parameter ignored) 
+    ///
+    /// @return status of the command with the version in text and
+    /// the extended version in arguments.
+    isc::data::ConstElementPtr
+    commandVersionGetHandler(const std::string& command,
+                             isc::data::ConstElementPtr args);
+
+    /// @brief handler for processing 'build-report' command
+    ///
+    /// This handler processes build-report command, which returns
+    /// over the control channel the -W command line argument.
+    /// @param command (parameter ignored)
+    /// @param args (parameter ignored) 
+    ///
+    /// @return status of the command with the config report
+    isc::data::ConstElementPtr
+    commandBuildReportHandler(const std::string& command,
+                              isc::data::ConstElementPtr args);
+
     /// @brief Handler for processing 'leases-reclaim' command
     /// @brief Handler for processing 'leases-reclaim' command
     ///
     ///
     /// This handler processes leases-reclaim command, which triggers
     /// This handler processes leases-reclaim command, which triggers

+ 29 - 0
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc

@@ -381,12 +381,20 @@ TEST_F(CtrlChannelDhcpv4SrvTest, commandsRegistration) {
     std::string command_list = answer->get("arguments")->str();
     std::string command_list = answer->get("arguments")->str();
 
 
     EXPECT_TRUE(command_list.find("\"list-commands\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"list-commands\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"build-report\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"config-get\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"config-write\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"leases-reclaim\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"libreload\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"set-config\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"shutdown\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset-all\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"version-get\"") != string::npos);
 
 
     // Ok, and now delete the server. It should deregister its commands.
     // Ok, and now delete the server. It should deregister its commands.
     server_.reset();
     server_.reset();
@@ -482,6 +490,25 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaim) {
     EXPECT_TRUE(lease1->stateExpiredReclaimed());
     EXPECT_TRUE(lease1->stateExpiredReclaimed());
 }
 }
 
 
+// This test verifies that the DHCP server handles version-get commands
+TEST_F(CtrlChannelDhcpv4SrvTest, getversion) {
+    createUnixChannelServer();
+
+    std::string response;
+
+    // Send the version-get command
+    sendUnixCommand("{ \"command\": \"version-get\" }", response);
+    EXPECT_TRUE(response.find("\"result\": 0") != string::npos);
+    EXPECT_TRUE(response.find("log4cplus") != string::npos);
+    EXPECT_FALSE(response.find("GTEST_VERSION") != string::npos);
+
+    // Send the build-report command
+    sendUnixCommand("{ \"command\": \"build-report\" }", response);
+    EXPECT_TRUE(response.find("\"result\": 0") != string::npos);
+    EXPECT_TRUE(response.find("GTEST_VERSION") != string::npos);
+}
+
+// This test verifies that the DHCP server immediately removed expired
 // This test verifies that the DHCP server immediately removed expired
 // This test verifies that the DHCP server immediately removed expired
 // leases on leases-reclaim command with remove = true
 // leases on leases-reclaim command with remove = true
 TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaimRemove) {
 TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaimRemove) {
@@ -722,6 +749,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, listCommands) {
     EXPECT_NO_THROW(rsp = Element::fromJSON(response));
     EXPECT_NO_THROW(rsp = Element::fromJSON(response));
 
 
     // We expect the server to report at least the following commands:
     // We expect the server to report at least the following commands:
+    checkListCommands(rsp, "build-report");
     checkListCommands(rsp, "config-get");
     checkListCommands(rsp, "config-get");
     checkListCommands(rsp, "config-write");
     checkListCommands(rsp, "config-write");
     checkListCommands(rsp, "list-commands");
     checkListCommands(rsp, "list-commands");
@@ -735,6 +763,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, listCommands) {
     checkListCommands(rsp, "statistic-remove-all");
     checkListCommands(rsp, "statistic-remove-all");
     checkListCommands(rsp, "statistic-reset");
     checkListCommands(rsp, "statistic-reset");
     checkListCommands(rsp, "statistic-reset-all");
     checkListCommands(rsp, "statistic-reset-all");
+    checkListCommands(rsp, "version-get");
 }
 }
 
 
 // Tests if the server returns its configuration using config-get.
 // Tests if the server returns its configuration using config-get.

+ 34 - 1
src/bin/dhcp6/ctrl_dhcp6_srv.cc

@@ -16,6 +16,7 @@
 #include <dhcp6/json_config_parser.h>
 #include <dhcp6/json_config_parser.h>
 #include <hooks/hooks_manager.h>
 #include <hooks/hooks_manager.h>
 #include <stats/stats_mgr.h>
 #include <stats/stats_mgr.h>
+#include <cfgrpt/config_report.h>
 
 
 using namespace isc::config;
 using namespace isc::config;
 using namespace isc::data;
 using namespace isc::data;
@@ -212,6 +213,24 @@ ControlledDhcpv6Srv::commandSetConfigHandler(const string&,
 
 
 
 
 ConstElementPtr
 ConstElementPtr
+ControlledDhcpv6Srv::commandVersionGetHandler(const string&, ConstElementPtr) {
+    ElementPtr extended = Element::create(Dhcpv6Srv::getVersion(true));
+    ElementPtr arguments = Element::createMap();
+    arguments->set("extended", extended);
+    ConstElementPtr answer = isc::config::createAnswer(0,
+                                Dhcpv6Srv::getVersion(false),
+                                arguments);
+    return (answer);
+}
+
+ConstElementPtr
+ControlledDhcpv6Srv::commandBuildReportHandler(const string&, ConstElementPtr) {
+    ConstElementPtr answer =
+        isc::config::createAnswer(0, isc::detail::getConfigReport());
+    return (answer);
+}
+
+ConstElementPtr
 ControlledDhcpv6Srv::commandLeasesReclaimHandler(const string&,
 ControlledDhcpv6Srv::commandLeasesReclaimHandler(const string&,
                                                  ConstElementPtr args) {
                                                  ConstElementPtr args) {
     int status_code = 1;
     int status_code = 1;
@@ -268,6 +287,12 @@ ControlledDhcpv6Srv::processCommand(const std::string& command,
         } else if (command == "config-get") {
         } else if (command == "config-get") {
             return (srv->commandConfigGetHandler(command, args));
             return (srv->commandConfigGetHandler(command, args));
 
 
+        } else if (command == "version-get") {
+            return (srv->commandVersionGetHandler(command, args));
+
+        } else if (command == "build-report") {
+            return (srv->commandBuildReportHandler(command, args));
+
         } else if (command == "leases-reclaim") {
         } else if (command == "leases-reclaim") {
             return (srv->commandLeasesReclaimHandler(command, args));
             return (srv->commandLeasesReclaimHandler(command, args));
 
 
@@ -427,6 +452,9 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t port)
 
 
     // These are the commands always supported by the DHCPv6 server.
     // These are the commands always supported by the DHCPv6 server.
     // Please keep the list in alphabetic order.
     // Please keep the list in alphabetic order.
+    CommandMgr::instance().registerCommand("build-report",
+        boost::bind(&ControlledDhcpv6Srv::commandBuildReportHandler, this, _1, _2));
+
     CommandMgr::instance().registerCommand("config-get",
     CommandMgr::instance().registerCommand("config-get",
         boost::bind(&ControlledDhcpv6Srv::commandConfigGetHandler, this, _1, _2));
         boost::bind(&ControlledDhcpv6Srv::commandConfigGetHandler, this, _1, _2));
 
 
@@ -447,6 +475,9 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t port)
     CommandMgr::instance().registerCommand("shutdown",
     CommandMgr::instance().registerCommand("shutdown",
         boost::bind(&ControlledDhcpv6Srv::commandShutdownHandler, this, _1, _2));
         boost::bind(&ControlledDhcpv6Srv::commandShutdownHandler, this, _1, _2));
 
 
+    CommandMgr::instance().registerCommand("version-get",
+        boost::bind(&ControlledDhcpv6Srv::commandVersionGetHandler, this, _1, _2));
+
     // Register statistic related commands
     // Register statistic related commands
     CommandMgr::instance().registerCommand("statistic-get",
     CommandMgr::instance().registerCommand("statistic-get",
         boost::bind(&StatsMgr::statisticGetHandler, _1, _2));
         boost::bind(&StatsMgr::statisticGetHandler, _1, _2));
@@ -485,10 +516,11 @@ ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
         CommandMgr::instance().closeCommandSocket();
         CommandMgr::instance().closeCommandSocket();
 
 
         // Deregister any registered commands (please keep in alphabetic order)
         // Deregister any registered commands (please keep in alphabetic order)
+        CommandMgr::instance().deregisterCommand("build-report");
         CommandMgr::instance().deregisterCommand("config-get");
         CommandMgr::instance().deregisterCommand("config-get");
         CommandMgr::instance().deregisterCommand("config-write");
         CommandMgr::instance().deregisterCommand("config-write");
-        CommandMgr::instance().deregisterCommand("libreload");
         CommandMgr::instance().deregisterCommand("leases-reclaim");
         CommandMgr::instance().deregisterCommand("leases-reclaim");
+        CommandMgr::instance().deregisterCommand("libreload");
         CommandMgr::instance().deregisterCommand("set-config");
         CommandMgr::instance().deregisterCommand("set-config");
         CommandMgr::instance().deregisterCommand("shutdown");
         CommandMgr::instance().deregisterCommand("shutdown");
         CommandMgr::instance().deregisterCommand("statistic-get");
         CommandMgr::instance().deregisterCommand("statistic-get");
@@ -497,6 +529,7 @@ ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
         CommandMgr::instance().deregisterCommand("statistic-remove-all");
         CommandMgr::instance().deregisterCommand("statistic-remove-all");
         CommandMgr::instance().deregisterCommand("statistic-reset");
         CommandMgr::instance().deregisterCommand("statistic-reset");
         CommandMgr::instance().deregisterCommand("statistic-reset-all");
         CommandMgr::instance().deregisterCommand("statistic-reset-all");
+        CommandMgr::instance().deregisterCommand("version-get");
 
 
     } catch (...) {
     } catch (...) {
         // Don't want to throw exceptions from the destructor. The server
         // Don't want to throw exceptions from the destructor. The server

+ 25 - 0
src/bin/dhcp6/ctrl_dhcp6_srv.h

@@ -187,6 +187,31 @@ private:
     commandSetConfigHandler(const std::string& command,
     commandSetConfigHandler(const std::string& command,
                             isc::data::ConstElementPtr args);
                             isc::data::ConstElementPtr args);
 
 
+    /// @brief handler for processing 'version-get' command
+    ///
+    /// This handler processes version-get command, which returns
+    /// over the control channel the -v and -V command line arguments.
+    /// @param command (parameter ignored)
+    /// @param args (parameter ignored) 
+    ///
+    /// @return status of the command with the version in text and
+    /// the extended version in arguments.
+    isc::data::ConstElementPtr
+    commandVersionGetHandler(const std::string& command,
+                             isc::data::ConstElementPtr args);
+
+    /// @brief handler for processing 'build-report' command
+    ///
+    /// This handler processes build-report command, which returns
+    /// over the control channel the -W command line argument.
+    /// @param command (parameter ignored)
+    /// @param args (parameter ignored) 
+    ///
+    /// @return status of the command with the config report
+    isc::data::ConstElementPtr
+    commandBuildReportHandler(const std::string& command,
+                              isc::data::ConstElementPtr args);
+
     /// @brief Handler for processing 'leases-reclaim' command
     /// @brief Handler for processing 'leases-reclaim' command
     ///
     ///
     /// This handler processes leases-reclaim command, which triggers
     /// This handler processes leases-reclaim command, which triggers

+ 26 - 0
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc

@@ -602,12 +602,20 @@ TEST_F(CtrlDhcpv6SrvTest, commandsRegistration) {
     std::string command_list = answer->get("arguments")->str();
     std::string command_list = answer->get("arguments")->str();
 
 
     EXPECT_TRUE(command_list.find("\"list-commands\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"list-commands\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"build-report\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"config-get\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"config-write\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"leases-reclaim\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"libreload\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"set-config\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"shutdown\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-get-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-remove-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset-all\"") != string::npos);
     EXPECT_TRUE(command_list.find("\"statistic-reset-all\"") != string::npos);
+    EXPECT_TRUE(command_list.find("\"version-get\"") != string::npos);
 
 
     // Ok, and now delete the server. It should deregister its commands.
     // Ok, and now delete the server. It should deregister its commands.
     srv.reset();
     srv.reset();
@@ -645,6 +653,24 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelShutdown) {
     EXPECT_EQ("{ \"result\": 0, \"text\": \"Shutting down.\" }",response);
     EXPECT_EQ("{ \"result\": 0, \"text\": \"Shutting down.\" }",response);
 }
 }
 
 
+// This test verifies that the DHCP server handles version-get commands
+TEST_F(CtrlChannelDhcpv6SrvTest, getversion) {
+    createUnixChannelServer();
+
+    std::string response;
+
+    // Send the version-get command
+    sendUnixCommand("{ \"command\": \"version-get\" }", response);
+    EXPECT_TRUE(response.find("\"result\": 0") != string::npos);
+    EXPECT_TRUE(response.find("log4cplus") != string::npos);
+    EXPECT_FALSE(response.find("GTEST_VERSION") != string::npos);
+
+    // Send the build-report command
+    sendUnixCommand("{ \"command\": \"build-report\" }", response);
+    EXPECT_TRUE(response.find("\"result\": 0") != string::npos);
+    EXPECT_TRUE(response.find("GTEST_VERSION") != string::npos);
+}
+
 // This test verifies that the DHCP server immediately reclaims expired
 // This test verifies that the DHCP server immediately reclaims expired
 // leases on leases-reclaim command
 // leases on leases-reclaim command
 TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaim) {
 TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaim) {

+ 1 - 1
src/bin/shell/tests/shell_process_tests.sh.in

@@ -178,6 +178,6 @@ version_test() {
 
 
 version_test "shell.version"
 version_test "shell.version"
 shell_command_test "shell.list-commands" "list-commands" \
 shell_command_test "shell.list-commands" "list-commands" \
-    "[ { \"arguments\": [ \"list-commands\" ], \"result\": 0 } ]" ""
+    "[ { \"arguments\": [ \"build-report\", \"list-commands\", \"shutdown\", \"version-get\" ], \"result\": 0 } ]" ""
 shell_command_test "shell.bogus" "give-me-a-beer" \
 shell_command_test "shell.bogus" "give-me-a-beer" \
     "[ { \"result\": 1, \"text\": \"'give-me-a-beer' command not supported.\" } ]" ""
     "[ { \"result\": 1, \"text\": \"'give-me-a-beer' command not supported.\" } ]" ""

+ 53 - 1
src/lib/cc/command_interpreter.cc

@@ -8,8 +8,9 @@
 
 
 #include <exceptions/exceptions.h>
 #include <exceptions/exceptions.h>
 #include <cc/command_interpreter.h>
 #include <cc/command_interpreter.h>
-#include <string>
 #include <cc/data.h>
 #include <cc/data.h>
+#include <string>
+#include <set>
 
 
 using namespace std;
 using namespace std;
 
 
@@ -171,5 +172,56 @@ parseCommand(ConstElementPtr& arg, ConstElementPtr command) {
     return (cmd->stringValue());
     return (cmd->stringValue());
 }
 }
 
 
+ConstElementPtr
+combineCommandsLists(const ConstElementPtr& response1,
+                     const ConstElementPtr& response2) {
+    // Usually when this method is called there should be two non-null
+    // responses. If there is just a single response, return this
+    // response.
+    if (!response1 && response2) {
+        return (response2);
+
+    } else if (response1 && !response2) {
+        return (response1);
+
+    } else if (!response1 && !response2) {
+        return (ConstElementPtr());
+
+    } else {
+        // Both responses are non-null so we need to combine the lists
+        // of supported commands if the status codes are 0.
+        int status_code;
+        ConstElementPtr args1 = parseAnswer(status_code, response1);
+        if (status_code != 0) {
+            return (response1);
+        }
+
+        ConstElementPtr args2 = parseAnswer(status_code, response2);
+        if (status_code != 0) {
+            return (response2);
+        }
+
+        const std::vector<ElementPtr> vec1 = args1->listValue();
+        const std::vector<ElementPtr> vec2 = args2->listValue();
+
+        // Storing command names in a set guarantees that the non-unique
+        // command names are aggregated.
+        std::set<std::string> combined_set;
+        for (auto v = vec1.cbegin(); v != vec1.cend(); ++v) {
+            combined_set.insert((*v)->stringValue());
+        }
+        for (auto v = vec2.cbegin(); v != vec2.cend(); ++v) {
+            combined_set.insert((*v)->stringValue());
+        }
+
+        // Create a combined list of commands.
+        ElementPtr combined_list = Element::createList();
+        for (auto s = combined_set.cbegin(); s != combined_set.cend(); ++s) {
+            combined_list->add(Element::create(*s));
+        }
+        return (createAnswer(CONTROL_RESULT_SUCCESS, combined_list));
+    }
+}
+
 }
 }
 }
 }

+ 17 - 0
src/lib/cc/command_interpreter.h

@@ -126,6 +126,23 @@ isc::data::ConstElementPtr createCommand(const std::string& command,
 std::string parseCommand(isc::data::ConstElementPtr& arg,
 std::string parseCommand(isc::data::ConstElementPtr& arg,
                          isc::data::ConstElementPtr command);
                          isc::data::ConstElementPtr command);
 
 
+/// @brief Combines lists of commands carried in two responses.
+///
+/// This method is used to combine list of commands returned by the
+/// two command managers.
+///
+/// If the same command appears in two responses only a single
+/// instance is returned in the combined response.
+///
+/// @param response1 First command response.
+/// @param response2 Second command response.
+///
+/// @return Pointer to the 'list-commands' response holding combined
+/// list of commands.
+isc::data::ConstElementPtr
+combineCommandsLists(const isc::data::ConstElementPtr& response1,
+                     const isc::data::ConstElementPtr& response2);
+
 }; // end of namespace isc::config
 }; // end of namespace isc::config
 }; // end of namespace isc
 }; // end of namespace isc
 
 

+ 0 - 52
src/lib/config/base_command_mgr.cc

@@ -8,7 +8,6 @@
 #include <config/base_command_mgr.h>
 #include <config/base_command_mgr.h>
 #include <config/config_log.h>
 #include <config/config_log.h>
 #include <boost/bind.hpp>
 #include <boost/bind.hpp>
-#include <set>
 
 
 using namespace isc::data;
 using namespace isc::data;
 
 
@@ -88,57 +87,6 @@ BaseCommandMgr::processCommand(const isc::data::ConstElementPtr& cmd) {
 }
 }
 
 
 ConstElementPtr
 ConstElementPtr
-BaseCommandMgr::combineCommandsLists(const ConstElementPtr& response1,
-                                     const ConstElementPtr& response2) const {
-    // Usually when this method is called there should be two non-null
-    // responses. If there is just a single response, return this
-    // response.
-    if (!response1 && response2) {
-        return (response2);
-
-    } else if (response1 && !response2) {
-        return (response1);
-
-    } else if (!response1 && !response2) {
-        return (ConstElementPtr());
-
-    } else {
-        // Both responses are non-null so we need to combine the lists
-        // of supported commands if the status codes are 0.
-        int status_code;
-        ConstElementPtr args1 = parseAnswer(status_code, response1);
-        if (status_code != 0) {
-            return (response1);
-        }
-
-        ConstElementPtr args2 = parseAnswer(status_code, response2);
-        if (status_code != 0) {
-            return (response2);
-        }
-
-        const std::vector<ElementPtr> vec1 = args1->listValue();
-        const std::vector<ElementPtr> vec2 = args2->listValue();
-
-        // Storing command names in a set guarantees that the non-unique
-        // command names are aggregated.
-        std::set<std::string> combined_set;
-        for (auto v = vec1.cbegin(); v != vec1.cend(); ++v) {
-            combined_set.insert((*v)->stringValue());
-        }
-        for (auto v = vec2.cbegin(); v != vec2.cend(); ++v) {
-            combined_set.insert((*v)->stringValue());
-        }
-
-        // Create a combined list of commands.
-        ElementPtr combined_list = Element::createList();
-        for (auto s = combined_set.cbegin(); s != combined_set.cend(); ++s) {
-            combined_list->add(Element::create(*s));
-        }
-        return (createAnswer(CONTROL_RESULT_SUCCESS, combined_list));
-    }
-}
-
-ConstElementPtr
 BaseCommandMgr::handleCommand(const std::string& cmd_name,
 BaseCommandMgr::handleCommand(const std::string& cmd_name,
                               const ConstElementPtr& params) {
                               const ConstElementPtr& params) {
     auto it = handlers_.find(cmd_name);
     auto it = handlers_.find(cmd_name);

+ 0 - 21
src/lib/config/base_command_mgr.h

@@ -118,27 +118,6 @@ public:
 
 
 protected:
 protected:
 
 
-    /// @brief Combines lists of commands carried in two responses.
-    ///
-    /// This method is used to combine list of commands returned by the
-    /// hook library with the commands supported by the local Command
-    /// Manager. This method should also be used within the hook library
-    /// to combine commands supported by this hook library with the
-    /// commands returned by other hook libraries attached to the server
-    /// at the same time.
-    ///
-    /// If the same command appears in two responses only a single
-    /// instance is returned in the combined response.
-    ///
-    /// @param response1 First command response.
-    /// @param response2 Second command response.
-    ///
-    /// @return Pointer to the 'list-commands' response holding combined
-    /// list of commands.
-    isc::data::ConstElementPtr
-    combineCommandsLists(const isc::data::ConstElementPtr& response1,
-                         const isc::data::ConstElementPtr& response2) const;
-
     /// @brief Handles the command having a given name and arguments.
     /// @brief Handles the command having a given name and arguments.
     ///
     ///
     /// This method can be overridden in the derived classes to provide
     /// This method can be overridden in the derived classes to provide

+ 1 - 1
src/lib/log/logger_impl.cc

@@ -82,7 +82,7 @@ LoggerImpl::~LoggerImpl() {
 std::string
 std::string
 LoggerImpl::getVersion() {
 LoggerImpl::getVersion() {
     std::ostringstream ver;
     std::ostringstream ver;
-    ver << "log4plus ";
+    ver << "log4cplus ";
     ver << log4cplus::versionStr;
     ver << log4cplus::versionStr;
     return (ver.str());
     return (ver.str());
 }
 }

+ 47 - 59
src/lib/process/d_controller.cc

@@ -29,6 +29,9 @@
 #include <sstream>
 #include <sstream>
 #include <unistd.h>
 #include <unistd.h>
 
 
+using namespace isc::data;
+using namespace isc::config;
+
 namespace isc {
 namespace isc {
 namespace process {
 namespace process {
 
 
@@ -54,9 +57,9 @@ DControllerBase::setController(const DControllerBasePtr& controller) {
     controller_ = controller;
     controller_ = controller;
 }
 }
 
 
-isc::data::ConstElementPtr
+ConstElementPtr
 DControllerBase::parseFile(const std::string&) {
 DControllerBase::parseFile(const std::string&) {
-    isc::data::ConstElementPtr elements;
+    ConstElementPtr elements;
     return (elements);
     return (elements);
 }
 }
 
 
@@ -125,8 +128,7 @@ DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
 
 
     // Step 3 is to load configuration from file.
     // Step 3 is to load configuration from file.
     int rcode;
     int rcode;
-    isc::data::ConstElementPtr comment
-        = isc::config::parseAnswer(rcode, configFromFile());
+    ConstElementPtr comment = parseAnswer(rcode, configFromFile());
     if (rcode != 0) {
     if (rcode != 0) {
         LOG_FATAL(dctl_logger, DCTL_CONFIG_FILE_LOAD_FAIL)
         LOG_FATAL(dctl_logger, DCTL_CONFIG_FILE_LOAD_FAIL)
                   .arg(app_name_).arg(comment->stringValue());
                   .arg(app_name_).arg(comment->stringValue());
@@ -169,7 +171,7 @@ DControllerBase::checkConfigOnly() {
             // Basic sanity check: file name must not be empty.
             // Basic sanity check: file name must not be empty.
             isc_throw(InvalidUsage, "JSON configuration file not specified");
             isc_throw(InvalidUsage, "JSON configuration file not specified");
         }
         }
-        isc::data::ConstElementPtr whole_config = parseFile(config_file);
+        ConstElementPtr whole_config = parseFile(config_file);
         if (!whole_config) {
         if (!whole_config) {
             // No fallback to fromJSONFile
             // No fallback to fromJSONFile
             isc_throw(InvalidUsage, "No configuration found");
             isc_throw(InvalidUsage, "No configuration found");
@@ -179,7 +181,7 @@ DControllerBase::checkConfigOnly() {
         }
         }
 
 
         // Check the logic next.
         // Check the logic next.
-        isc::data::ConstElementPtr module_config;
+        ConstElementPtr module_config;
         module_config = whole_config->get(getAppName());
         module_config = whole_config->get(getAppName());
         if (!module_config) {
         if (!module_config) {
             isc_throw(InvalidUsage, "Config file " << config_file <<
             isc_throw(InvalidUsage, "Config file " << config_file <<
@@ -189,10 +191,9 @@ DControllerBase::checkConfigOnly() {
         // Get an application process object.
         // Get an application process object.
         initProcess();
         initProcess();
 
 
-        isc::data::ConstElementPtr answer;
-        answer = checkConfig(module_config);
+        ConstElementPtr answer = checkConfig(module_config);
         int rcode = 0;
         int rcode = 0;
-        answer = isc::config::parseAnswer(rcode, answer);
+        answer = parseAnswer(rcode, answer);
         if (rcode != 0) {
         if (rcode != 0) {
             isc_throw(InvalidUsage, "Error encountered: "
             isc_throw(InvalidUsage, "Error encountered: "
                       << answer->stringValue());
                       << answer->stringValue());
@@ -312,15 +313,15 @@ DControllerBase::initProcess() {
     process_->init();
     process_->init();
 }
 }
 
 
-isc::data::ConstElementPtr
+ConstElementPtr
 DControllerBase::configFromFile() {
 DControllerBase::configFromFile() {
     // Rollback any previous staging configuration. For D2, only a
     // Rollback any previous staging configuration. For D2, only a
     // logger configuration is used here.
     // logger configuration is used here.
     isc::dhcp::CfgMgr::instance().rollback();
     isc::dhcp::CfgMgr::instance().rollback();
     // Will hold configuration.
     // Will hold configuration.
-    isc::data::ConstElementPtr module_config;
+    ConstElementPtr module_config;
     // Will receive configuration result.
     // Will receive configuration result.
-    isc::data::ConstElementPtr answer;
+    ConstElementPtr answer;
     try {
     try {
         std::string config_file = getConfigFile();
         std::string config_file = getConfigFile();
         if (config_file.empty()) {
         if (config_file.empty()) {
@@ -331,10 +332,10 @@ DControllerBase::configFromFile() {
 
 
         // If parseFile returns an empty pointer, then pass the file onto the
         // If parseFile returns an empty pointer, then pass the file onto the
         // original JSON parser.
         // original JSON parser.
-        isc::data::ConstElementPtr whole_config = parseFile(config_file);
+        ConstElementPtr whole_config = parseFile(config_file);
         if (!whole_config) {
         if (!whole_config) {
             // Read contents of the file and parse it as JSON
             // Read contents of the file and parse it as JSON
-            whole_config = isc::data::Element::fromJSONFile(config_file, true);
+            whole_config = Element::fromJSONFile(config_file, true);
         }
         }
 
 
         // Let's configure logging before applying the configuration,
         // Let's configure logging before applying the configuration,
@@ -358,7 +359,7 @@ DControllerBase::configFromFile() {
 
 
         answer = updateConfig(module_config);
         answer = updateConfig(module_config);
         int rcode = 0;
         int rcode = 0;
-        isc::config::parseAnswer(rcode, answer);
+        parseAnswer(rcode, answer);
         if (!rcode) {
         if (!rcode) {
             // Configuration successful, so apply the logging configuration
             // Configuration successful, so apply the logging configuration
             // to log4cplus.
             // to log4cplus.
@@ -370,9 +371,8 @@ DControllerBase::configFromFile() {
         // Rollback logging configuration.
         // Rollback logging configuration.
         isc::dhcp::CfgMgr::instance().rollback();
         isc::dhcp::CfgMgr::instance().rollback();
         // build an error result
         // build an error result
-        isc::data::ConstElementPtr error =
-            isc::config::createAnswer(1,
-                std::string("Configuration parsing failed: ") + ex.what());
+        ConstElementPtr error = createAnswer(COMMAND_ERROR,
+                 std::string("Configuration parsing failed: ") + ex.what());
         return (error);
         return (error);
     }
     }
 
 
@@ -394,55 +394,45 @@ DControllerBase::runProcess() {
 }
 }
 
 
 // Instance method for handling new config
 // Instance method for handling new config
-isc::data::ConstElementPtr
-DControllerBase::updateConfig(isc::data::ConstElementPtr new_config) {
+ConstElementPtr
+DControllerBase::updateConfig(ConstElementPtr new_config) {
     return (process_->configure(new_config, false));
     return (process_->configure(new_config, false));
 }
 }
 
 
 // Instance method for checking new config
 // Instance method for checking new config
-isc::data::ConstElementPtr
-DControllerBase::checkConfig(isc::data::ConstElementPtr new_config) {
+ConstElementPtr
+DControllerBase::checkConfig(ConstElementPtr new_config) {
     return (process_->configure(new_config, true));
     return (process_->configure(new_config, true));
 }
 }
 
 
+ConstElementPtr
+DControllerBase::versionGetHandler(const std::string&, ConstElementPtr args) {
+    ConstElementPtr answer;
 
 
-// Instance method for executing commands
-isc::data::ConstElementPtr
-DControllerBase::executeCommand(const std::string& command,
-                            isc::data::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.
-    isc::data::ConstElementPtr answer;
-    if (command.compare(SHUT_DOWN_COMMAND) == 0) {
-        answer = shutdownProcess(args);
-    } else {
-        // It wasn't shutdown, so it may be a custom controller command.
-        int rcode = 0;
-        answer = customControllerCommand(command, args);
-        isc::config::parseAnswer(rcode, answer);
-        if (rcode == COMMAND_INVALID)
-        {
-            // It wasn't a controller command, so it may be an application command.
-            answer = process_->command(command, args);
-        }
-    }
-
+    // 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);
     return (answer);
 }
 }
 
 
-isc::data::ConstElementPtr
-DControllerBase::customControllerCommand(const std::string& command,
-                                     isc::data::ConstElementPtr /* args */) {
+ConstElementPtr
+DControllerBase::buildReportHandler(const std::string&, ConstElementPtr args) {
+    return (createAnswer(COMMAND_SUCCESS, isc::detail::getConfigReport()));
+}
 
 
-    // Default implementation always returns invalid command.
-    return (isc::config::createAnswer(COMMAND_INVALID,
-                                      "Unrecognized command: " + command));
+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));
 }
 }
 
 
-isc::data::ConstElementPtr
-DControllerBase::shutdownProcess(isc::data::ConstElementPtr args) {
+ConstElementPtr
+DControllerBase::shutdownProcess(ConstElementPtr args) {
     if (process_) {
     if (process_) {
         return (process_->shutdown(args));
         return (process_->shutdown(args));
     }
     }
@@ -450,7 +440,7 @@ DControllerBase::shutdownProcess(isc::data::ConstElementPtr args) {
     // Not really a failure, but this condition is worth noting. In reality
     // Not really a failure, but this condition is worth noting. In reality
     // it should be pretty hard to cause this.
     // it should be pretty hard to cause this.
     LOG_WARN(dctl_logger, DCTL_NOT_RUNNING).arg(app_name_);
     LOG_WARN(dctl_logger, DCTL_NOT_RUNNING).arg(app_name_);
-    return (isc::config::createAnswer(0, "Process has not been initialized."));
+    return (createAnswer(COMMAND_SUCCESS, "Process has not been initialized"));
 }
 }
 
 
 void
 void
@@ -498,9 +488,7 @@ DControllerBase::processSignal(int signum) {
             LOG_INFO(dctl_logger, DCTL_CFG_FILE_RELOAD_SIGNAL_RECVD)
             LOG_INFO(dctl_logger, DCTL_CFG_FILE_RELOAD_SIGNAL_RECVD)
                      .arg(signum).arg(getConfigFile());
                      .arg(signum).arg(getConfigFile());
             int rcode;
             int rcode;
-            isc::data::ConstElementPtr comment = isc::config::
-                                                 parseAnswer(rcode,
-                                                             configFromFile());
+            ConstElementPtr comment = parseAnswer(rcode, configFromFile());
             if (rcode != 0) {
             if (rcode != 0) {
                 LOG_ERROR(dctl_logger, DCTL_CFG_FILE_RELOAD_ERROR)
                 LOG_ERROR(dctl_logger, DCTL_CFG_FILE_RELOAD_ERROR)
                           .arg(comment->stringValue());
                           .arg(comment->stringValue());
@@ -514,8 +502,8 @@ DControllerBase::processSignal(int signum) {
         {
         {
             LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT,
             LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT,
                       DCTL_SHUTDOWN_SIGNAL_RECVD).arg(signum);
                       DCTL_SHUTDOWN_SIGNAL_RECVD).arg(signum);
-            isc::data::ElementPtr arg_set;
-            executeCommand(SHUT_DOWN_COMMAND, arg_set);
+            ElementPtr arg_set;
+            shutdownHandler(SHUT_DOWN_COMMAND, arg_set);
             break;
             break;
         }
         }
 
 

+ 37 - 53
src/lib/process/d_controller.h

@@ -19,6 +19,8 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/noncopyable.hpp>
 
 
+#include <string>
+#include <set>
 
 
 namespace isc {
 namespace isc {
 namespace process {
 namespace process {
@@ -216,39 +218,6 @@ public:
     /// non-zero means failure), and a string explanation of the outcome.
     /// non-zero means failure), and a string explanation of the outcome.
     virtual isc::data::ConstElementPtr configFromFile();
     virtual isc::data::ConstElementPtr configFromFile();
 
 
-    /// @brief Instance method invoked by the command event handler and  which
-    /// processes the actual command directive.
-    ///
-    /// It supports the execution of:
-    ///
-    ///   1. Stock controller commands - commands common to all DControllerBase
-    /// derivations.  Currently there is only one, the shutdown command.
-    ///
-    ///   2. Custom controller commands - commands that the deriving controller
-    /// class implements.  These commands are executed by the deriving
-    /// controller.
-    ///
-    ///   3. Custom application commands - commands supported by the application
-    /// process implementation.  These commands are executed by the application
-    /// process.
-    ///
-    /// @param command is a string label representing the command to execute.
-    /// @param args is a set of arguments (if any) required for the given
-    /// command.
-    ///
-    /// @return an Element that contains the results of command composed
-    /// of an integer status value and a string explanation of the outcome.
-    /// The status value is one of the following:
-    ///   COMMAND_SUCCESS - Command executed successfully
-    ///   COMMAND_ERROR - Command is valid but suffered an operational
-    ///   failure.
-    ///   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);
-
     /// @brief Fetches the name of the application under control.
     /// @brief Fetches the name of the application under control.
     ///
     ///
     /// @return returns the controller service name string
     /// @return returns the controller service name string
@@ -263,6 +232,41 @@ public:
         return (bin_name_);
         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 '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:
 protected:
     /// @brief Virtual method that provides derivations the opportunity to
     /// @brief Virtual method that provides derivations the opportunity to
     /// support additional command line options.  It is invoked during command
     /// support additional command line options.  It is invoked during command
@@ -287,26 +291,6 @@ protected:
     /// Note this value is subsequently wrapped in a smart pointer.
     /// Note this value is subsequently wrapped in a smart pointer.
     virtual DProcessBase* createProcess() = 0;
     virtual DProcessBase* createProcess() = 0;
 
 
-    /// @brief Virtual method that provides derivations the opportunity to
-    /// support custom external commands executed by the controller.  This
-    /// method is invoked by the processCommand if the received command is
-    /// not a stock controller command.
-    ///
-    /// @param command is a string label representing the command to execute.
-    /// @param args is a set of arguments (if any) required for the given
-    /// command.
-    ///
-    /// @return an Element that contains the results of command composed
-    /// of an integer status value and a string explanation of the outcome.
-    /// The status value is one of the following:
-    ///   COMMAND_SUCCESS - Command executed successfully
-    ///   COMMAND_ERROR - Command is valid but suffered an operational
-    ///   failure.
-    ///   COMMAND_INVALID - Command is not recognized as a valid custom
-    ///   controller command.
-    virtual isc::data::ConstElementPtr customControllerCommand(
-            const std::string& command, isc::data::ConstElementPtr args);
-
     /// @brief Virtual method which can be used to contribute derivation
     /// @brief Virtual method which can be used to contribute derivation
     /// specific usage text.  It is invoked by the usage() method under
     /// specific usage text.  It is invoked by the usage() method under
     /// invalid usage conditions.
     /// invalid usage conditions.

+ 6 - 20
src/lib/process/d_process.h

@@ -25,6 +25,12 @@ public:
         isc::Exception(file, line, what) { };
         isc::Exception(file, line, what) { };
 };
 };
 
 
+/// @brief String value for the version-get command.
+static const std::string VERSION_GET_COMMAND("version-get");
+
+/// @brief String value for the build-report command.
+static const std::string BUILD_REPORT_COMMAND("build-report");
+
 /// @brief String value for the shutdown command.
 /// @brief String value for the shutdown command.
 static const std::string SHUT_DOWN_COMMAND("shutdown");
 static const std::string SHUT_DOWN_COMMAND("shutdown");
 
 
@@ -121,26 +127,6 @@ public:
     configure(isc::data::ConstElementPtr config_set,
     configure(isc::data::ConstElementPtr config_set,
               bool check_only = false) = 0;
               bool check_only = false) = 0;
 
 
-    /// @brief Processes the given command.
-    ///
-    /// This method is called to execute any custom commands supported by the
-    /// process. This method must not throw, it should catch any processing
-    /// errors and return a success or failure answer as described below.
-    ///
-    /// @param command is a string label representing the command to execute.
-    /// @param args is a set of arguments (if any) required for the given
-    /// command.
-    /// @return an Element that contains the results of command composed
-    /// of an integer status value: 
-    ///
-    /// - COMMAND_SUCCESS indicates a command was successful.
-    /// - COMMAND_ERROR indicates a valid command failed execute.
-    /// - COMMAND_INVALID indicates a command is not valid.
-    ///
-    /// and a string explanation of the outcome.
-    virtual isc::data::ConstElementPtr command(
-            const std::string& command, isc::data::ConstElementPtr args) = 0;
-
     /// @brief Destructor
     /// @brief Destructor
     virtual ~DProcessBase(){};
     virtual ~DProcessBase(){};
 
 

+ 0 - 64
src/lib/process/tests/d_controller_unittests.cc

@@ -290,70 +290,6 @@ TEST_F(DStubControllerTest, configUpdateTests) {
     EXPECT_EQ(1, rcode);
     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.
-/// This test verifies that:
-/// 1. That an unrecognized command is detected and returns a status of
-/// process::COMMAND_INVALID.
-/// 2. Shutdown command is recognized and returns a process::COMMAND_SUCCESS
-/// status.
-/// 3. A valid, custom controller command is recognized a
-/// process::COMMAND_SUCCESS
-/// status.
-/// 4. A valid, custom process command is recognized a
-/// process::COMMAND_SUCCESS status.
-/// 5. That a valid controller command that fails returns a
-/// process::COMMAND_ERROR.
-/// 6. That a valid process command that fails returns a process::COMMAND_ERROR.
-TEST_F(DStubControllerTest, 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 process::COMMAND_INVALID
-    // response.
-    std::string bogus_command("bogus");
-    answer = executeCommand(bogus_command, arg_set);
-    isc::config::parseAnswer(rcode, answer);
-    EXPECT_EQ(COMMAND_INVALID, rcode);
-
-    // Verify that shutdown command returns process::COMMAND_SUCCESS response.
-    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
-    // process::COMMAND_SUCCESS response.
-    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
-    // process::COMMAND_SUCCESS response.
-    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 process::COMMAND_ERROR.
-    SimFailure::set(SimFailure::ftControllerCommand);
-    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 process::COMMAND_ERROR.
-    SimFailure::set(SimFailure::ftProcessCommand);
-    answer = executeCommand(DStubProcess::stub_proc_command_, arg_set);
-    isc::config::parseAnswer(rcode, answer);
-    EXPECT_EQ(COMMAND_ERROR, rcode);
-}
-
 // Tests that registered signals are caught and handled.
 // Tests that registered signals are caught and handled.
 TEST_F(DStubControllerTest, ioSignals) {
 TEST_F(DStubControllerTest, ioSignals) {
     // Tell test controller just to record the signals, don't call the
     // Tell test controller just to record the signals, don't call the

+ 1 - 8
src/lib/process/testutils/d_test_stubs.h

@@ -499,18 +499,11 @@ public:
         return (getController()->checkConfig(new_config));
         return (getController()->checkConfig(new_config));
     }
     }
 
 
-    /// @Wrapper to invoke the Controller's executeCommand method.  Please
-    /// refer to DControllerBase::executeCommand for details.
-    isc::data::ConstElementPtr executeCommand(const std::string& command,
-                                       isc::data::ConstElementPtr args){
-        return (getController()->executeCommand(command, args));
-    }
-
     /// @brief Callback that will generate shutdown command via the
     /// @brief Callback that will generate shutdown command via the
     /// command callback function.
     /// command callback function.
     static void genShutdownCallback() {
     static void genShutdownCallback() {
         isc::data::ElementPtr arg_set;
         isc::data::ElementPtr arg_set;
-        getController()->executeCommand(SHUT_DOWN_COMMAND, arg_set);
+        getController()->shutdownHandler(SHUT_DOWN_COMMAND, arg_set);
     }
     }
 
 
     /// @brief Callback that throws an exception.
     /// @brief Callback that throws an exception.