22 #include <boost/pointer_cast.hpp>
38 CtrlAgentCommandMgr::instance() {
43 CtrlAgentCommandMgr::CtrlAgentCommandMgr()
51 ConstElementPtr answer = handleCommandInternal(cmd_name, params, original_cmd);
53 if (answer->getType() == Element::list) {
61 ElementPtr answer_list = Element::createList();
62 answer_list->add(boost::const_pointer_cast<Element>(answer));
69 CtrlAgentCommandMgr::handleCommandInternal(std::string cmd_name,
77 if (original_cmd && original_cmd->contains(
"service")) {
78 services = original_cmd->get(
"service");
81 if (services->getType() != Element::list) {
90 if (services->empty()) {
104 ElementPtr answer = boost::const_pointer_cast<Element>
105 (HookedCommandMgr::handleCommand(cmd_name, params, original_cmd));
117 std::ostringstream s;
118 s << text->stringValue();
119 s <<
" You did not include \"service\" parameter in the command,"
120 " which indicates that Kea Control Agent should process this"
121 " command rather than forward it to one or more DHCP servers. If you"
122 " aimed to send this command to one of the DHCP servers you"
123 " should include the \"service\" parameter in your request, e.g."
124 " \"service\": [ \"dhcp4\" ] to forward the command to the DHCPv4"
125 " server, or \"service\": [ \"dhcp4\", \"dhcp6\" ] to forward it to"
126 " both DHCPv4 and DHCPv6 servers etc.";
139 ElementPtr answer_list = Element::createList();
143 if (HookedCommandMgr::delegateCommandToHookLibrary(cmd_name, params, original_cmd,
146 return (answer_list);
151 answer_list = Element::createList();
154 for (
unsigned i = 0; i < services->size(); ++i) {
159 CTRL_AGENT_COMMAND_FORWARD_BEGIN)
160 .arg(cmd_name).arg(services->get(i)->stringValue());
162 answer = forwardCommand(services->get(i)->stringValue(),
163 cmd_name, original_cmd);
165 }
catch (
const CommandForwardingError& ex) {
167 CTRL_AGENT_COMMAND_FORWARD_FAILED)
168 .arg(cmd_name).arg(ex.what());
172 answer_list->add(boost::const_pointer_cast<Element>(answer));
176 return (answer_list);
180 CtrlAgentCommandMgr::forwardCommand(
const std::string& service,
181 const std::string& cmd_name,
190 boost::shared_ptr<CtrlAgentController> controller =
197 ctx = cfgmgr->getCtrlAgentCfgContext();
205 isc_throw(CommandForwardingError,
"internal server error: unable to retrieve"
206 " Control Agent configuration information");
214 isc_throw(CommandForwardingError,
"forwarding socket is not configured"
215 " for the server type " << service);
220 std::string socket_name = socket_info->get(
"socket-name")->stringValue();
225 boost::system::error_code received_ec;
229 [&io_service, &received_ec, &received_feed]
233 received_feed = feed;
236 io_service->stopWork();
241 isc_throw(CommandForwardingError,
"unable to forward command to the "
242 << service <<
" service: " << received_ec.message()
243 <<
". The server is likely to be offline");
249 if (!received_feed) {
250 isc_throw(CommandForwardingError,
"internal server error: empty response"
251 " received from the unix domain socket");
256 answer = received_feed->toElement();
259 .arg(cmd_name).arg(service);
261 }
catch (
const std::exception& ex) {
262 isc_throw(CommandForwardingError,
"internal server error: unable to parse"
263 " server's answer to the forwarded message: " << ex.what());