Browse Source

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

Jelte Jansen 15 years ago
parent
commit
33f2f0f5f3

+ 3 - 1
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);
 }

+ 1 - 4
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;
 }
 

+ 0 - 1
src/lib/cc/cpp/data.h

@@ -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) :

+ 52 - 16
src/lib/config/cpp/ccsession.cc

@@ -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_) {

+ 15 - 2
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);
 
 }
 }