1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// Copyright (C) 2017 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 <cc/command_interpreter.h>
#include <config/base_command_mgr.h>
#include <config/config_log.h>
#include <boost/bind.hpp>
using namespace isc::data;
namespace isc {
namespace config {
BaseCommandMgr::BaseCommandMgr() {
registerCommand("list-commands", boost::bind(&BaseCommandMgr::listCommandsHandler,
this, _1, _2));
}
void
BaseCommandMgr::registerCommand(const std::string& cmd, CommandHandler handler) {
if (!handler) {
isc_throw(InvalidCommandHandler, "Specified command handler is NULL");
}
HandlerContainer::const_iterator it = handlers_.find(cmd);
if (it != handlers_.end()) {
isc_throw(InvalidCommandName, "Handler for command '" << cmd
<< "' is already installed.");
}
handlers_.insert(make_pair(cmd, handler));
LOG_DEBUG(command_logger, DBG_COMMAND, COMMAND_REGISTERED).arg(cmd);
}
void
BaseCommandMgr::deregisterCommand(const std::string& cmd) {
if (cmd == "list-commands") {
isc_throw(InvalidCommandName,
"Can't uninstall internal command 'list-commands'");
}
HandlerContainer::iterator it = handlers_.find(cmd);
if (it == handlers_.end()) {
isc_throw(InvalidCommandName, "Handler for command '" << cmd
<< "' not found.");
}
handlers_.erase(it);
LOG_DEBUG(command_logger, DBG_COMMAND, COMMAND_DEREGISTERED).arg(cmd);
}
void
BaseCommandMgr::deregisterAll() {
// No need to log anything here. deregisterAll is not used in production
// code, just in tests.
handlers_.clear();
registerCommand("list-commands",
boost::bind(&BaseCommandMgr::listCommandsHandler, this, _1, _2));
}
isc::data::ConstElementPtr
BaseCommandMgr::processCommand(const isc::data::ConstElementPtr& cmd) {
if (!cmd) {
return (createAnswer(CONTROL_RESULT_ERROR,
"Command processing failed: NULL command parameter"));
}
try {
ConstElementPtr arg;
std::string name = parseCommand(arg, cmd);
LOG_INFO(command_logger, COMMAND_RECEIVED).arg(name);
return (handleCommand(name, arg));
} catch (const Exception& e) {
LOG_WARN(command_logger, COMMAND_PROCESS_ERROR2).arg(e.what());
return (createAnswer(CONTROL_RESULT_ERROR,
std::string("Error during command processing: ")
+ e.what()));
}
}
ConstElementPtr
BaseCommandMgr::handleCommand(const std::string& cmd_name,
const ConstElementPtr& params) {
auto it = handlers_.find(cmd_name);
if (it == handlers_.end()) {
// Ok, there's no such command.
return (createAnswer(CONTROL_RESULT_ERROR,
"'" + cmd_name + "' command not supported."));
}
// Call the actual handler and return whatever it returned
return (it->second(cmd_name, params));
}
isc::data::ConstElementPtr
BaseCommandMgr::listCommandsHandler(const std::string& name,
const isc::data::ConstElementPtr& ) {
using namespace isc::data;
ElementPtr commands = Element::createList();
for (HandlerContainer::const_iterator it = handlers_.begin();
it != handlers_.end(); ++it) {
commands->add(Element::create(it->first));
}
return (createAnswer(CONTROL_RESULT_SUCCESS, commands));
}
} // namespace isc::config
} // namespace isc
|