From 33f2f0f5f34ffcd06898c55b7fb1c17c72600dd7 Mon Sep 17 00:00:00 2001 From: Jelte Jansen Date: Fri, 19 Feb 2010 12:54:14 +0000 Subject: [PATCH] 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 --- src/bin/auth/auth_srv.cc | 4 +- src/bin/auth/main.cc | 5 +-- src/lib/cc/cpp/data.h | 1 - src/lib/config/cpp/ccsession.cc | 68 +++++++++++++++++++++++++-------- src/lib/config/cpp/ccsession.h | 17 ++++++++- 5 files changed, 71 insertions(+), 24 deletions(-) diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc index 7045f8163..d8bd2db25 100644 --- a/src/bin/auth/auth_srv.cc +++ b/src/bin/auth/auth_srv.cc @@ -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); } diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc index 2fe39e89f..df050a5a6 100644 --- a/src/bin/auth/main.cc +++ b/src/bin/auth/main.cc @@ -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; } diff --git a/src/lib/cc/cpp/data.h b/src/lib/cc/cpp/data.h index 76ac36f19..ad1fa49ba 100644 --- a/src/lib/cc/cpp/data.h +++ b/src/lib/cc/cpp/data.h @@ -35,7 +35,6 @@ typedef boost::shared_ptr 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) : diff --git a/src/lib/config/cpp/ccsession.cc b/src/lib/config/cpp/ccsession.cc index 2531900ef..ae6df1b52 100644 --- a/src/lib/config/cpp/ccsession.cc +++ b/src/lib/config/cpp/ccsession.cc @@ -36,6 +36,7 @@ #include #include #include +#include //#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_) { diff --git a/src/lib/config/cpp/ccsession.h b/src/lib/config/cpp/ccsession.h index d7340c90d..c48cae34e 100644 --- a/src/lib/config/cpp/ccsession.h +++ b/src/lib/config/cpp/ccsession.h @@ -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); } } -- GitLab