VOL-1330: Fix mib reconcile

mib db queries in converting from internal json
storage back to dict() overwrote the original
json in storage.  This caused subquent queries to fail.
Need a deepcopy to prevent the reference copy/overwrite.

In allowing adapters to run resync/reconcile we need to
allow classes that use openomci to disable auditing.
Some onu (brcm) do not allow uploading of mib after its configured
causing audit and resync timeoutes.

Change-Id: Ia45ca958340ec4e0b11684adb35cc8e4beda32ae
diff --git a/pyvoltha/adapters/extensions/omci/database/mib_db_dict.py b/pyvoltha/adapters/extensions/omci/database/mib_db_dict.py
index 6a7de8f..dbf23cc 100644
--- a/pyvoltha/adapters/extensions/omci/database/mib_db_dict.py
+++ b/pyvoltha/adapters/extensions/omci/database/mib_db_dict.py
@@ -387,7 +387,7 @@
         :raises DatabaseStateError: If the database is not enabled
         """
         self.log.debug('query', device_id=device_id, class_id=class_id,
-                       instance_id=instance_id, attributes=attributes)
+                       entity_instance_id=instance_id, attributes=attributes)
 
         if not self._started:
             raise DatabaseStateError('The Database is not currently active')
@@ -395,9 +395,9 @@
         if not isinstance(device_id, basestring):
             raise TypeError('Device ID is a string')
 
-        device_db = self._data[device_id]
+        device_db = self._data.get(device_id, dict())
         if class_id is None:
-            return self._fix_dev_json_attributes(copy.copy(device_db), device_id)
+            return self._fix_dev_json_attributes(copy.deepcopy(device_db), device_id)
 
         if not isinstance(class_id, int):
             raise TypeError('Class ID is an integer')
@@ -407,14 +407,14 @@
 
         class_db = device_db.get(class_id, dict())
         if instance_id is None or len(class_db) == 0:
-            return self._fix_cls_json_attributes(copy.copy(class_db), entity)
+            return self._fix_cls_json_attributes(copy.deepcopy(class_db), entity)
 
         if not isinstance(instance_id, int):
             raise TypeError('Instance ID is an integer')
 
         instance_db = class_db.get(instance_id, dict())
         if attributes is None or len(instance_db) == 0:
-            return self._fix_inst_json_attributes(copy.copy(instance_db), entity)
+            return self._fix_inst_json_attributes(copy.deepcopy(instance_db), entity)
 
         if not isinstance(attributes, (basestring, list, set)):
             raise TypeError('Attributes should be a string or list/set of strings')
@@ -428,7 +428,7 @@
         for attr, attr_data in results.items():
             attr_index = entity.attribute_name_to_index_map[attr]
             eca = entity.attributes[attr_index]
-            results[attr] = self._fix_attr_json_attribute(copy.copy(attr_data), eca)
+            results[attr] = self._fix_attr_json_attribute(copy.deepcopy(attr_data), eca)
 
         return results
 
@@ -444,13 +444,13 @@
             if isinstance(cls_id, int):
                 me_map = self._omci_agent.get_device(device_id).me_map
                 entity = me_map.get(cls_id)
-                dev_data[cls_id] = self._fix_cls_json_attributes(copy.copy(cls_data), entity)
+                dev_data[cls_id] = self._fix_cls_json_attributes(copy.deepcopy(cls_data), entity)
         return dev_data
 
     def _fix_cls_json_attributes(self, cls_data, entity):
         for inst_id, inst_data in cls_data.items():
             if isinstance(inst_id, int):
-                cls_data[inst_id] = self._fix_inst_json_attributes(copy.copy(inst_data), entity)
+                cls_data[inst_id] = self._fix_inst_json_attributes(copy.deepcopy(inst_data), entity)
         return cls_data
 
     def _fix_inst_json_attributes(self, inst_data, entity):
@@ -459,7 +459,7 @@
                 attr_index = entity.attribute_name_to_index_map[attr] \
                     if entity is not None and attr in entity.attribute_name_to_index_map else None
                 eca = entity.attributes[attr_index] if attr_index is not None else None
-                inst_data[ATTRIBUTES_KEY][attr] = self._fix_attr_json_attribute(copy.copy(attr_data), eca)
+                inst_data[ATTRIBUTES_KEY][attr] = self._fix_attr_json_attribute(copy.deepcopy(attr_data), eca)
         return inst_data
 
     def _fix_attr_json_attribute(self, attr_data, eca):
diff --git a/pyvoltha/adapters/extensions/omci/onu_device_entry.py b/pyvoltha/adapters/extensions/omci/onu_device_entry.py
index a671620..40cb834 100644
--- a/pyvoltha/adapters/extensions/omci/onu_device_entry.py
+++ b/pyvoltha/adapters/extensions/omci/onu_device_entry.py
@@ -99,11 +99,13 @@
             self._mib_db_in_sync = False
             mib_synchronizer_info = support_classes.get('mib-synchronizer')
             advertise = mib_synchronizer_info['advertise-events']
+            audit_delay = mib_synchronizer_info['audit-delay']
             self._mib_sync_sm = mib_synchronizer_info['state-machine'](self._omci_agent,
                                                                        device_id,
                                                                        mib_synchronizer_info['tasks'],
                                                                        mib_db,
-                                                                       advertise_events=advertise)
+                                                                       advertise_events=advertise,
+                                                                       audit_delay=audit_delay)
             # ONU OMCI Capabilities state machine
             capabilities_info = support_classes.get('omci-capabilities')
             advertise = capabilities_info['advertise-events']
diff --git a/pyvoltha/adapters/extensions/omci/openomci_agent.py b/pyvoltha/adapters/extensions/omci/openomci_agent.py
index e416d58..b927621 100644
--- a/pyvoltha/adapters/extensions/omci/openomci_agent.py
+++ b/pyvoltha/adapters/extensions/omci/openomci_agent.py
@@ -43,6 +43,7 @@
         'database': MibDbVolatileDict,     # Implements volatile ME MIB database
         # 'database': MibDbExternal,         # Implements persistent ME MIB database
         'advertise-events': True,          # Advertise events on OpenOMCI event bus
+        'audit-delay': 60,                 # Time to wait between MIB audits.  0 to disable audits.
         'tasks': {
             'mib-upload': MibUploadTask,
             'get-mds': GetMdsTask,
diff --git a/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py b/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py
index a5b0e2a..8d8d54c 100644
--- a/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py
+++ b/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py
@@ -944,7 +944,7 @@
         from pyvoltha.adapters.extensions.omci.database.mib_db_api import DatabaseStateError
 
         self.log.debug('query', class_id=class_id,
-                       instance_id=instance_id, attributes=attributes)
+                       entity_instance_id=instance_id, attributes=attributes)
         if self._database is None:
             raise DatabaseStateError('Database does not yet exist')