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) { ...@@ -120,5 +120,7 @@ AuthSrv::updateConfig(isc::data::ElementPtr config) {
// todo: what to do with port change. restart automatically? // todo: what to do with port change. restart automatically?
// ignore atm // 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) ...@@ -64,18 +64,15 @@ my_config_handler(isc::data::ElementPtr config)
isc::data::ElementPtr isc::data::ElementPtr
my_command_handler(isc::data::ElementPtr command) { 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; cout << "[XX] Handle command: " << endl << command->str() << endl;
if (command->get(0)->stringValue() == "print_message") if (command->get(0)->stringValue() == "print_message")
{ {
cout << command->get(1)->get("message") << endl; cout << command->get(1)->get("message") << endl;
/* let's add that message to our answer as well */ /* let's add that message to our answer as well */
cout << "[XX] answer was: " << answer->str() << endl;
answer->get("result")->add(command->get(1)); answer->get("result")->add(command->get(1));
cout << "[XX] answer now: " << answer->str() << endl;
} }
return answer; return answer;
} }
......
...@@ -35,7 +35,6 @@ typedef boost::shared_ptr<Element> ElementPtr; ...@@ -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 /// is called for an Element that has a wrong type (e.g. int_value on a
/// ListElement) /// ListElement)
/// ///
// todo: include types and called function in the exception
class TypeError : public isc::Exception { class TypeError : public isc::Exception {
public: public:
TypeError(const char* file, size_t line, const char* what) : TypeError(const char* file, size_t line, const char* what) :
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <cc/data.h> #include <cc/data.h>
#include <module_spec.h> #include <module_spec.h>
#include <cc/session.h> #include <cc/session.h>
#include <exceptions/exceptions.h>
//#include "common.h" //#include "common.h"
#include "ccsession.h" #include "ccsession.h"
...@@ -50,8 +51,9 @@ using isc::data::ParseError; ...@@ -50,8 +51,9 @@ using isc::data::ParseError;
namespace isc { namespace isc {
namespace config { namespace config {
/// Creates a standard config/command protocol answer message
ElementPtr ElementPtr
create_answer(const int rcode, const ElementPtr arg) createAnswer(const int rcode, const ElementPtr arg)
{ {
ElementPtr answer = Element::createFromString("{\"result\": []"); ElementPtr answer = Element::createFromString("{\"result\": []");
ElementPtr answer_content = answer->get("result"); ElementPtr answer_content = answer->get("result");
...@@ -61,7 +63,7 @@ create_answer(const int rcode, const ElementPtr arg) ...@@ -61,7 +63,7 @@ create_answer(const int rcode, const ElementPtr arg)
} }
ElementPtr 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 = Element::createFromString("{\"result\": []");
ElementPtr answer_content = answer->get("result"); ElementPtr answer_content = answer->get("result");
...@@ -70,6 +72,28 @@ create_answer(const int rcode, const std::string& arg) ...@@ -70,6 +72,28 @@ create_answer(const int rcode, const std::string& arg)
return answer; 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 void
ModuleCCSession::read_module_specification(const std::string& filename) { ModuleCCSession::read_module_specification(const std::string& filename) {
std::ifstream file; std::ifstream file;
...@@ -126,14 +150,33 @@ ModuleCCSession::ModuleCCSession(std::string spec_file_name, ...@@ -126,14 +150,33 @@ ModuleCCSession::ModuleCCSession(std::string spec_file_name,
session_.group_sendmsg(cmd, "ConfigManager"); session_.group_sendmsg(cmd, "ConfigManager");
session_.group_recvmsg(env, answer, false); session_.group_recvmsg(env, answer, false);
cout << "[XX] got config: " << endl << answer->str() << endl; cout << "[XX] got config: " << endl << answer->str() << endl;
if (answer->contains("result") && int rcode;
answer->get("result")->get(0)->intValue() == 0 && ElementPtr new_config = parseAnswer(rcode, answer);
answer->get("result")->size() > 1) { handleConfigUpdate(new_config);
config_handler(answer->get("result")->get(1)); }
} else { }
cout << "[XX] no result in answer" << endl;
/// 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 int
...@@ -157,14 +200,7 @@ ModuleCCSession::check_command() ...@@ -157,14 +200,7 @@ ModuleCCSession::check_command()
ElementPtr answer; ElementPtr answer;
if (data->contains("config_update")) { if (data->contains("config_update")) {
ElementPtr new_config = data->get("config_update"); ElementPtr new_config = data->get("config_update");
if (!config_handler_) { answer = handleConfigUpdate(new_config);
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);
}
} }
if (data->contains("command")) { if (data->contains("command")) {
if (command_handler_) { if (command_handler_) {
......
...@@ -26,6 +26,18 @@ ...@@ -26,6 +26,18 @@
namespace isc { namespace isc {
namespace config { 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 { class ModuleCCSession {
public: public:
/** /**
...@@ -72,7 +84,7 @@ public: ...@@ -72,7 +84,7 @@ public:
* This protocol is very likely to change. * This protocol is very likely to change.
*/ */
void set_command_handler(isc::data::ElementPtr(*command_handler)(isc::data::ElementPtr command)) { command_handler_ = command_handler; }; void set_command_handler(isc::data::ElementPtr(*command_handler)(isc::data::ElementPtr command)) { command_handler_ = command_handler; };
private: private:
void read_module_specification(const std::string& filename); void read_module_specification(const std::string& filename);
...@@ -80,13 +92,14 @@ private: ...@@ -80,13 +92,14 @@ private:
isc::cc::Session session_; isc::cc::Session session_;
ModuleSpec module_specification_; ModuleSpec module_specification_;
isc::data::ElementPtr config_; isc::data::ElementPtr config_;
ElementPtr handleConfigUpdate(ElementPtr new_config);
isc::data::ElementPtr(*config_handler_)(isc::data::ElementPtr new_config); isc::data::ElementPtr(*config_handler_)(isc::data::ElementPtr new_config);
isc::data::ElementPtr(*command_handler_)(isc::data::ElementPtr command); isc::data::ElementPtr(*command_handler_)(isc::data::ElementPtr command);
}; };
ElementPtr createAnswer(const int rcode, const ElementPtr arg); 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