Commit 33f2f0f5 authored by Jelte Jansen's avatar Jelte Jansen

add parseAnswer helper function

moved two sets of common code into one private handleConfigUpdate function


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jelte-configuration@881 e5f2f494-b856-4b98-b285-d166d9295462
parent da8e6967
......@@ -120,5 +120,7 @@ AuthSrv::updateConfig(isc::data::ElementPtr config) {
// todo: what to do with port change. restart automatically?
// ignore atm
//}
return isc::data::Element::createFromString("{ \"result\": [0] }");
std::cout << "[XX] auth: new config " << config << std::endl;
return isc::config::createAnswer(0);
}
......@@ -64,18 +64,15 @@ my_config_handler(isc::data::ElementPtr config)
isc::data::ElementPtr
my_command_handler(isc::data::ElementPtr command) {
isc::data::ElementPtr answer = isc::data::Element::createFromString("{ \"result\": [0] }");
isc::data::ElementPtr answer = isc::config::createAnswer(0);
cout << "[XX] Handle command: " << endl << command->str() << endl;
if (command->get(0)->stringValue() == "print_message")
{
cout << command->get(1)->get("message") << endl;
/* let's add that message to our answer as well */
cout << "[XX] answer was: " << answer->str() << endl;
answer->get("result")->add(command->get(1));
cout << "[XX] answer now: " << answer->str() << endl;
}
return answer;
}
......
......@@ -35,7 +35,6 @@ typedef boost::shared_ptr<Element> ElementPtr;
/// is called for an Element that has a wrong type (e.g. int_value on a
/// ListElement)
///
// todo: include types and called function in the exception
class TypeError : public isc::Exception {
public:
TypeError(const char* file, size_t line, const char* what) :
......
......@@ -36,6 +36,7 @@
#include <cc/data.h>
#include <module_spec.h>
#include <cc/session.h>
#include <exceptions/exceptions.h>
//#include "common.h"
#include "ccsession.h"
......@@ -50,8 +51,9 @@ using isc::data::ParseError;
namespace isc {
namespace config {
/// Creates a standard config/command protocol answer message
ElementPtr
create_answer(const int rcode, const ElementPtr arg)
createAnswer(const int rcode, const ElementPtr arg)
{
ElementPtr answer = Element::createFromString("{\"result\": []");
ElementPtr answer_content = answer->get("result");
......@@ -61,7 +63,7 @@ create_answer(const int rcode, const ElementPtr arg)
}
ElementPtr
create_answer(const int rcode, const std::string& arg)
createAnswer(const int rcode, const std::string& arg)
{
ElementPtr answer = Element::createFromString("{\"result\": []");
ElementPtr answer_content = answer->get("result");
......@@ -70,6 +72,28 @@ create_answer(const int rcode, const std::string& arg)
return answer;
}
ElementPtr
parseAnswer(int &rcode, const ElementPtr msg)
{
if (!msg->contains("result")) {
// TODO: raise CCSessionError exception
dns_throw(CCSessionError, "No result in answer message");
} else {
ElementPtr result = msg->get("result");
if (result->get(0)->getType() != Element::integer) {
dns_throw(CCSessionError, "First element of result is not an rcode in answer message");
} else if (result->get(0)->intValue() != 0 && result->get(1)->getType() != Element::string) {
dns_throw(CCSessionError, "Rcode in answer message is non-zero, but other argument is not a StringElement");
}
rcode = result->get(0)->intValue();
if (result->size() > 1) {
return result->get(1);
} else {
return ElementPtr();
}
}
}
void
ModuleCCSession::read_module_specification(const std::string& filename) {
std::ifstream file;
......@@ -126,14 +150,33 @@ ModuleCCSession::ModuleCCSession(std::string spec_file_name,
session_.group_sendmsg(cmd, "ConfigManager");
session_.group_recvmsg(env, answer, false);
cout << "[XX] got config: " << endl << answer->str() << endl;
if (answer->contains("result") &&
answer->get("result")->get(0)->intValue() == 0 &&
answer->get("result")->size() > 1) {
config_handler(answer->get("result")->get(1));
} else {
cout << "[XX] no result in answer" << endl;
int rcode;
ElementPtr new_config = parseAnswer(rcode, answer);
handleConfigUpdate(new_config);
}
}
/// Validates the new config values, if they are correct,
/// call the config handler
/// If that results in success, store the new config
ElementPtr
ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
{
ElementPtr answer;
if (!config_handler_) {
answer = createAnswer(1, module_name_ + " does not have a config handler");
} else if (!module_specification_.validate_config(new_config)) {
answer = createAnswer(2, "Error in config validation");
} else {
// handle config update
answer = config_handler_(new_config);
int rcode;
parseAnswer(rcode, answer);
if (rcode == 0) {
config_ = new_config;
}
}
return answer;
}
int
......@@ -157,14 +200,7 @@ ModuleCCSession::check_command()
ElementPtr answer;
if (data->contains("config_update")) {
ElementPtr new_config = data->get("config_update");
if (!config_handler_) {
answer = create_answer(1, module_name_ + " does not have a config handler");
} else if (!module_specification_.validate_config(new_config)) {
answer = create_answer(2, "Error in config validation");
} else {
// handle config update
answer = config_handler_(new_config);
}
answer = handleConfigUpdate(new_config);
}
if (data->contains("command")) {
if (command_handler_) {
......
......@@ -26,6 +26,18 @@
namespace isc {
namespace config {
///
/// \brief A standard cc session 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 {
public:
CCSessionError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
class ModuleCCSession {
public:
/**
......@@ -72,7 +84,7 @@ public:
* This protocol is very likely to change.
*/
void set_command_handler(isc::data::ElementPtr(*command_handler)(isc::data::ElementPtr command)) { command_handler_ = command_handler; };
private:
void read_module_specification(const std::string& filename);
......@@ -80,13 +92,14 @@ private:
isc::cc::Session session_;
ModuleSpec module_specification_;
isc::data::ElementPtr config_;
ElementPtr handleConfigUpdate(ElementPtr new_config);
isc::data::ElementPtr(*config_handler_)(isc::data::ElementPtr new_config);
isc::data::ElementPtr(*command_handler_)(isc::data::ElementPtr command);
};
ElementPtr createAnswer(const int rcode, const ElementPtr arg);
ElementPtr createAnswer(const int rcode, const std::string arg);
ElementPtr createAnswer(const int rcode, const std::string& arg);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment