#include <config/client_connection.h>
#include <boost/pointer_cast.hpp>
#include <iterator>
+#include <sstream>
#include <string>
#include <vector>
// process the command with hooks libraries (if available) or by one of the
// CA's native handlers.
if (services->empty()) {
- return (HookedCommandMgr::handleCommand(cmd_name, params, original_cmd));
+
+ // It is frequent user error to not include the 'service' parameter in
+ // the commands that should be forwarded to Kea servers. If the command
+ // lacks this parameter the CA will try to process it and often fail
+ // because it is not supported by the CA. In the future we may want to
+ // make this parameter mandatory. For now, we're going to improve the
+ // situation by clearly explaining to the controlling client that the
+ // command is not supported by the CA, but it is possible that he may
+ // achieve what he wants by providing the 'service' parameter.
+
+ // Our interface is very restrictive so we walk around this by const
+ // casting the returned pointer. It is certainly easier to do than
+ // changing the whole data interface.
+ ElementPtr answer = boost::const_pointer_cast<Element>
+ (HookedCommandMgr::handleCommand(cmd_name, params, original_cmd));
+
+ try {
+ // Check what error code was returned by the handler.
+ int rcode = 0;
+ ConstElementPtr text = parseAnswer(rcode, answer);
+
+ // There is a dedicated error code for unsupported command case.
+ if (rcode == CONTROL_RESULT_COMMAND_UNSUPPORTED) {
+
+ // Append the explanatory text to the text reported by the handler.
+ // Smart, eh?
+ std::ostringstream s;
+ s << text->stringValue();
+ s << " You did not include \"service\" parameter in the command,"
+ " which indicates that Kea Control Agent should process this"
+ " command rather than forward it to one or more DHCP servers. If you"
+ " aimed to send this command to one of the DHCP servers you"
+ " should include the \"service\" parameter in your request, e.g."
+ " \"service\": [ \"dhcp4\" ] to forward the command to the DHCPv4"
+ " server, or \"service\": [ \"dhcp4\", \"dhcp6\" ] to forward it to"
+ " both DHCPv4 and DHCPv6 servers etc.";
+
+ answer->set(CONTROL_TEXT, Element::create(s.str()));
+ }
+
+ } catch (...) {
+ // Exceptions are not really possible assuming that the BaseCommandMgr
+ // creates the response correctly.
+ }
+
+ return (answer);
}
ElementPtr answer_list = Element::createList();