22#include <boost/pointer_cast.hpp> 
   39    static CtrlAgentCommandMgr command_mgr;
 
 
   43CtrlAgentCommandMgr::CtrlAgentCommandMgr()
 
   58    answer_list->add(boost::const_pointer_cast<Element>(answer));
 
 
   70        remote_addr_ = raddr_ptr->stringValue();
 
   72        remote_addr_ = 
"(unknown)";
 
   82    if (original_cmd && original_cmd->contains(
"service")) {
 
   83        services = original_cmd->get(
"service");
 
   95    if (services->empty()) {
 
  109        ElementPtr answer = boost::const_pointer_cast<Element>
 
  122                std::ostringstream s;
 
  123                s << text->stringValue();
 
  124                s << 
" You did not include \"service\" parameter in the command," 
  125                    " which indicates that Kea Control Agent should process this" 
  126                    " command rather than forward it to one or more Kea servers. If you" 
  127                    " aimed to send this command to one of the Kea servers you" 
  128                    " should include the \"service\" parameter in your request, e.g." 
  129                    " \"service\": [ \"dhcp4\" ] to forward the command to the DHCPv4" 
  130                    " server, or \"service\": [ \"dhcp4\", \"dhcp6\", \"d2\" ] to forward it to" 
  131                    " DHCPv4, DHCPv6 and D2 servers etc.";
 
  151        return (answer_list);
 
  159    for (
unsigned i = 0; i < services->size(); ++i) {
 
  165                    .arg(cmd_name).arg(services->get(i)->stringValue());
 
  167                answer = forwardCommand(services->get(i)->stringValue(),
 
  168                                        cmd_name, original_cmd);
 
  173                    .arg(cmd_name).arg(ex.
what());
 
  177            answer_list->add(boost::const_pointer_cast<Element>(answer));
 
  181    return (answer_list);
 
 
  185CtrlAgentCommandMgr::forwardCommand(
const std::string& service,
 
  186                                    const std::string& cmd_name,
 
  195    boost::shared_ptr<CtrlAgentController> controller =
 
  202                ctx = cfgmgr->getCtrlAgentCfgContext();
 
  210        isc_throw(CommandForwardingError, 
"internal server error: unable to retrieve" 
  211                  " Control Agent configuration information");
 
  219        isc_throw(CommandForwardingError, 
"forwarding socket is not configured" 
  220                  " for the server type " << service);
 
  225    if (!socket_info->get(
"validated-socket-name")) {
 
  226        isc_throw(Unexpected, 
"validated-socket-name missing from " 
  227                  << 
" socket_info: " << socket_info->str()
 
  228                  << 
" for the server type " << service);
 
  231    auto socket_name = socket_info->get(
"validated-socket-name")->stringValue();
 
  235    ClientConnection conn(io_service);
 
  236    boost::system::error_code received_ec;
 
  238    conn.start(ClientConnection::SocketPath(socket_name),
 
  239               ClientConnection::ControlCommand(command->toWire()),
 
  240               [&io_service, &received_ec, &received_feed]
 
  244                   received_feed = feed;
 
  247                   io_service->stopWork();
 
  252        isc_throw(CommandForwardingError, 
"unable to forward command to the " 
  253                  << service << 
" service: " << received_ec.message()
 
  254                  << 
". The server is likely to be offline");
 
  260    if (!received_feed) {
 
  261        isc_throw(CommandForwardingError, 
"internal server error: empty response" 
  262                  " received from the unix domain socket");
 
  267        answer = received_feed->toElement();
 
  274    } 
catch (
const std::exception& ex) {
 
  275        isc_throw(CommandForwardingError, 
"internal server error: unable to parse" 
  276                  " server's answer to the forwarded message: " << ex.what());
 
static ElementPtr create(const Position &pos=ZERO_POSITION())
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Exception thrown when an error occurred during control command forwarding.
Command Manager for Control Agent.
virtual isc::data::ConstElementPtr handleCommand(const std::string &cmd_name, const isc::data::ConstElementPtr ¶ms, const isc::data::ConstElementPtr &original_cmd)
Handles the command having a given name and arguments.
static CtrlAgentCommandMgr & instance()
Returns sole instance of the Command Manager.
virtual isc::data::ConstElementPtr processCommand(const isc::data::ConstElementPtr &cmd)
Triggers command processing.
static process::DControllerBasePtr & instance()
Static singleton instance method.
virtual isc::data::ConstElementPtr processCommand(const isc::data::ConstElementPtr &cmd)
Triggers command processing.
Command Manager which can delegate commands to a hook library.
virtual isc::data::ConstElementPtr handleCommand(const std::string &cmd_name, const isc::data::ConstElementPtr ¶ms, const isc::data::ConstElementPtr &original_cmd)
Handles the command having a given name and arguments.
bool delegateCommandToHookLibrary(const std::string &cmd_name, const isc::data::ConstElementPtr ¶ms, const isc::data::ConstElementPtr &original_cmd, isc::data::ElementPtr &answer)
Handles the command within the hooks libraries.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
const isc::log::MessageID CTRL_AGENT_COMMAND_FORWARD_BEGIN
boost::shared_ptr< CtrlAgentCfgContext > CtrlAgentCfgContextPtr
Pointer to a configuration context.
boost::shared_ptr< CtrlAgentProcess > CtrlAgentProcessPtr
Defines a shared pointer to CtrlAgentProcess.
const isc::log::MessageID CTRL_AGENT_COMMAND_FORWARDED
isc::log::Logger agent_logger("ctrl-agent")
Control Agent logger.
boost::shared_ptr< CtrlAgentCfgMgr > CtrlAgentCfgMgrPtr
Defines a shared pointer to CtrlAgentCfgMgr.
const isc::log::MessageID CTRL_AGENT_COMMAND_RECEIVED
const isc::log::MessageID CTRL_AGENT_COMMAND_FORWARD_FAILED
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
boost::shared_ptr< const JSONFeed > ConstJSONFeedPtr
Pointer to the const JSONFeed.
const char * CONTROL_TEXT
String used for storing textual description ("text")
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
Parses a standard config/command level answer and returns arguments or text status code.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_COMMAND_UNSUPPORTED
Status code indicating that the specified command is not supported.
constexpr long TIMEOUT_AGENT_FORWARD_COMMAND
Timeout for the Control Agent to forward command to a Kea server, e.g.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
const int DBGLVL_COMMAND
This debug level is reserved for logging the exchange of messages/commands between processes,...
Defines the logger used by the top-level component of kea-lfc.