Browse Source

same things for python side;
added remove_identical(), fixed a small problem in merge()
ModuleCCSession now only calls the config handler with a dict containing the values that have acutally changed
+tests


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1043 e5f2f494-b856-4b98-b285-d166d9295462

Jelte Jansen 15 years ago
parent
commit
ede5b4df74

+ 16 - 0
src/lib/cc/python/isc/cc/data.py

@@ -25,6 +25,18 @@ import ast
 class DataNotFoundError(Exception): pass
 class DataNotFoundError(Exception): pass
 class DataTypeError(Exception): pass
 class DataTypeError(Exception): pass
 
 
+def remove_identical(a, b):
+    """Removes the values from dict a that are the same as in dict b.
+       Raises a DataTypeError is a or b is not a dict"""
+    to_remove = []
+    if type(a) != dict or type(b) != dict:
+        raise DataTypeError("Not a dict in remove_identical()")
+    for ka in a.keys():
+        if ka in b and a[ka] == b[ka]:
+            to_remove.append(ka)
+    for id in to_remove:
+        del(a[id])
+
 def merge(orig, new):
 def merge(orig, new):
     """Merges the contents of new into orig, think recursive update()
     """Merges the contents of new into orig, think recursive update()
        orig and new must both be dicts. If an element value is None in
        orig and new must both be dicts. If an element value is None in
@@ -78,6 +90,10 @@ def set(element, identifier, value):
         if id in cur_el.keys():
         if id in cur_el.keys():
             cur_el = cur_el[id]
             cur_el = cur_el[id]
         else:
         else:
+            if value == None:
+                # ok we are unsetting a value that wasn't set in
+                # the first place. Simply stop.
+                return
             cur_el[id] = {}
             cur_el[id] = {}
             cur_el = cur_el[id]
             cur_el = cur_el[id]
     # value can be an empty list or dict, so check for None eplicitely
     # value can be an empty list or dict, so check for None eplicitely

+ 49 - 0
src/lib/cc/python/isc/cc/data_test.py

@@ -22,6 +22,55 @@ import os
 import data
 import data
 
 
 class TestData(unittest.TestCase):
 class TestData(unittest.TestCase):
+    def test_remove_identical(self):
+        a = {}
+        b = {}
+        c = {}
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+
+        a = { "a": 1 }
+        b = { "a": 1 }
+        c = {}
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+    
+        a = { "a": 1, "b": [ 1, 2 ] }
+        b = {}
+        c = { "a": 1, "b": [ 1, 2 ] }
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+    
+        a = { "a": 1, "b": [ 1, 2 ] }
+        b = { "a": 1, "b": [ 1, 2 ] }
+        c = {}
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+    
+        a = { "a": 1, "b": [ 1, 2 ] }
+        b = { "a": 1, "b": [ 1, 3 ] }
+        c = { "b": [ 1, 2 ] }
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+    
+        a = { "a": { "b": "c" } }
+        b = {}
+        c = { "a": { "b": "c" } }
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+    
+        a = { "a": { "b": "c" } }
+        b = { "a": { "b": "c" } }
+        c = {}
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+    
+        a = { "a": { "b": "c" } }
+        b = { "a": { "b": "d" } }
+        c = { "a": { "b": "c" } }
+        data.remove_identical(a, b)
+        self.assertEqual(a, c)
+        
     def test_merge(self):
     def test_merge(self):
         d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
         d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
         d2 = { 'a': None, 'c': { 'd': None, 'e': 3, 'f': [ 1 ] } }
         d2 = { 'a': None, 'c': { 'd': None, 'e': 3, 'f': [ 1 ] } }

+ 0 - 3
src/lib/config/cpp/ccsession.cc

@@ -210,7 +210,6 @@ ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
 {
 {
     ElementPtr answer;
     ElementPtr answer;
     ElementPtr errors = Element::createFromString("[]");
     ElementPtr errors = Element::createFromString("[]");
-    std::cout << "handleConfigUpdate " << new_config << std::endl;
     if (!config_handler_) {
     if (!config_handler_) {
         answer = createAnswer(1, module_name_ + " does not have a config handler");
         answer = createAnswer(1, module_name_ + " does not have a config handler");
     } else if (!module_specification_.validate_config(new_config, false, errors)) {
     } else if (!module_specification_.validate_config(new_config, false, errors)) {
@@ -224,7 +223,6 @@ ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
         // remove the values that have not changed
         // remove the values that have not changed
         isc::data::removeIdentical(new_config, getConfig());
         isc::data::removeIdentical(new_config, getConfig());
         // handle config update
         // handle config update
-        std::cout << "handleConfigUpdate " << new_config << std::endl;
         answer = config_handler_(new_config);
         answer = config_handler_(new_config);
         int rcode;
         int rcode;
         parseAnswer(rcode, answer);
         parseAnswer(rcode, answer);
@@ -232,7 +230,6 @@ ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
             isc::data::merge(config_, new_config);
             isc::data::merge(config_, new_config);
         }
         }
     }
     }
-    std::cout << "end handleConfigUpdate " << new_config << std::endl;
     return answer;
     return answer;
 }
 }
 
 

+ 8 - 0
src/lib/config/python/isc/config/ccsession.py

@@ -189,14 +189,22 @@ class ModuleCCSession(ConfigData):
                     elif not self.get_module_spec().validate_config(False, new_config, errors):
                     elif not self.get_module_spec().validate_config(False, new_config, errors):
                         answer = create_answer(1, " ".join(errors))
                         answer = create_answer(1, " ".join(errors))
                     else:
                     else:
+                        isc.cc.data.remove_identical(new_config, self.get_local_config())
                         answer = self._config_handler(new_config)
                         answer = self._config_handler(new_config)
+                        rcode, val = parse_answer(answer)
+                        if rcode == 0:
+                            newc = self.get_local_config()
+                            isc.cc.data.merge(newc, new_config)
+                            self.set_local_config(newc)
                 else:
                 else:
                     if self._command_handler:
                     if self._command_handler:
                         answer = self._command_handler(cmd, arg)
                         answer = self._command_handler(cmd, arg)
                     else:
                     else:
                         answer = create_answer(2, self._module_name + " has no command handler")
                         answer = create_answer(2, self._module_name + " has no command handler")
             except Exception as exc:
             except Exception as exc:
+                print("error! " + str(exc))
                 answer = create_answer(1, str(exc))
                 answer = create_answer(1, str(exc))
+                raise exc
             if answer:
             if answer:
                 self._session.group_reply(env, answer)
                 self._session.group_reply(env, answer)