Parcourir la source

[master] Merge branch 'trac5075'

Marcin Siodelski il y a 8 ans
Parent
commit
1ec7586da5

+ 3 - 0
configure.ac

@@ -1547,6 +1547,9 @@ AC_CONFIG_FILES([compatcheck/Makefile
                  Makefile
                  Makefile
                  src/Makefile
                  src/Makefile
                  src/bin/Makefile
                  src/bin/Makefile
+                 src/bin/agent/Makefile
+                 src/bin/agent/tests/Makefile
+                 src/bin/agent/tests/ctrl_agent_process_tests.sh
                  src/bin/d2/Makefile
                  src/bin/d2/Makefile
                  src/bin/d2/tests/Makefile
                  src/bin/d2/tests/Makefile
                  src/bin/d2/tests/d2_process_tests.sh
                  src/bin/d2/tests/d2_process_tests.sh

+ 1 - 1
src/bin/Makefile.am

@@ -1,4 +1,4 @@
 # The following build order must be maintained.
 # The following build order must be maintained.
-SUBDIRS = dhcp4 dhcp6 d2 perfdhcp admin lfc keactrl
+SUBDIRS = dhcp4 dhcp6 d2 agent perfdhcp admin lfc keactrl
 
 
 check-recursive: all-recursive
 check-recursive: all-recursive

+ 5 - 0
src/bin/admin/kea-admin.xml

@@ -224,6 +224,11 @@
       </citerefentry>,
       </citerefentry>,
 
 
       <citerefentry>
       <citerefentry>
+        <refentrytitle>kea-ctrl-agent</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
         <refentrytitle>keactrl</refentrytitle>
         <refentrytitle>keactrl</refentrytitle>
         <manvolnum>8</manvolnum>
         <manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,

+ 6 - 0
src/bin/agent/.gitignore

@@ -0,0 +1,6 @@
+/kea-ctrl-agent
+/ctrl_agent_messages.cc
+/ctrl_agent_messages.h
+/s-messages
+/kea-ctrl-agent.8
+

+ 78 - 0
src/bin/agent/Makefile.am

@@ -0,0 +1,78 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(KEA_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES  = *.gcno *.gcda ctrl_agent_messages.h ctrl_agent_messages.cc s-messages
+
+man_MANS = kea-ctrl-agent.8
+DISTCLEANFILES = $(man_MANS)
+EXTRA_DIST = $(man_MANS) kea-ctrl-agent.xml
+
+if GENERATE_DOCS
+kea-ctrl-agent.8: kea-ctrl-agent.xml
+	@XSLTPROC@ --novalid --xinclude --nonet -o $@ \
+        http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
+	$(srcdir)/kea-ctrl-agent.xml
+
+else
+
+$(man_MANS):
+	@echo Man generation disabled.  Creating dummy $@.  Configure with --enable-generate-docs to enable it.
+	@echo Man generation disabled.  Remove this file, configure with --enable-generate-docs, and rebuild Kea > $@
+
+endif
+
+ctrl_agent_messages.h ctrl_agent_messages.cc: s-messages
+
+s-messages: ctrl_agent_messages.mes
+	$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/bin/agent/ctrl_agent_messages.mes
+	touch $@
+
+BUILT_SOURCES = ctrl_agent_messages.h ctrl_agent_messages.cc
+
+
+# convenience archive
+
+noinst_LTLIBRARIES = libagent.la
+
+libagent_la_SOURCES  = ctrl_agent_cfg_mgr.cc ctrl_agent_cfg_mgr.h
+libagent_la_SOURCES += ctrl_agent_controller.cc ctrl_agent_controller.h
+libagent_la_SOURCES += ctrl_agent_log.cc ctrl_agent_log.h
+libagent_la_SOURCES += ctrl_agent_process.cc ctrl_agent_process.h
+
+nodist_libagent_la_SOURCES = ctrl_agent_messages.h ctrl_agent_messages.cc
+EXTRA_DIST += ctrl_agent_messages.mes
+
+sbin_PROGRAMS = kea-ctrl-agent
+
+kea_ctrl_agent_SOURCES = main.cc
+
+kea_ctrl_agent_LDADD  = libagent.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/cfgrpt/libcfgrpt.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
+kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+kea_ctrl_agent_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS)
+
+kea_ctrl_agent_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS)
+

+ 43 - 0
src/bin/agent/ctrl_agent_cfg_mgr.cc

@@ -0,0 +1,43 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_cfg_mgr.h>
+
+using namespace isc::dhcp;
+using namespace isc::process;
+
+namespace isc {
+namespace agent {
+
+CtrlAgentCfgMgr::CtrlAgentCfgMgr()
+    : DCfgMgrBase(DCfgContextBasePtr(new CtrlAgentCfgContext())) {
+}
+
+CtrlAgentCfgMgr::~CtrlAgentCfgMgr() {
+}
+
+std::string
+CtrlAgentCfgMgr::getConfigSummary(const uint32_t selection) {
+    return ("Control Agent is currently not configurable.");
+}
+
+isc::dhcp::ParserPtr
+CtrlAgentCfgMgr::createConfigParser(const std::string& element_id,
+                                    const isc::data::Element::Position& pos) {
+    // Create dummy parser, so as we don't return null pointer.
+    isc::dhcp::ParserPtr parser;
+    parser.reset(new Uint32Parser(element_id, getContext()->getUint32Storage()));
+    return (parser);
+}
+
+DCfgContextBasePtr
+CtrlAgentCfgMgr::createNewContext() {
+    return (DCfgContextBasePtr(new CtrlAgentCfgContext()));
+}
+
+} // namespace isc::agent
+} // namespace isc

+ 106 - 0
src/bin/agent/ctrl_agent_cfg_mgr.h

@@ -0,0 +1,106 @@
+// Copyright (C) 2016 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 CTRL_AGENT_CFG_MGR_H
+#define CTRL_AGENT_CFG_MGR_H
+
+#include <process/d_cfg_mgr.h>
+#include <boost/pointer_cast.hpp>
+
+namespace isc {
+namespace agent {
+
+class CtrlAgentCfgContext;
+/// @brief Pointer to a configuration context.
+typedef boost::shared_ptr<CtrlAgentCfgContext> CtrlAgentCfgContextPtr;
+
+/// @brief Control Agent Configuration Context.
+///
+/// Implement the storage container for configuration context.
+/// It provides a single enclosure for the storage of configuration parameters
+/// and any other Control Agent specific information that needs to be accessible
+/// during configuration parsing as well as to the application as a whole.
+/// It is derived from the context base class, DCfgContextBase.
+class CtrlAgentCfgContext : public process::DCfgContextBase {
+public:
+    /// @brief Creates a clone of this context object.
+    ///
+    /// @return A pointer to the new clone.
+    virtual process::DCfgContextBasePtr clone() {
+        return (process::DCfgContextBasePtr(new CtrlAgentCfgContext(*this)));
+    }
+
+private:
+    /// @brief Private assignment operator to avoid potential for slicing.
+    CtrlAgentCfgContext& operator=(const CtrlAgentCfgContext& rhs);
+};
+
+/// @brief Ctrl Agent Configuration Manager.
+///
+/// Provides the mechanisms for managing the Control Agent application's
+/// configuration.
+class CtrlAgentCfgMgr : public process::DCfgMgrBase {
+public:
+
+    /// @brief Constructor.
+    CtrlAgentCfgMgr();
+
+    /// @brief Destructor
+    virtual ~CtrlAgentCfgMgr();
+
+    /// @brief Convenience method that returns the Control Agent configuration
+    /// context.
+    ///
+    /// @return returns a pointer to the configuration context.
+    CtrlAgentCfgContextPtr getCtrlAgentCfgContext() {
+        return (boost::dynamic_pointer_cast<CtrlAgentCfgContext>(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:
+
+    /// @brief  Create a parser instance based on an element id.
+    ///
+    /// Given an element_id returns an instance of the appropriate parser.
+    ///
+    /// @param element_id is the string name of the element as it will appear
+    /// in the configuration set.
+    /// @param pos position within the configuration text (or file) of element
+    /// to be parsed.  This is passed for error messaging.
+    ///
+    /// @return returns a ParserPtr to the parser instance.
+    virtual isc::dhcp::ParserPtr
+    createConfigParser(const std::string& element_id,
+                       const isc::data::Element::Position& pos
+                       = isc::data::Element::ZERO_POSITION());
+
+    /// @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();
+};
+
+/// @brief Defines a shared pointer to CtrlAgentCfgMgr.
+typedef boost::shared_ptr<CtrlAgentCfgMgr> CtrlAgentCfgMgrPtr;
+
+} // namespace isc::agent
+} // namespace isc
+
+#endif // CTRL_AGENT_CFG_MGR_H

+ 51 - 0
src/bin/agent/ctrl_agent_controller.cc

@@ -0,0 +1,51 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_controller.h>
+#include <agent/ctrl_agent_process.h>
+
+using namespace isc::process;
+
+namespace isc {
+namespace agent {
+
+/// @brief Defines the application name, this is passed into base class
+/// it may be used to locate configuration data and appears in log statement.
+const char* CtrlAgentController::agent_app_name_ = "CtrlAgent";
+
+/// @brief Defines the executable name. This is passed into the base class
+const char* CtrlAgentController::agent_bin_name_ = "kea-ctrl-agent";
+
+DControllerBasePtr&
+CtrlAgentController::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 CtrlAgentController());
+        setController(controller_ptr);
+    }
+
+    return (getController());
+}
+
+DProcessBase*
+CtrlAgentController::createProcess() {
+    // Instantiate and return an instance of the D2 application process. Note
+    // that the process is passed the controller's io_service.
+    return (new CtrlAgentProcess(getAppName().c_str(), getIOService()));
+}
+
+CtrlAgentController::CtrlAgentController()
+    : DControllerBase(agent_app_name_, agent_bin_name_) {
+}
+
+CtrlAgentController::~CtrlAgentController() {
+}
+
+} // namespace isc::agent
+} // namespace isc

+ 66 - 0
src/bin/agent/ctrl_agent_controller.h

@@ -0,0 +1,66 @@
+// Copyright (C) 2016 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 CTRL_AGENT_CONTROLLER_H
+#define CTRL_AGENT_CONTROLLER_H
+
+#include <process/d_controller.h>
+
+namespace isc {
+namespace agent {
+
+/// @brief Process Controller for Control Agent Process.
+///
+/// This class is the Control Agent specific derivation of the DControllerBase.
+/// It creates and manages an instance of the Control Agent application process,
+/// CtrlAgentProcess.
+class CtrlAgentController : 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 ~CtrlAgentController();
+
+    /// @brief Defines the application name, this is passed into base class
+    /// and appears in log statements.
+    static const char* agent_app_name_;
+
+    /// @brief Defines the executable name. This is passed into the base class
+    /// by convention this should match the executable name.
+    static const char* agent_bin_name_;
+
+private:
+
+    /// @brief Creates an instance of the Control Agent 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 Constructor is declared private to maintain the integrity of
+    /// the singleton instance.
+    CtrlAgentController();
+
+};
+
+} // namespace isc::agent
+} // namespace isc
+
+#endif // CTRL_AGENT_CONTROLLER_H

+ 15 - 0
src/bin/agent/ctrl_agent_log.cc

@@ -0,0 +1,15 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_log.h>
+
+namespace isc {
+namespace agent {
+
+isc::log::Logger agent_logger("ctrl-agent");
+
+} // namespace isc::agent
+} // namespace isc

+ 23 - 0
src/bin/agent/ctrl_agent_log.h

@@ -0,0 +1,23 @@
+// Copyright (C) 2016 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 CTRL_AGENT_LOG_H
+#define CTRL_AGENT_LOG_H
+
+#include <log/logger_support.h>
+#include <log/macros.h>
+#include <agent/ctrl_agent_messages.h>
+
+namespace isc {
+namespace agent {
+
+/// @brief Control Agent logger.
+extern isc::log::Logger agent_logger;
+
+} // namespace isc::agent
+} // namespace isc
+
+#endif

+ 20 - 0
src/bin/agent/ctrl_agent_messages.mes

@@ -0,0 +1,20 @@
+# Copyright (C) 2016 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/.
+
+$NAMESPACE isc::agent
+
+% CTRL_AGENT_FAILED application experienced a fatal error: %1
+This is a debug message issued when the Control Agent application
+encounters an unrecoverable error from within the event loop.
+
+% CTRL_AGENT_RUN_EXIT application is exiting the event loop
+This is a debug message issued when the Control Agent exits its
+event loop.
+
+% CTRL_AGENT_STARTED Kea Control Agent version %1 started
+This informational message indicates that the DHCP-DDNS server has
+processed all configuration information and is ready to begin processing.
+The version is also printed.

+ 76 - 0
src/bin/agent/ctrl_agent_process.cc

@@ -0,0 +1,76 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_process.h>
+#include <agent/ctrl_agent_log.h>
+#include <cc/command_interpreter.h>
+#include <boost/pointer_cast.hpp>
+
+using namespace isc::process;
+
+namespace isc {
+namespace agent {
+
+CtrlAgentProcess::CtrlAgentProcess(const char* name,
+                                   const asiolink::IOServicePtr& io_service)
+    : DProcessBase(name, io_service, DCfgMgrBasePtr(new CtrlAgentCfgMgr())) {
+}
+
+CtrlAgentProcess::~CtrlAgentProcess() {
+}
+
+void
+CtrlAgentProcess::init() {
+}
+
+void
+CtrlAgentProcess::run() {
+    LOG_INFO(agent_logger, CTRL_AGENT_STARTED).arg(VERSION);
+
+    while (!shouldShutdown()) {
+        try {
+            getIoService()->run_one();
+
+        } catch (const std::exception& ex) {
+            LOG_FATAL(agent_logger, CTRL_AGENT_FAILED).arg(ex.what());
+            isc_throw(DProcessBaseError,
+                      "Process run method failed: " << ex.what());
+        }
+    }
+
+    LOG_DEBUG(agent_logger, DBGLVL_START_SHUT, CTRL_AGENT_RUN_EXIT);
+}
+
+isc::data::ConstElementPtr
+CtrlAgentProcess::shutdown(isc::data::ConstElementPtr args) {
+    setShutdownFlag(true);
+    return (isc::config::createAnswer(0, "Control Agent is shutting down"));
+}
+
+isc::data::ConstElementPtr
+CtrlAgentProcess::configure(isc::data::ConstElementPtr config_set) {
+    int rcode = 0;
+    isc::data::ConstElementPtr answer = getCfgMgr()->parseConfig(config_set);
+    config::parseAnswer(rcode, 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
+CtrlAgentProcess::getCtrlAgentCfgMgr() {
+    return(boost::dynamic_pointer_cast<CtrlAgentCfgMgr>(getCfgMgr()));
+}
+
+} // namespace isc::agent
+} // namespace isc

+ 118 - 0
src/bin/agent/ctrl_agent_process.h

@@ -0,0 +1,118 @@
+// Copyright (C) 2016 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 CTRL_AGENT_PROCESS_H
+#define CTRL_AGENT_PROCESS_H
+
+#include <agent/ctrl_agent_cfg_mgr.h>
+#include <process/d_process.h>
+
+namespace isc {
+namespace agent {
+
+/// @brief Kea Control Agent Application Process
+///
+/// CtrlAgentProcess provides top level application logic for the Control
+/// Agent, a process managing Kea servers.
+///
+/// The Control Agent receives JSON control commands over HTTP and forwards
+/// the JSON commands to the respective Kea servers. The JSON command
+/// includes a name of the server to which the command pertains. After
+/// receiving a response from the Kea server it is sent back over HTTP
+/// to the control API client.
+///
+/// Some commands are handled by the Control Agent process itself, rather than
+/// forwarded to the Kea servers. An example of such command is the one that
+/// instructs the agent to start a specific service.
+class CtrlAgentProcess : public process::DProcessBase {
+public:
+    /// @brief Constructor
+    ///
+    /// @param name name is a text label for the process. Generally used
+    /// in log statements, but otherwise arbitrary.
+    /// @param io_service is the io_service used by the caller for
+    /// asynchronous event handling.
+    CtrlAgentProcess(const char* name, const asiolink::IOServicePtr& io_service);
+
+    /// @brief Destructor
+    virtual ~CtrlAgentProcess();
+
+    /// @brief Initialize the Control Agent process.
+    ///
+    /// This is invoked by the controller after command line arguments but
+    /// prior to configuration reception. The base class provides this method
+    /// as a place to perform any derivation-specific initialization steps
+    /// that are inappropriate for the constructor but necessary prior to
+    /// launch.
+    virtual void init();
+
+    /// @brief Implements the process's event loop.
+    ///
+    /// @throw DProcessBaseError if an operational error is encountered.
+    virtual void run();
+
+    /// @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);
+
+    /// @brief Processes the given configuration.
+    ///
+    /// This method may be called multiple times during the process lifetime.
+    /// Certainly once during process startup, and possibly later if the user
+    /// alters configuration. This method must not throw, it should catch any
+    /// processing errors and return a success or failure answer as described
+    /// below.
+    ///
+    /// @param config_set a new configuration (JSON) for the process
+    /// @return an Element that contains the results of configuration composed
+    /// of an integer status value (0 means successful, non-zero means failure),
+    /// and a string explanation of the outcome.
+    virtual isc::data::ConstElementPtr
+    configure(isc::data::ConstElementPtr config_set);
+
+    /// @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.
+    CtrlAgentCfgMgrPtr getCtrlAgentCfgMgr();
+};
+
+/// @brief Defines a shared pointer to CtrlAgentProcess.
+typedef boost::shared_ptr<CtrlAgentProcess> CtrlAgentProcessPtr;
+
+}; // namespace isc::agent
+}; // namespace isc
+
+#endif // CTRL_AGENT_PROCESS_H

+ 213 - 0
src/bin/agent/kea-ctrl-agent.xml

@@ -0,0 +1,213 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+               [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2016 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/.
+-->
+
+<refentry>
+
+  <refentryinfo>
+    <productname>ISC Kea</productname>
+    <date>Sep. 28, 2016</date>
+    <edition>1.1.0</edition>
+    <author>
+      <contrib>The Kea software has been written by a number of
+        engineers working for ISC: Tomek Mrugalski, Stephen Morris, Marcin
+        Siodelski, Thomas Markwalder, Francis Dupont, Jeremy C. Reed,
+        Wlodek Wencel and Shawn Routhier.  That list is roughly in the
+        chronological order in which the authors made their first
+        contribution. For a complete list of authors and
+        contributors, see AUTHORS file.</contrib>
+      <orgname>Internet Systems Consortium, Inc.</orgname>
+    </author>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kea-ctrl-agent</refentrytitle>
+    <manvolnum>8</manvolnum>
+    <refmiscinfo class="manual">Kea</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kea-ctrl-agent</refname>
+    <refpurpose>Control Agent process in Kea</refpurpose>
+  </refnamediv>
+
+  <docinfo>
+    <copyright>
+      <year>2016</year>
+      <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+    </copyright>
+  </docinfo>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>kea-ctrl-agent</command>
+      <arg><option>-v</option></arg>
+      <arg><option>-V</option></arg>
+      <arg><option>-W</option></arg>
+      <arg><option>-d</option></arg>
+      <arg><option>-s</option></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+    <para>
+      The <command>kea-ctrl-agent</command> provides a REST service for
+      controlling Kea services. The received HTTP requests are decapsulated
+      and forwarded to the respective Kea services in JSON format. Received
+      JSON responses are encapsulated within HTTP responses and returned to
+      the controlling entity. Some commands may be handled by the Control
+      Agent directly, and not forwarded to any Kea service.
+    </para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>ARGUMENTS</title>
+
+    <para>The arguments are as follows:</para>
+
+    <variablelist>
+
+      <varlistentry>
+        <term><option>-v</option></term>
+        <listitem><para>
+          Display the version.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-V</option></term>
+        <listitem><para>
+          Display the extended version.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-W</option></term>
+        <listitem><para>
+          Display the configuration report.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-d</option></term>
+        <listitem><para>
+          Verbose mode sets the logging level to debug. This is primarily
+          for development purposes in stand-alone mode.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-c</option></term>
+        <listitem><para>
+          Configuration file including the configuration for the Control Agent
+          server. It may also contain configuration entries for other Kea
+          services.
+        </para></listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>DOCUMENTATION</title>
+    <para>Kea comes with an extensive Kea User's Guide documentation
+      that covers all aspects of running the Kea software -
+      compilation, installation, configuration, configuration examples
+      and many more. Kea also features a Kea Messages Manual, which
+      lists all possible messages Kea can print with a brief
+      description for each of them. Both documents are typically
+      available in various formats (txt, html, pdf) with your Kea
+      distribution. The on-line version is available at
+      http://kea.isc.org/docs/.</para>
+    <para>
+      Kea source code is documented in the Kea Developer's Guide. It's
+      on-line version is available at http://kea.isc.org. Please
+      follow Developer's Guide link.
+    </para>
+    <para>
+      Kea project website is available at: http://kea.isc.org.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>MAILING LISTS AND SUPPORT</title>
+    <para>
+      There are two mailing lists available for Kea project. kea-users
+      (kea-users at lists.isc.org) is intended for Kea users, while kea-dev
+      (kea-dev at lists.isc.org) is intended for Kea developers, prospective
+      contributors and other advanced users.  Both lists are available at
+      http://lists.isc.org. The community provides best effort type of support
+      on both of those lists.
+    </para>
+    <para>
+      ISC provides professional support for Kea services. See
+      https://www.isc.org/kea/ for details.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>HISTORY</title>
+    <para>
+      The <command>kea-ctrl-agent</command> was first coded in December 2016
+      by Marcin Siodelski.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+    <para>
+      <citerefentry>
+        <refentrytitle>kea-dhcp4</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
+        <refentrytitle>kea-dhcp6</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
+        <refentrytitle>kea-dhcp-ddns</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
+        <refentrytitle>kea-admin</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
+        <refentrytitle>keactrl</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
+        <refentrytitle>perfdhcp</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
+        <refentrytitle>kea-lfc</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citetitle>Kea Administrator's Guide</citetitle>.
+
+    </para>
+  </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->

+ 35 - 0
src/bin/agent/main.cc

@@ -0,0 +1,35 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_controller.h>
+#include <exceptions/exceptions.h>
+#include <cstdlib>
+#include <iostream>
+
+using namespace isc::agent;
+using namespace isc::process;
+
+int main(int argc, char* argv[]) {
+    int ret = EXIT_SUCCESS;
+
+    // Launch the controller passing in command line arguments.
+    // Exit program with the controller's return code.
+    try  {
+        // Instantiate/fetch the application controller singleton.
+        DControllerBasePtr& controller = CtrlAgentController::instance();
+
+        // 'false' value disables test mode.
+        controller->launch(argc, argv, false);
+    } catch (const VersionMessage& ex) {
+        std::cout << ex.what() << std::endl;
+    } catch (const isc::Exception& ex) {
+        std::cerr << "Service failed:" << ex.what() << std::endl;
+        ret = EXIT_FAILURE;
+    }
+
+    return (ret);
+}

+ 2 - 0
src/bin/agent/tests/.gitignore

@@ -0,0 +1,2 @@
+/ctrl_agent_unittests
+/ctrl_agent_process_tests.sh

+ 76 - 0
src/bin/agent/tests/Makefile.am

@@ -0,0 +1,76 @@
+SHTESTS =
+# The test of dynamic reconfiguration based on signals will work only
+# if we are using file based configuration approach.
+SHTESTS += ctrl_agent_process_tests.sh
+
+noinst_SCRIPTS = ctrl_agent_process_tests.sh
+
+EXTRA_DIST  = ctrl_agent_process_tests.sh.in
+
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+	for shtest in $(SHTESTS) ; do \
+	echo Running test: $$shtest ; \
+	export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
+	export KEA_PIDFILE_DIR=$(abs_top_builddir); \
+	${SHELL} $(abs_builddir)/$$shtest || exit ; \
+	done
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_builddir)/src/bin # for generated spec_config.h header
+AM_CPPFLAGS += -I$(top_srcdir)/src/bin
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/agent/tests\"
+AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
+
+CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
+
+DISTCLEANFILES = ctrl_agent_process_tests.sh
+
+AM_CXXFLAGS = $(KEA_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+TESTS_ENVIRONMENT = \
+        $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
+
+TESTS =
+if HAVE_GTEST
+
+TESTS += ctrl_agent_unittests
+
+ctrl_agent_unittests_SOURCES  = ctrl_agent_cfg_mgr_unittests.cc
+ctrl_agent_unittests_SOURCES += ctrl_agent_controller_unittests.cc
+ctrl_agent_unittests_SOURCES += ctrl_agent_process_unittests.cc
+ctrl_agent_unittests_SOURCES += ctrl_agent_unittests.cc
+
+ctrl_agent_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+ctrl_agent_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
+
+ctrl_agent_unittests_LDADD = $(top_builddir)/src/bin/agent/libagent.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/process/testutils/libprocesstest.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/cfgrpt/libcfgrpt.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
+ctrl_agent_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+ctrl_agent_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS)
+ctrl_agent_unittests_LDADD += $(BOOST_LIBS) $(GTEST_LDADD)
+
+endif
+
+noinst_PROGRAMS = $(TESTS)

+ 33 - 0
src/bin/agent/tests/ctrl_agent_cfg_mgr_unittests.cc

@@ -0,0 +1,33 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_cfg_mgr.h>
+#include <process/testutils/d_test_stubs.h>
+#include <boost/scoped_ptr.hpp>
+#include <gtest/gtest.h>
+
+using namespace isc::agent;
+
+namespace  {
+
+// Tests construction of CtrlAgentCfgMgr class.
+TEST(CtrlAgentCfgMgr, construction) {
+    boost::scoped_ptr<CtrlAgentCfgMgr> cfg_mgr;
+
+    // Verify that configuration manager constructions without error.
+    ASSERT_NO_THROW(cfg_mgr.reset(new CtrlAgentCfgMgr()));
+
+    // Verify that the context can be retrieved and is not null.
+    CtrlAgentCfgContextPtr context;
+    ASSERT_NO_THROW(context = cfg_mgr->getCtrlAgentCfgContext());
+    EXPECT_TRUE(context);
+
+    // Verify that the manager can be destructed without error.
+    EXPECT_NO_THROW(cfg_mgr.reset());
+}
+
+}

+ 142 - 0
src/bin/agent/tests/ctrl_agent_controller_unittests.cc

@@ -0,0 +1,142 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_controller.h>
+#include <agent/ctrl_agent_process.h>
+#include <process/testutils/d_test_stubs.h>
+#include <boost/pointer_cast.hpp>
+
+using namespace isc::agent;
+using namespace isc::process;
+
+namespace {
+
+/// @brief Valid Control Agent Config used in tests.
+/// @todo Use actual config once configuration parsing is implemented.
+const char* valid_agent_config = "{ }";
+
+/// @brief test fixture class for testing CtrlAgentController class. This
+/// class derives from DControllerTest and wraps CtrlAgentController. Much
+/// of the underlying functionality is in the DControllerBase class which
+/// has extensive set of unit tests that are independent from the Control
+/// Agent.
+class CtrlAgentControllerTest : public DControllerTest {
+public:
+
+    /// @brief Constructor.
+    CtrlAgentControllerTest()
+        : DControllerTest(CtrlAgentController::instance) {
+    }
+
+};
+
+// Basic Controller instantiation testing.
+// Verifies that the controller singleton gets created and that the
+// basic derivation from the base class is intact.
+TEST_F(CtrlAgentControllerTest, basicInstanceTesting) {
+    // Verify the we can the singleton instance can be fetched and that
+    // it is the correct type.
+    DControllerBasePtr& controller = DControllerTest::getController();
+    ASSERT_TRUE(controller);
+    ASSERT_NO_THROW(boost::dynamic_pointer_cast<CtrlAgentController>(controller));
+
+    // Verify that controller's app name is correct.
+    EXPECT_TRUE(checkAppName(CtrlAgentController::agent_app_name_));
+
+    // Verify that controller's bin name is correct.
+    EXPECT_TRUE(checkBinName(CtrlAgentController::agent_bin_name_));
+
+    // Verify that controller's IOService exists.
+    EXPECT_TRUE(checkIOService());
+
+    // Verify that the Process does NOT exist.
+    EXPECT_FALSE(checkProcess());
+}
+
+
+// Tests basic command line processing.
+// Verifies that:
+// 1. Standard command line options are supported.
+// 2. Invalid options are detected.
+TEST_F(CtrlAgentControllerTest, commandLineArgs) {
+    char* argv[] = { const_cast<char*>("progName"),
+                     const_cast<char*>("-c"),
+                     const_cast<char*>(DControllerTest::CFG_TEST_FILE),
+                     const_cast<char*>("-d") };
+    int argc = 4;
+
+    // Verify that verbose flag is false initially.
+    EXPECT_TRUE(checkVerbose(false));
+
+    // Verify that standard options can be parsed without error.
+    EXPECT_NO_THROW(parseArgs(argc, argv));
+
+    // Verify that verbose flag is true.
+    EXPECT_TRUE(checkVerbose(true));
+
+    // Verify configuration file name is correct.
+    EXPECT_TRUE(checkConfigFileName(DControllerTest::CFG_TEST_FILE));
+
+    // Verify that an unknown option is detected.
+    char* argv2[] = { const_cast<char*>("progName"),
+                      const_cast<char*>("-x") };
+    argc = 2;
+    EXPECT_THROW(parseArgs(argc, argv2), InvalidUsage);
+}
+
+// Tests application process creation and initialization.
+// Verifies that the process can be successfully created and initialized.
+TEST_F(CtrlAgentControllerTest, initProcessTesting) {
+    ASSERT_NO_THROW(initProcess());
+    EXPECT_TRUE(checkProcess());
+}
+
+// Tests launch and normal shutdown (stand alone mode).
+// This creates an interval timer to generate a normal shutdown and then
+// launches with a valid, stand-alone command line and no simulated errors.
+TEST_F(CtrlAgentControllerTest, launchNormalShutdown) {
+    // Write valid_agent_config and then run launch() for 1000 ms.
+    time_duration elapsed_time;
+    runWithConfig(valid_agent_config, 1000, elapsed_time);
+
+    // Give a generous margin to accommodate slower test environs.
+    EXPECT_TRUE(elapsed_time.total_milliseconds() >= 800 &&
+                elapsed_time.total_milliseconds() <= 1300);
+}
+
+// Tests that the SIGINT triggers a normal shutdown.
+TEST_F(CtrlAgentControllerTest, sigintShutdown) {
+    // Setup to raise SIGHUP in 1 ms.
+    TimedSignal sighup(*getIOService(), SIGINT, 1);
+
+    // Write valid_agent_config and then run launch() for a maximum
+    // of 1000 ms.
+    time_duration elapsed_time;
+    runWithConfig(valid_agent_config, 1000, elapsed_time);
+
+    // Signaled shutdown should make our elapsed time much smaller than
+    // the maximum run time.  Give generous margin to accommodate slow
+    // test environs.
+    EXPECT_TRUE(elapsed_time.total_milliseconds() < 300);
+}
+
+// Tests that the SIGTERM triggers a normal shutdown.
+TEST_F(CtrlAgentControllerTest, sigtermShutdown) {
+    // Setup to raise SIGHUP in 1 ms.
+    TimedSignal sighup(*getIOService(), SIGTERM, 1);
+
+    // Write valid_agent_config and then run launch() for a maximum of 1 s.
+    time_duration elapsed_time;
+    runWithConfig(valid_agent_config, 1000, elapsed_time);
+
+    // Signaled shutdown should make our elapsed time much smaller than
+    // the maximum run time.  Give generous margin to accommodate slow
+    // test environs.
+    EXPECT_TRUE(elapsed_time.total_milliseconds() < 300);
+}
+
+}

+ 105 - 0
src/bin/agent/tests/ctrl_agent_process_tests.sh.in

@@ -0,0 +1,105 @@
+# Copyright (C) 2016 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/.
+
+# Path to the temporary configuration file.
+CFG_FILE=@abs_top_builddir@/src/bin/agent/tests/test_config.json
+# Path to the Control Agent log file.
+LOG_FILE=@abs_top_builddir@/src/bin/agent/tests/test.log
+# Expected version
+EXPECTED_VERSION="@PACKAGE_VERSION@"
+
+# Control Agent configuration to be stored in the configuration file.
+# todo: use actual configuration once we support it.
+CONFIG="{
+    \"CtrlAgent\":
+    {
+        \"dummy-param\": 123
+    },
+    \"Logging\":
+    {
+        \"loggers\": [
+        {
+            \"name\": \"kea-ctrl-agent\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+bin="kea-ctrl-agent"
+bin_path=@abs_top_builddir@/src/bin/agent
+
+# Import common test library.
+. @abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh
+
+# This test verifies that Control Agent is shut down gracefully when it
+# receives a SIGINT or SIGTERM signal.
+shutdown_test() {
+    test_name=${1}  # Test name
+    signum=${2}      # Signal number
+    # Log the start of the test and print test name.
+    test_start ${test_name}
+    # Remove dangling D2 instances and remove log files.
+    cleanup
+    # Create new configuration file.
+    create_config "${CONFIG}"
+    # Instruct Control Agent to log to the specific file.
+    set_logger
+    # Start Control Agent.
+    start_kea ${bin_path}/${bin}
+    # Wait up to 20s for Control Agent to start.
+    wait_for_kea 20
+    if [ ${_WAIT_FOR_KEA} -eq 0 ]; then
+        printf "ERROR: timeout waiting for Control Agent to start.\n"
+        clean_exit 1
+    fi
+
+    # Check if it is still running. It could have terminated (e.g. as a result
+    # of configuration failure).
+    get_pid ${bin}
+    if [ ${_GET_PIDS_NUM} -ne 1 ]; then
+        printf "ERROR: expected one Control Agent process to be started. Found %d processes\
+ started.\n" ${_GET_PIDS_NUM}
+        clean_exit 1
+    fi
+
+    # Check in the log file, how many times server has been configured.
+    # It should be just once on startup.
+    get_reconfigs
+    if [ ${_GET_RECONFIGS} -ne 1 ]; then
+        printf "ERROR: server hasn't been configured.\n"
+        clean_exit 1
+    else
+        printf "Server successfully configured.\n"
+    fi
+
+    # Send signal to Control Agent (SIGTERM, SIGINT etc.)
+    send_signal ${signum} ${bin}
+
+    # Now wait for process to log that it is exiting.
+    wait_for_message 10 "DCTL_SHUTDOWN" 1
+    if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
+        printf "ERROR: Control Agent did not log shutdown.\n"
+        clean_exit 1
+    fi
+
+    # Make sure the server is down.
+    wait_for_server_down 5 ${bin}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    test_finish 0
+}
+
+server_pid_file_test "${CONFIG}" DCTL_ALREADY_RUNNING
+shutdown_test "ctrl-agent.sigterm_test" 15
+shutdown_test "ctrl-agent.sigint_test" 2
+

+ 87 - 0
src/bin/agent/tests/ctrl_agent_process_unittests.cc

@@ -0,0 +1,87 @@
+// Copyright (C) 2016 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 <agent/ctrl_agent_cfg_mgr.h>
+#include <agent/ctrl_agent_process.h>
+#include <asiolink/interval_timer.h>
+#include <asiolink/io_service.h>
+#include <process/testutils/d_test_stubs.h>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <gtest/gtest.h>
+
+using namespace boost::posix_time;
+using namespace isc;
+using namespace isc::agent;
+using namespace isc::asiolink;
+using namespace isc::process;
+
+namespace {
+
+/// @brief CtrlAgentProcess test fixture class.
+class CtrlAgentProcessTest : public CtrlAgentProcess, public ::testing::Test  {
+public:
+    /// @brief Constructor
+    CtrlAgentProcessTest() :
+        CtrlAgentProcess("agent-test",
+                         IOServicePtr(new isc::asiolink::IOService())) {
+    }
+
+    /// @brief Destructor
+    virtual ~CtrlAgentProcessTest() {
+    }
+
+    /// @brief Callback that will invoke shutdown method.
+    void genShutdownCallback() {
+        shutdown(isc::data::ConstElementPtr());
+    }
+};
+
+// Test construction of the CtrlAgentProcess object.
+TEST(CtrlAgentProcess, construction) {
+    // Verify that the constructor will fail if given an empty
+    // io service.
+    IOServicePtr lcl_io_service;
+    EXPECT_THROW(CtrlAgentProcess("TestProcess", lcl_io_service),
+                 DProcessBaseError);
+
+    // Verify that the constructor succeeds with a valid io_service
+    lcl_io_service.reset(new IOService());
+    ASSERT_NO_THROW(CtrlAgentProcess("TestProcess", lcl_io_service));
+
+    // Verify tha the configuration is accessible after construction.
+    CtrlAgentProcess agent_process("TestProcess", lcl_io_service);
+    CtrlAgentCfgMgrPtr cfg_mgr = agent_process.getCtrlAgentCfgMgr();
+    ASSERT_TRUE(cfg_mgr);
+}
+
+// Verifies that en external call to shutdown causes the run method to
+// exit gracefully. 
+TEST_F(CtrlAgentProcessTest, shutdown) {
+    // Use an asiolink IntervalTimer and callback to generate the
+    // shutdown invocation. (Note IntervalTimer setup is in milliseconds).
+    IntervalTimer timer(*getIoService());
+    timer.setup(boost::bind(&CtrlAgentProcessTest::genShutdownCallback, this),
+                2 * 1000);
+
+    // Record start time, and invoke run().
+    ptime start = microsec_clock::universal_time();
+    EXPECT_NO_THROW(run());
+
+    // Record stop time.
+    ptime stop = microsec_clock::universal_time();
+
+    // Verify that duration of the run invocation is the same as the
+    // timer duration.  This demonstrates that the shutdown was driven
+    // by an io_service event and callback.
+    time_duration elapsed = stop - start;
+    EXPECT_TRUE(elapsed.total_milliseconds() >= 1900 &&
+                elapsed.total_milliseconds() <= 2200);
+}
+
+
+}

+ 25 - 0
src/bin/agent/tests/ctrl_agent_unittests.cc

@@ -0,0 +1,25 @@
+// Copyright (C) 2016 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 <log/logger_support.h>
+#include <gtest/gtest.h>
+
+int
+main(int argc, char* argv[]) {
+
+    ::testing::InitGoogleTest(&argc, argv);
+
+    // See the documentation of the KEA_* environment variables in
+    // src/lib/log/README for info on how to tweak logging
+    isc::log::initLogger();
+
+    // Override --localstatedir value for PID files
+    setenv("KEA_PIDFILE_DIR", TEST_DATA_BUILDDIR, 1);
+
+    int result = RUN_ALL_TESTS();
+
+    return (result);
+}

+ 6 - 1
src/bin/d2/kea-dhcp-ddns.xml

@@ -2,7 +2,7 @@
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                [<!ENTITY mdash "&#8212;">]>
                [<!ENTITY mdash "&#8212;">]>
 <!--
 <!--
- - Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2013-2016 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
@@ -179,6 +179,11 @@
       </citerefentry>,
       </citerefentry>,
 
 
       <citerefentry>
       <citerefentry>
+        <refentrytitle>kea-ctrl-agent</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
         <refentrytitle>kea-admin</refentrytitle>
         <refentrytitle>kea-admin</refentrytitle>
         <manvolnum>8</manvolnum>
         <manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,

+ 6 - 1
src/bin/dhcp4/kea-dhcp4.xml

@@ -2,7 +2,7 @@
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                [<!ENTITY mdash "&#8212;">]>
                [<!ENTITY mdash "&#8212;">]>
 <!--
 <!--
- - Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2011-2016 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
@@ -184,6 +184,11 @@
       </citerefentry>,
       </citerefentry>,
 
 
       <citerefentry>
       <citerefentry>
+        <refentrytitle>kea-ctrl-agent</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
         <refentrytitle>kea-admin</refentrytitle>
         <refentrytitle>kea-admin</refentrytitle>
         <manvolnum>8</manvolnum>
         <manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,

+ 1 - 1
src/bin/dhcp6/Makefile.am

@@ -79,8 +79,8 @@ kea_dhcp6_SOURCES  = main.cc
 
 
 kea_dhcp6_LDADD  = libdhcp6.la
 kea_dhcp6_LDADD  = libdhcp6.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/cfgrpt/libcfgrpt.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/cfgrpt/libcfgrpt.la
-kea_dhcp6_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+kea_dhcp6_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la

+ 6 - 1
src/bin/dhcp6/kea-dhcp6.xml

@@ -2,7 +2,7 @@
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                [<!ENTITY mdash "&#8212;">]>
                [<!ENTITY mdash "&#8212;">]>
 <!--
 <!--
- - Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2011-2016 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
@@ -185,6 +185,11 @@
       </citerefentry>,
       </citerefentry>,
 
 
       <citerefentry>
       <citerefentry>
+        <refentrytitle>kea-ctrl-agent</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
         <refentrytitle>kea-admin</refentrytitle>
         <refentrytitle>kea-admin</refentrytitle>
         <manvolnum>8</manvolnum>
         <manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,

+ 5 - 0
src/bin/keactrl/keactrl.xml

@@ -235,6 +235,11 @@
       </citerefentry>,
       </citerefentry>,
 
 
       <citerefentry>
       <citerefentry>
+        <refentrytitle>kea-ctrl-agent</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
         <refentrytitle>kea-admin</refentrytitle>
         <refentrytitle>kea-admin</refentrytitle>
         <manvolnum>8</manvolnum>
         <manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,

+ 6 - 1
src/bin/lfc/kea-lfc.xml

@@ -2,7 +2,7 @@
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
                [<!ENTITY mdash "&#8212;">]>
                [<!ENTITY mdash "&#8212;">]>
 <!--
 <!--
- - Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2015-2016 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
@@ -259,6 +259,11 @@
       </citerefentry>,
       </citerefentry>,
 
 
       <citerefentry>
       <citerefentry>
+        <refentrytitle>kea-ctrl-agent</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
         <refentrytitle>kea-admin</refentrytitle>
         <refentrytitle>kea-admin</refentrytitle>
         <manvolnum>8</manvolnum>
         <manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,

+ 5 - 0
src/bin/perfdhcp/perfdhcp.xml

@@ -934,6 +934,11 @@
       </citerefentry>,
       </citerefentry>,
 
 
       <citerefentry>
       <citerefentry>
+        <refentrytitle>kea-ctrl-agent</refentrytitle>
+        <manvolnum>8</manvolnum>
+      </citerefentry>,
+
+      <citerefentry>
         <refentrytitle>kea-admin</refentrytitle>
         <refentrytitle>kea-admin</refentrytitle>
         <manvolnum>8</manvolnum>
         <manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,

+ 1 - 1
src/lib/testutils/dhcp_test_lib.sh.in

@@ -5,7 +5,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 # A list of Kea processes, mainly used by the cleanup functions.
 # A list of Kea processes, mainly used by the cleanup functions.
-KEA_PROCS="kea-dhcp4 kea-dhcp6 kea-dhcp-ddns"
+KEA_PROCS="kea-dhcp4 kea-dhcp6 kea-dhcp-ddns kea-ctrl-agent"
 
 
 ### Logging functions ###
 ### Logging functions ###