libkea_cc_la_SOURCES = data.cc data.h
libkea_cc_la_SOURCES += logger.cc logger.h
nodist_libkea_cc_la_SOURCES = cc_messages.cc cc_messages.h
-libkea_cc_la_SOURCES += proto_defs.cc proto_defs.h
libkea_cc_la_LIBADD = $(top_builddir)/src/lib/log/libkea-log.la
CLEANFILES = *.gcno *.gcda session_config.h cc_messages.cc cc_messages.h \
$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/cc/cc_messages.mes
touch $@
-BUILT_SOURCES = session_config.h cc_messages.cc cc_messages.h proto_defs.h
-
-# This rule is here, but we added proto_defs.h to the git repo,
-# so the script is no longer needed.
-#proto_defs.h: $(top_srcdir)/src/lib/util/python/const2hdr.py proto_defs.cc
-# $(PYTHON) $(top_srcdir)/src/lib/util/python/const2hdr.py $(srcdir)/proto_defs.cc $@
+BUILT_SOURCES = session_config.h cc_messages.cc cc_messages.h
EXTRA_DIST = cc_messages.mes
+++ /dev/null
-// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <cc/proto_defs.h>
-
-namespace isc {
-namespace cc {
-
-// Aside from defining the values for the C++ library, this file is also
-// used as direct input of the generator of the python counterpart. Please,
-// keep the syntax here simple and check the generated file
-// (lib/python/isc/cc/proto_defs.py) is correct and sane.
-
-// The constants used in the CC protocol
-// First the header names
-const char* const CC_HEADER_TYPE = "type";
-const char* const CC_HEADER_FROM = "from";
-const char* const CC_HEADER_TO = "to";
-const char* const CC_HEADER_GROUP = "group";
-const char* const CC_HEADER_INSTANCE = "instance";
-const char* const CC_HEADER_SEQ = "seq";
-const char* const CC_HEADER_WANT_ANSWER = "want_answer";
-const char* const CC_HEADER_REPLY = "reply";
-// The commands in the "type" header
-const char* const CC_COMMAND_SEND = "send";
-const char* const CC_COMMAND_SUBSCRIBE = "subscribe";
-const char* const CC_COMMAND_UNSUBSCRIBE = "unsubscribe";
-const char* const CC_COMMAND_GET_LNAME = "getlname";
-const char* const CC_COMMAND_PING = "ping";
-const char* const CC_COMMAND_PONG = "pong";
-const char* const CC_COMMAND_STOP = "stop";
-// The wildcards of some headers
-const char* const CC_TO_WILDCARD = "*";
-const char* const CC_INSTANCE_WILDCARD = "*";
-// Prefixes for groups
-const char* const CC_GROUP_NOTIFICATION_PREFIX = "notifications/";
-// Reply codes
-const int CC_REPLY_NO_RECPT = -1;
-const int CC_REPLY_SUCCESS = 0;
-// Payload in the message
-const char *const CC_PAYLOAD_LNAME = "lname";
-const char *const CC_PAYLOAD_RESULT = "result";
-const char *const CC_PAYLOAD_COMMAND = "command";
-const char *const CC_PAYLOAD_NOTIFICATION = "notification";
-
-}
-}
+++ /dev/null
-// This file is generated from ./proto_defs.cc
-// by the const2hdr.py script.
-// Do not edit, all changes will be lost.
-
-// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef KEA_COMMON_DEFS_H
-#define KEA_COMMON_DEFS_H
-
-// \file proto_defs.h
-// \brief Common shared constants
-
-// This file contains common definitions of constasts used across the sources.
-// It includes, but is not limited to the definitions of messages sent from
-// one process to another. Since the names should be self-explanatory and
-// the variables here are used mostly to synchronize the same values across
-// multiple programs, separate documentation for each variable is not provided.
-
-namespace isc {
-namespace cc {
-
-// Aside from defining the values for the C++ library, this file is also
-// used as direct input of the generator of the python counterpart. Please,
-// keep the syntax here simple and check the generated file
-// (lib/python/isc/cc/proto_defs.py) is correct and sane.
-
-// The constants used in the CC protocol
-// First the header names
-extern const char* const CC_HEADER_TYPE;
-extern const char* const CC_HEADER_FROM;
-extern const char* const CC_HEADER_TO;
-extern const char* const CC_HEADER_GROUP;
-extern const char* const CC_HEADER_INSTANCE;
-extern const char* const CC_HEADER_SEQ;
-extern const char* const CC_HEADER_WANT_ANSWER;
-extern const char* const CC_HEADER_REPLY;
-// The commands in the "type" header
-extern const char* const CC_COMMAND_SEND;
-extern const char* const CC_COMMAND_SUBSCRIBE;
-extern const char* const CC_COMMAND_UNSUBSCRIBE;
-extern const char* const CC_COMMAND_GET_LNAME;
-extern const char* const CC_COMMAND_PING;
-extern const char* const CC_COMMAND_PONG;
-extern const char* const CC_COMMAND_STOP;
-// The wildcards of some headers
-extern const char* const CC_TO_WILDCARD;
-extern const char* const CC_INSTANCE_WILDCARD;
-// Prefixes for groups
-extern const char* const CC_GROUP_NOTIFICATION_PREFIX;
-// Reply codes
-extern const int CC_REPLY_NO_RECPT;
-extern const int CC_REPLY_SUCCESS;
-// Payload in the message
-extern const char *const CC_PAYLOAD_LNAME;
-extern const char *const CC_PAYLOAD_RESULT;
-extern const char *const CC_PAYLOAD_COMMAND;
-extern const char *const CC_PAYLOAD_NOTIFICATION;
-
-}
-}
-#endif
namespace isc {
namespace config {
-/// Creates a standard config/command protocol answer message
-ConstElementPtr
-createAnswer() {
- ElementPtr answer = Element::createMap();
- ElementPtr answer_content = Element::createList();
- answer_content->add(Element::create(isc::cc::CC_REPLY_SUCCESS));
- answer->set(isc::cc::CC_PAYLOAD_RESULT, answer_content);
+const char *CONTROL_COMMAND="command";
- return (answer);
-}
+const char *CONTROL_RESULT="result";
+const char *CONTROL_TEXT="text";
+const char *CONTROL_ARGUMENTS="arguments";
+// Full version, with status, text and arguments
ConstElementPtr
-createAnswer(const int rcode, ConstElementPtr arg) {
- if (rcode != 0 && (!arg || arg->getType() != Element::string)) {
- isc_throw(CCSessionError, "Bad or no argument for rcode != 0");
+createAnswer(const int status_code, const std::string& text,
+ const ConstElementPtr& arg) {
+ if (status_code != 0 && text.empty()) {
+ isc_throw(CtrlChannelError, "Text has to be provided for status_code != 0");
}
+
ElementPtr answer = Element::createMap();
- ElementPtr answer_content = Element::createList();
- answer_content->add(Element::create(rcode));
- answer_content->add(arg);
- answer->set(isc::cc::CC_PAYLOAD_RESULT, answer_content);
+ ElementPtr result = Element::create(status_code);
+ answer->set(CONTROL_RESULT, result);
+ if (!text.empty()) {
+ answer->set(CONTROL_TEXT, Element::create(text));
+ }
+ if (arg) {
+ answer->set(CONTROL_ARGUMENTS, arg);
+ }
return (answer);
}
ConstElementPtr
-createAnswer(const int rcode, const std::string& arg) {
- ElementPtr answer = Element::createMap();
- ElementPtr answer_content = Element::createList();
- answer_content->add(Element::create(rcode));
- answer_content->add(Element::create(arg));
- answer->set(isc::cc::CC_PAYLOAD_RESULT, answer_content);
+createAnswer() {
+ return (createAnswer(0, string(""), ConstElementPtr()));
+}
- return (answer);
+ConstElementPtr
+createAnswer(const int status_code, const std::string& text) {
+ return (createAnswer(status_code, text, ElementPtr()));
}
ConstElementPtr
-parseAnswer(int &rcode, ConstElementPtr msg) {
- if (msg &&
- msg->getType() == Element::map &&
- msg->contains(isc::cc::CC_PAYLOAD_RESULT)) {
- ConstElementPtr result = msg->get(isc::cc::CC_PAYLOAD_RESULT);
- if (result->getType() != Element::list) {
- isc_throw(CCSessionError, "Result element in answer message is not a list");
- } else if (result->get(0)->getType() != Element::integer) {
- isc_throw(CCSessionError, "First element of result is not an rcode in answer message");
- }
- rcode = result->get(0)->intValue();
- if (result->size() > 1) {
- if (rcode == 0 || result->get(1)->getType() == Element::string) {
- return (result->get(1));
- } else {
- isc_throw(CCSessionError, "Error description in result with rcode != 0 is not a string");
- }
- } else {
- if (rcode == 0) {
- return (ElementPtr());
- } else {
- isc_throw(CCSessionError, "Result with rcode != 0 does not have an error description");
- }
- }
- } else {
- isc_throw(CCSessionError, "No result part in answer message");
+createAnswer(const int status_code, const ConstElementPtr& arg) {
+ return (createAnswer(status_code, "", arg));
+}
+
+ConstElementPtr
+parseAnswer(int &rcode, const ConstElementPtr& msg) {
+ if (!msg) {
+ isc_throw(CtrlChannelError, "No answer specified");
+ }
+ if (msg->getType() != Element::map) {
+ isc_throw(CtrlChannelError,
+ "Invalid answer Element specified, expected map");
+ }
+ if (!msg->contains(CONTROL_RESULT)) {
+ isc_throw(CtrlChannelError,
+ "Invalid answer specified, does not contain mandatory 'result'");
+ }
+
+ ConstElementPtr result = msg->get(CONTROL_RESULT);
+ if (result->getType() != Element::integer) {
+ isc_throw(CtrlChannelError,
+ "Result element in answer message is not a string");
}
+
+ rcode = result->intValue();
+
+ // If there are arguments, return them.
+ ConstElementPtr args = msg->get(CONTROL_ARGUMENTS);
+ if (args) {
+ return (args);
+ }
+
+ // There are no arguments, let's try to return just the text status
+ return (msg->get(CONTROL_TEXT));
}
ConstElementPtr
ConstElementPtr
createCommand(const std::string& command, ConstElementPtr arg) {
- ElementPtr cmd = Element::createMap();
- ElementPtr cmd_parts = Element::createList();
- cmd_parts->add(Element::create(command));
+ ElementPtr query = Element::createMap();
+ ElementPtr cmd = Element::create(command);
+ query->set(CONTROL_COMMAND, cmd);
if (arg) {
- cmd_parts->add(arg);
+ query->set(CONTROL_ARGUMENTS, arg);
}
- cmd->set(isc::cc::CC_PAYLOAD_COMMAND, cmd_parts);
- return (cmd);
+ return (query);
}
std::string
parseCommand(ConstElementPtr& arg, ConstElementPtr command) {
- if (command &&
- command->getType() == Element::map &&
- command->contains(isc::cc::CC_PAYLOAD_COMMAND)) {
- ConstElementPtr cmd = command->get(isc::cc::CC_PAYLOAD_COMMAND);
- if (cmd->getType() == Element::list &&
- !cmd->empty() &&
- cmd->get(0)->getType() == Element::string) {
- if (cmd->size() > 1) {
- arg = cmd->get(1);
- } else {
- arg = Element::createMap();
- }
- return (cmd->get(0)->stringValue());
- } else {
- isc_throw(CCSessionError, "Command part in command message missing, empty, or not a list");
- }
- } else {
- isc_throw(CCSessionError, "Command Element empty or not a map with \"command\"");
+ if (!command) {
+ isc_throw(CtrlChannelError, "No command specified");
+ }
+ if (command->getType() != Element::map) {
+ isc_throw(CtrlChannelError, "Invalid command Element specified, expected map");
+ }
+ if (!command->contains(CONTROL_COMMAND)) {
+ isc_throw(CtrlChannelError,
+ "Invalid answer specified, does not contain mandatory 'command'");
}
+
+ ConstElementPtr cmd = command->get(CONTROL_COMMAND);
+ if (cmd->getType() != Element::string) {
+ isc_throw(CtrlChannelError,
+ "'command' element in command message is not a string");
+ }
+
+ arg = command->get(CONTROL_ARGUMENTS);
+
+ return (cmd->stringValue());
}
namespace {
#include <config/module_spec.h>
#include <cc/data.h>
-#include <cc/proto_defs.h>
#include <string>
#include <list>
namespace isc {
namespace config {
-///
-/// \brief Creates a standard config/command level success answer message
-/// (i.e. of the form { "result": [ 0 ] }
-/// \return Standard command/config success answer message
+extern const char *CONTROL_COMMAND;
+
+extern const char *CONTROL_RESULT;
+extern const char *CONTROL_TEXT;
+extern const char *CONTROL_ARGUMENTS;
+
+const int CONTROL_RESULT_SUCCESS = 0;
+const int CONTROL_RESULT_ERROR = 1;
+
+/// @brief Creates a standard config/command level success answer message
+/// (i.e. of the form { "result": 0 }
+/// @return Standard command/config success answer message
isc::data::ConstElementPtr createAnswer();
+/// @brief Creates a standard config/command level answer message
+/// (i.e. of the form { "result": 1, "text": "Invalid command received" }
///
-/// \brief Creates a standard config/command level answer message
-/// (i.e. of the form { "result": [ rcode, arg ] }
-/// If rcode != 0, arg must be a StringElement
-///
-/// \param rcode The return code (0 for success)
-/// \param arg For rcode == 0, this is an optional argument of any
-/// Element type. For rcode == 1, this argument is mandatory,
-/// and must be a StringElement containing an error description
-/// \return Standard command/config answer message
-isc::data::ConstElementPtr createAnswer(const int rcode,
- isc::data::ConstElementPtr arg);
-
+/// @param status_code The return code (0 for success)
+/// @param status_text A string to put into the "text" argument
+/// @return Standard command/config answer message
+isc::data::ConstElementPtr createAnswer(const int status_code,
+ const std::string& status_text);
+
+/// @brief Creates a standard config/command level answer message
+/// (i.e. of the form { "result": status_code, "arguments": arg }
///
-/// \brief Creates a standard config/command level answer message
-/// (i.e. of the form { "result": [ rcode, arg ] }
+/// @param status_code The return code (0 for success)
+/// @param status_text A string to put into the "text" argument
+/// @return Standard command/config answer message
+isc::data::ConstElementPtr createAnswer(const int status_code,
+ const isc::data::ConstElementPtr& arg);
+
+/// @brief Creates a standard config/command level answer message
+/// (i.e. of the form { "result": X, "[ rcode, arg ] }
+/// If rcode != 0, arg must be a StringElement
///
-/// \param rcode The return code (0 for success)
-/// \param arg A string to put into the StringElement argument
-/// \return Standard command/config answer message
-isc::data::ConstElementPtr createAnswer(const int rcode,
- const std::string& arg);
-
+/// @param status_code The return code (0 for success)
+/// @param arg For status_code == 0, this is an optional argument of any
+/// Element type. For status_code == 1, this argument is mandatory,
+/// and may be any type of ElementPtr.
+/// @return Standard command/config answer message
+isc::data::ConstElementPtr createAnswer(const int status_code,
+ const std::string& status,
+ const isc::data::ConstElementPtr& arg);
+
+/// @brief Parses a standard config/command level answer message.
///
-/// Parses a standard config/command level answer message
-///
-/// \param rcode This value will be set to the return code contained in
+/// @param status_code This value will be set to the return code contained in
/// the message
-/// \param msg The message to parse
-/// \return The optional argument in the message, or an empty ElementPtr
+/// @param msg The message to parse
+/// @return The optional argument in the message, or an empty ElementPtr
/// if there was no argument. If rcode != 0, this contains a
/// StringElement with the error description.
-isc::data::ConstElementPtr parseAnswer(int &rcode,
- isc::data::ConstElementPtr msg);
+isc::data::ConstElementPtr parseAnswer(int &status_code,
+ const isc::data::ConstElementPtr& msg);
+/// @brief Creates a standard config/command command message with no
+/// argument (of the form { "command": "my_command" }
///
-/// \brief Creates a standard config/command command message with no
-/// argument (of the form { "command": [ "my_command" ] }
-///
-/// \param command The command string
-/// \return The created message
+/// @param command The command string
+/// @return The created message
isc::data::ConstElementPtr createCommand(const std::string& command);
+/// @brief Creates a standard config/command command message with the
+/// given argument (of the form { "command": "my_command", "arguments": arg }
///
-/// \brief Creates a standard config/command command message with the
-/// given argument (of the form { "command": [ "my_command", arg ] }
-///
-/// \param command The command string
-/// \param arg The optional argument for the command. This can be of
+/// @param command The command string
+/// @param arg The optional argument for the command. This can be of
/// any Element type, but it should conform to the .spec file.
-/// \return The created message
+/// @return The created message
isc::data::ConstElementPtr createCommand(const std::string& command,
isc::data::ConstElementPtr arg);
-///
-/// \brief Parses the given command into a string containing the actual
+/// @brief Parses the given command into a string containing the actual
/// command and an ElementPtr containing the optional argument.
///
-/// Raises a CCSessionError if this is not a well-formed command
+/// @throw Raises a CtrlChannelError if this is not a well-formed command
///
-/// Example code: (command_message is a ConstElementPtr that is
-/// passed here)
-/// \code
-/// ElementPtr command_message = Element::fromJSON("{ \"command\": [\"foo\", { \"bar\": 123 } ] }");
-/// try {
-/// ConstElementPtr args;
-/// std::string command_str = parseCommand(args, command_message);
-/// if (command_str == "foo") {
-/// std::cout << "The command 'foo' was given" << std::endl;
-/// if (args->contains("bar")) {
-/// std::cout << "It had argument name 'bar' set, which has"
-/// << "value "
-/// << args->get("bar")->intValue();
-/// }
-/// } else {
-/// std::cout << "Unknown command '" << command_str << std::endl;
-/// }
-/// } catch (CCSessionError cse) {
-/// std::cerr << "Bad command in CC Session: "
-/// << cse.what() << std::endl;
-/// }
-/// \endcode
-///
-/// \param arg This value will be set to the ElementPtr pointing to
+/// @param arg This value will be set to the ElementPtr pointing to
/// the argument, or to an empty Map (ElementPtr) if there was none.
-/// \param command The command message containing the command (as made
+/// @param command The command message containing the command (as made
/// by createCommand()
/// \return The command name
std::string parseCommand(isc::data::ConstElementPtr& arg,
isc::data::ConstElementPtr command);
-
-///
-/// \brief A standard cc session exception that is thrown if a function
+/// @brief A standard control channel exception that is thrown if a function
/// is there is a problem with one of the messages
-///
-// todo: include types and called function in the exception
-class CCSessionError : public isc::Exception {
+class CtrlChannelError : public isc::Exception {
public:
- CCSessionError(const char* file, size_t line, const char* what) :
+ CtrlChannelError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
using namespace isc::data;
using namespace isc::config;
-using namespace isc::cc;
using namespace std;
namespace {
TEST_F(CCSessionTest, createAnswer) {
ConstElementPtr answer;
answer = createAnswer();
- EXPECT_EQ("{ \"result\": [ 0 ] }", answer->str());
+ EXPECT_EQ("{ \"result\": 0 }", answer->str());
answer = createAnswer(1, "error");
- EXPECT_EQ("{ \"result\": [ 1, \"error\" ] }", answer->str());
+ EXPECT_EQ("{ \"result\": 1, \"text\": \"error\" }", answer->str());
- EXPECT_THROW(createAnswer(1, ElementPtr()), CCSessionError);
- EXPECT_THROW(createAnswer(1, Element::create(1)), CCSessionError);
+ EXPECT_THROW(createAnswer(1, ElementPtr()), CtrlChannelError);
+ EXPECT_THROW(createAnswer(1, Element::create(1)), CtrlChannelError);
ConstElementPtr arg = el("[ \"just\", \"some\", \"data\" ]");
answer = createAnswer(0, arg);
- EXPECT_EQ("{ \"result\": [ 0, [ \"just\", \"some\", \"data\" ] ] }", answer->str());
+ EXPECT_EQ("{ \"arguments\": [ \"just\", \"some\", \"data\" ], \"result\": 0 }",
+ answer->str());
}
TEST_F(CCSessionTest, parseAnswer) {
ConstElementPtr arg;
int rcode;
- EXPECT_THROW(parseAnswer(rcode, ElementPtr()), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("1")), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("[]")), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("{ }")), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("{ \"something\": 1 }")), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": 0 }")), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": 1 }")), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": [ 1 ] }")), CCSessionError);
- EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": [ 1, 1 ] }")), CCSessionError);
+ EXPECT_THROW(parseAnswer(rcode, ElementPtr()), CtrlChannelError);
+ EXPECT_THROW(parseAnswer(rcode, el("1")), CtrlChannelError);
+ EXPECT_THROW(parseAnswer(rcode, el("[]")), CtrlChannelError);
+ EXPECT_THROW(parseAnswer(rcode, el("{ }")), CtrlChannelError);
+ EXPECT_THROW(parseAnswer(rcode, el("{ \"something\": 1 }")), CtrlChannelError);
+ EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": [ 0 ] }")), CtrlChannelError);
+ EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": [ 1 ] }")), CtrlChannelError);
+ EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": [ 1, 1 ] }")), CtrlChannelError);
- answer = el("{ \"result\": [ 0 ] }");
+ answer = el("{ \"result\": 0 }");
arg = parseAnswer(rcode, answer);
EXPECT_EQ(0, rcode);
EXPECT_TRUE(isNull(arg));
- answer = el("{ \"result\": [ 1, \"error\"] }");
+ answer = el("{ \"result\": 1, \"text\": \"error\" }");
arg = parseAnswer(rcode, answer);
EXPECT_EQ(1, rcode);
EXPECT_EQ("error", arg->stringValue());
- answer = el("{ \"result\": [ 0, [ \"just\", \"some\", \"data\" ] ] }");
+ answer = el("{ \"result\": 0, \"arguments\": [ \"just\", \"some\", \"data\" ] }");
arg = parseAnswer(rcode, answer);
EXPECT_EQ(0, rcode);
EXPECT_EQ("[ \"just\", \"some\", \"data\" ]", arg->str());
ConstElementPtr arg;
command = createCommand("my_command");
- ASSERT_EQ("{ \"command\": [ \"my_command\" ] }", command->str());
+ ASSERT_EQ("{ \"command\": \"my_command\" }", command->str());
arg = el("1");
command = createCommand("my_command", arg);
- ASSERT_EQ("{ \"command\": [ \"my_command\", 1 ] }", command->str());
+ ASSERT_EQ("{ \"arguments\": 1, \"command\": \"my_command\" }",
+ command->str());
arg = el("[ \"a\", \"b\" ]");
command = createCommand("my_cmd", arg);
- ASSERT_EQ("{ \"command\": [ \"my_cmd\", [ \"a\", \"b\" ] ] }", command->str());
+ ASSERT_EQ("{ \"arguments\": [ \"a\", \"b\" ], \"command\": \"my_cmd\" }",
+ command->str());
arg = el("{ \"a\": \"map\" }");
command = createCommand("foo", arg);
- ASSERT_EQ("{ \"command\": [ \"foo\", { \"a\": \"map\" } ] }", command->str());
+ ASSERT_EQ("{ \"arguments\": { \"a\": \"map\" }, \"command\": \"foo\" }",
+ command->str());
}
TEST_F(CCSessionTest, parseCommand) {
std::string cmd;
// should throw
- EXPECT_THROW(parseCommand(arg, ElementPtr()), CCSessionError);
- EXPECT_THROW(parseCommand(arg, el("1")), CCSessionError);
- EXPECT_THROW(parseCommand(arg, el("{ }")), CCSessionError);
- EXPECT_THROW(parseCommand(arg, el("{ \"not a command\": 1 }")), CCSessionError);
- EXPECT_THROW(parseCommand(arg, el("{ \"command\": 1 }")), CCSessionError);
- EXPECT_THROW(parseCommand(arg, el("{ \"command\": [] }")), CCSessionError);
- EXPECT_THROW(parseCommand(arg, el("{ \"command\": [ 1 ] }")), CCSessionError);
-
- cmd = parseCommand(arg, el("{ \"command\": [ \"my_command\" ] }"));
+ EXPECT_THROW(parseCommand(arg, ElementPtr()), CtrlChannelError);
+ EXPECT_THROW(parseCommand(arg, el("1")), CtrlChannelError);
+ EXPECT_THROW(parseCommand(arg, el("{ }")), CtrlChannelError);
+ EXPECT_THROW(parseCommand(arg, el("{ \"not a command\": 1 }")), CtrlChannelError);
+ EXPECT_THROW(parseCommand(arg, el("{ \"command\": 1 }")), CtrlChannelError);
+ EXPECT_THROW(parseCommand(arg, el("{ \"command\": [] }")), CtrlChannelError);
+ EXPECT_THROW(parseCommand(arg, el("{ \"command\": [ 1 ] }")), CtrlChannelError);
+
+ cmd = parseCommand(arg, el("{ \"command\": \"my_command\" }"));
EXPECT_EQ("my_command", cmd);
- EXPECT_EQ(*arg, *Element::createMap());
+ EXPECT_FALSE(arg);
- cmd = parseCommand(arg, el("{ \"command\": [ \"my_command\", 1 ] }"));
+ cmd = parseCommand(arg, el("{ \"command\": \"my_command\", \"arguments\": 1 }"));
+ ASSERT_TRUE(arg);
EXPECT_EQ("my_command", cmd);
EXPECT_EQ("1", arg->str());
- parseCommand(arg, el("{ \"command\": [ \"my_command\", [ \"some\", \"argument\", \"list\" ] ] }"));
+ parseCommand(arg, el("{ \"command\": \"my_command\", \"arguments\": [ \"some\", \"argument\", \"list\" ] }"));
EXPECT_EQ("my_command", cmd);
+ ASSERT_TRUE(arg);
EXPECT_EQ("[ \"some\", \"argument\", \"list\" ]", arg->str());
}
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#include <cc/proto_defs.h>
+#include <config/ccsession.h>
#include <dhcpsrv/testutils/config_result_check.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/constants.hpp>
bool errorContainsPosition(ConstElementPtr error_element,
const std::string& file_name) {
- if (error_element->contains(isc::cc::CC_PAYLOAD_RESULT)) {
- ConstElementPtr result = error_element->get(isc::cc::CC_PAYLOAD_RESULT);
- if ((result->getType() != Element::list) || (result->size() < 2) ||
- (result->get(1)->getType() != Element::string)) {
+ if (error_element->contains(isc::config::CONTROL_RESULT)) {
+ ConstElementPtr result = error_element->get(isc::config::CONTROL_RESULT);
+ ConstElementPtr text = error_element->get(isc::config::CONTROL_TEXT);
+ if (!result || (result->getType() != Element::integer) || !text
+ || (text->getType() != Element::string)) {
return (false);
}
// Get the error message in the textual format.
- std::string error_string = result->get(1)->stringValue();
+ std::string error_string = text->stringValue();
// The position of the data element causing an error has the following
// format: <filename>:<linenum>:<pos>. The <filename> has been specified