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 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):
     """Merges the contents of new into orig, think recursive update()
        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():
             cur_el = cur_el[id]
         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 = cur_el[id]
     # 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
 
 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):
         d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
         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 errors = Element::createFromString("[]");
-    std::cout << "handleConfigUpdate " << new_config << std::endl;
     if (!config_handler_) {
         answer = createAnswer(1, module_name_ + " does not have a config handler");
     } 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
         isc::data::removeIdentical(new_config, getConfig());
         // handle config update
-        std::cout << "handleConfigUpdate " << new_config << std::endl;
         answer = config_handler_(new_config);
         int rcode;
         parseAnswer(rcode, answer);
@@ -232,7 +230,6 @@ ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
             isc::data::merge(config_, new_config);
         }
     }
-    std::cout << "end handleConfigUpdate " << new_config << std::endl;
     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):
                         answer = create_answer(1, " ".join(errors))
                     else:
+                        isc.cc.data.remove_identical(new_config, self.get_local_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:
                     if self._command_handler:
                         answer = self._command_handler(cmd, arg)
                     else:
                         answer = create_answer(2, self._module_name + " has no command handler")
             except Exception as exc:
+                print("error! " + str(exc))
                 answer = create_answer(1, str(exc))
+                raise exc
             if answer:
                 self._session.group_reply(env, answer)