Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
ceb361c7
Commit
ceb361c7
authored
Dec 02, 2016
by
Marcin Siodelski
Browse files
[5075] Created Control Agent application stub.
parent
16be7fe3
Changes
22
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
ceb361c7
...
...
@@ -1512,6 +1512,9 @@ AC_CONFIG_FILES([compatcheck/Makefile
Makefile
src/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/tests/Makefile
src/bin/d2/tests/d2_process_tests.sh
...
...
src/bin/Makefile.am
View file @
ceb361c7
# 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
src/bin/agent/.gitignore
0 → 100644
View file @
ceb361c7
/kea-ctrl-agent
/ctrl_agent_messages.cc
/ctrl_agent_messages.h
/s-messages
src/bin/agent/Makefile.am
0 → 100644
View file @
ceb361c7
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 agent.dox
#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/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/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/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)
src/bin/agent/ctrl_agent_cfg_mgr.cc
0 → 100644
View file @
ceb361c7
// 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
src/bin/agent/ctrl_agent_cfg_mgr.h
0 → 100644
View file @
ceb361c7
// 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>
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
::
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
src/bin/agent/ctrl_agent_controller.cc
0 → 100644
View file @
ceb361c7
// 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
src/bin/agent/ctrl_agent_controller.h
0 → 100644
View file @
ceb361c7
// 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
src/bin/agent/ctrl_agent_log.cc
0 → 100644
View file @
ceb361c7
// 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
src/bin/agent/ctrl_agent_log.h
0 → 100644
View file @
ceb361c7
// 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
src/bin/agent/ctrl_agent_messages.mes
0 → 100644
View file @
ceb361c7
# 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 Angent 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.
src/bin/agent/ctrl_agent_process.cc
0 → 100644
View file @
ceb361c7
// 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>
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
src/bin/agent/ctrl_agent_process.h
0 → 100644
View file @
ceb361c7
// 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