4.2.0 policy-handler - periodic reconfigure

- reconfigure == periodically retrieve the policy-handler config
  from consul-kv and compare to previous config and subconfigs.
  If changed, reconfigure the subunits
- selectively change one or any settings for the following
  = catch_up timer interval
  = reconfigure timer interval
  = deployment-handler url and params (thread-safe)
  = policy-engine url and params (thread-safe)
  = web-socket url to policy-engine (through a callback)
- each subunit has its own Settings that keep track of changes
- try-catch and metrics around discovery - consul API
- hidden the secrets from logs
- froze the web-socket version to 0.49.0 because 0.50.0
  and 0.51.0 are broken - looking around for stable alternatives
- fixed-adapted the callbacks passed to the web-socket lib
  that changed its API in 0.49.0 and later
- log the stack on the exception occurring in the web-socket lib
- unit test refactoring

Change-Id: Id53bad59660a197f59d9aeb7c05ab761d1060cd0
Signed-off-by: Alex Shatov <alexs@att.com>
Issue-ID: DCAEGEN2-470
diff --git a/policyhandler/policy_utils.py b/policyhandler/policy_utils.py
index da83935..08d26f0 100644
--- a/policyhandler/policy_utils.py
+++ b/policyhandler/policy_utils.py
@@ -141,8 +141,10 @@
         return json_str
 
     @staticmethod
-    def are_the_same(body_1, body_2):
+    def are_the_same(body_1, body_2, json_dumps=None):
         """check whether both objects are the same"""
+        if not json_dumps:
+            json_dumps = json.dumps
         if (body_1 and not body_2) or (not body_1 and body_2):
             Utils._logger.debug("only one is empty %s != %s", body_1, body_2)
             return False
@@ -152,21 +154,21 @@
 
         if isinstance(body_1, list) and isinstance(body_2, list):
             if len(body_1) != len(body_2):
-                Utils._logger.debug("len %s != %s", json.dumps(body_1), json.dumps(body_2))
+                Utils._logger.debug("len %s != %s", json_dumps(body_1), json_dumps(body_2))
                 return False
 
             for val_1, val_2 in zip(body_1, body_2):
-                if not Utils.are_the_same(val_1, val_2):
+                if not Utils.are_the_same(val_1, val_2, json_dumps):
                     return False
             return True
 
         if isinstance(body_1, dict) and isinstance(body_2, dict):
             if body_1.keys() ^ body_2.keys():
-                Utils._logger.debug("keys %s != %s", json.dumps(body_1), json.dumps(body_2))
+                Utils._logger.debug("keys %s != %s", json_dumps(body_1), json_dumps(body_2))
                 return False
 
             for key, val_1 in body_1.items():
-                if not Utils.are_the_same(val_1, body_2[key]):
+                if not Utils.are_the_same(val_1, body_2[key], json_dumps):
                     return False
             return True