Revert "VOL-722: MIB Resynchronization Task implemented"
This reverts commit 7ea591a99f0cdbe63eb057574340ce7a65f0b89d.
Change-Id: I8181422846acc08b5d41c5ff54aac639a393d4e9
diff --git a/tests/utests/voltha/extensions/omci/test_mib_resync_task.py b/tests/utests/voltha/extensions/omci/test_mib_resync_task.py
index 073b2d6..d598c48 100644
--- a/tests/utests/voltha/extensions/omci/test_mib_resync_task.py
+++ b/tests/utests/voltha/extensions/omci/test_mib_resync_task.py
@@ -214,10 +214,10 @@
self.assertEqual(len(attr_diffs), 0)
def test_on_olt_only(self):
- class_id = GemInterworkingTp.class_id
+ class_id = PriorityQueueG.class_id
inst_id = 0
attributes = {
- 'gal_loopback_configuration': int(1)
+ 'related_port': int(1234567) # IntField
}
self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes)
diff --git a/tests/utests/voltha/extensions/omci/test_openomci_agent.py b/tests/utests/voltha/extensions/omci/test_openomci_agent.py
index 498a59c..d1c69d2 100644
--- a/tests/utests/voltha/extensions/omci/test_openomci_agent.py
+++ b/tests/utests/voltha/extensions/omci/test_openomci_agent.py
@@ -24,7 +24,6 @@
from voltha.extensions.omci.tasks.mib_upload import MibUploadTask
from voltha.extensions.omci.tasks.get_mds_task import GetMdsTask
from voltha.extensions.omci.tasks.mib_resync_task import MibResyncTask
-from voltha.extensions.omci.tasks.mib_reconcile_task import MibReconcileTask
class TestOpenOmciAgent(TestCase):
@@ -54,7 +53,7 @@
self.assertTrue(isinstance(mib_sync_tasks['get-mds'], type(GetMdsTask)))
self.assertTrue(isinstance(mib_sync_tasks['mib-audit'], type(GetMdsTask)))
self.assertTrue(isinstance(mib_sync_tasks['mib-resync'], type(MibResyncTask)))
- self.assertTrue(isinstance(mib_sync_tasks['mib-reconcile'], type(MibReconcileTask)))
+ # self.assertTrue(isinstance(mib_sync_tasks['mib-reconcile'], type('TODO: not yet coded')))
# caps = OpenOmciAgentDefaults.get('onu-capabilities')
#
diff --git a/voltha/extensions/omci/database/mib_db_dict.py b/voltha/extensions/omci/database/mib_db_dict.py
index 19294b2..daadc68 100644
--- a/voltha/extensions/omci/database/mib_db_dict.py
+++ b/voltha/extensions/omci/database/mib_db_dict.py
@@ -234,14 +234,13 @@
try:
device_db = self._data[device_id]
class_db = device_db.get(class_id)
- created = False
if class_db is None:
- device_db[class_id] = {CLASS_ID_KEY: class_id}
-
+ device_db[class_id] = {
+ CLASS_ID_KEY: class_id
+ }
class_db = device_db[class_id]
self._modified = now
- created = True
instance_db = class_db.get(instance_id)
if instance_db is None:
@@ -253,7 +252,6 @@
}
instance_db = class_db[instance_id]
self._modified = now
- created = True
changed = False
@@ -292,7 +290,7 @@
if ATTRIBUTES_KEY in instance_db else None
assert db_value is None or isinstance(value, type(db_value)), \
- "New value type for attribute '{}' type is changing from '{}' to '{}'".\
+ "New value for attribute '{}' type is changing from '{}' to '{}'".\
format(attribute, type(db_value), type(value))
if db_value is None or db_value != value:
@@ -303,11 +301,10 @@
instance_db[MODIFIED_KEY] = now
self._modified = now
- return changed or created
+ return changed
except Exception as e:
- self.log.error('set-failure', e, class_id=class_id,
- instance_id=instance_id, attributes=attributes)
+ self.log.error('set-failure', e=e)
raise
def delete(self, device_id, class_id, instance_id):
diff --git a/voltha/extensions/omci/database/mib_db_ext.py b/voltha/extensions/omci/database/mib_db_ext.py
index 1a895c5..c6f77b8 100644
--- a/voltha/extensions/omci/database/mib_db_ext.py
+++ b/voltha/extensions/omci/database/mib_db_ext.py
@@ -764,7 +764,7 @@
except KeyError:
# Here if the class-id does not yet exist in the database
- self.log.debug("adding-key-not-found", class_id=class_id)
+ self.log.info("adding-key-not-found", class_id=class_id)
return self._add_new_class(device_id, class_id, instance_id,
attributes)
finally:
@@ -837,7 +837,7 @@
diff = datetime.utcnow() - start_time
# NOTE: Change to 'debug' when checked in, manually change to 'info'
# for development testing.
- self.log.debug('db-delete-time', milliseconds=diff.microseconds/1000)
+ self.log.info('db-delete-time', milliseconds=diff.microseconds/1000)
self._statistics['delete'].increment(diff.microseconds/1000)
def query(self, device_id, class_id=None, instance_id=None, attributes=None):
@@ -920,8 +920,8 @@
diff = end_time.utcnow() - start_time
# NOTE: Change to 'debug' when checked in, manually change to 'info'
# for development testing.
- self.log.debug('db-get-time', milliseconds=diff.microseconds/1000, class_id=class_id,
- instance_id=instance_id)
+ self.log.info('db-get-time', milliseconds=diff.microseconds/1000, class_id=class_id,
+ instance_id=instance_id)
self._statistics['get'].increment(diff.microseconds/1000)
def _instance_to_dict(self, device_id, class_id, instance):
diff --git a/voltha/extensions/omci/omci_me.py b/voltha/extensions/omci/omci_me.py
index a8a2d05..808fd78 100644
--- a/voltha/extensions/omci/omci_me.py
+++ b/voltha/extensions/omci/omci_me.py
@@ -700,11 +700,7 @@
raise TypeError('ignore_arc should be a boolean')
if mib_data_sync is not None:
- # Note: Currently the Scapy decode/encode is 16-bits since we need
- # the data field that large in order to support MIB and Alarm Upload Next
- # commands. Push our 8-bit MDS value into the upper 8-bits so that
- # it is encoded properly into the ONT_Data 'set' frame
- data = {'mib_data_sync': mib_data_sync << 8}
+ data = {'mib_data_sync': mib_data_sync}
elif sequence_number is not None:
data = {'mib_data_sync': sequence_number}
diff --git a/voltha/extensions/omci/onu_device_entry.py b/voltha/extensions/omci/onu_device_entry.py
index 0d07522..165ffa0 100644
--- a/voltha/extensions/omci/onu_device_entry.py
+++ b/voltha/extensions/omci/onu_device_entry.py
@@ -123,8 +123,8 @@
# downloader_info['tasks'],
# advertise_events=advertise)
self._image_agent = ImageAgent(self._omci_agent, device_id, downloader_info['state-machine'],
- downloader_info['tasks'],
- advertise_events=advertise)
+ downloader_info['tasks'],
+ advertise_events=advertise)
except Exception as e:
self.log.exception('state-machine-create-failed', e=e)
raise
diff --git a/voltha/extensions/omci/openomci_agent.py b/voltha/extensions/omci/openomci_agent.py
index 9e2cdde..778debb 100644
--- a/voltha/extensions/omci/openomci_agent.py
+++ b/voltha/extensions/omci/openomci_agent.py
@@ -20,7 +20,6 @@
from voltha.extensions.omci.tasks.mib_upload import MibUploadTask
from voltha.extensions.omci.tasks.get_mds_task import GetMdsTask
from voltha.extensions.omci.tasks.mib_resync_task import MibResyncTask
-from voltha.extensions.omci.tasks.mib_reconcile_task import MibReconcileTask
from voltha.extensions.omci.tasks.sync_time_task import SyncTimeTask
from voltha.extensions.omci.state_machines.alarm_sync import AlarmSynchronizer
from voltha.extensions.omci.tasks.alarm_resync_task import AlarmResyncTask
@@ -46,7 +45,7 @@
'get-mds': GetMdsTask,
'mib-audit': GetMdsTask,
'mib-resync': MibResyncTask,
- 'mib-reconcile': MibReconcileTask
+ 'mib-reconcile': None # TODO: post-v1.3.0 (Reconcile out-of-sync MIB DB)
}
},
'omci-capabilities': {
diff --git a/voltha/extensions/omci/state_machines/mib_sync.py b/voltha/extensions/omci/state_machines/mib_sync.py
index 16f29b2..7e2fcfd 100644
--- a/voltha/extensions/omci/state_machines/mib_sync.py
+++ b/voltha/extensions/omci/state_machines/mib_sync.py
@@ -18,7 +18,6 @@
from transitions import Machine
from twisted.internet import reactor
from voltha.extensions.omci.omci_frame import OmciFrame
-from voltha.extensions.omci.database.mib_db_api import MDS_KEY
from voltha.extensions.omci.omci_defs import EntityOperations, ReasonCodes, \
AttributeAccess
from voltha.extensions.omci.omci_cc import OmciCCRxEvents, OMCI_CC, TX_REQUEST_KEY, \
@@ -50,30 +49,29 @@
{'trigger': 'examine_mds', 'source': 'starting', 'dest': 'examining_mds'},
{'trigger': 'success', 'source': 'uploading', 'dest': 'in_sync'},
+ {'trigger': 'timeout', 'source': 'uploading', 'dest': 'starting'},
{'trigger': 'success', 'source': 'examining_mds', 'dest': 'in_sync'},
- {'trigger': 'mismatch', 'source': 'examining_mds', 'dest': 'resynchronizing'},
+ {'trigger': 'timeout', 'source': 'examining_mds', 'dest': 'starting'},
+ {'trigger': 'mismatch', 'source': 'examining_mds', 'dest': 'uploading'},
{'trigger': 'audit_mib', 'source': 'in_sync', 'dest': 'auditing'},
-
- {'trigger': 'success', 'source': 'out_of_sync', 'dest': 'in_sync'},
{'trigger': 'audit_mib', 'source': 'out_of_sync', 'dest': 'auditing'},
{'trigger': 'success', 'source': 'auditing', 'dest': 'in_sync'},
+ {'trigger': 'timeout', 'source': 'auditing', 'dest': 'starting'},
{'trigger': 'mismatch', 'source': 'auditing', 'dest': 'resynchronizing'},
{'trigger': 'force_resync', 'source': 'auditing', 'dest': 'resynchronizing'},
{'trigger': 'success', 'source': 'resynchronizing', 'dest': 'in_sync'},
{'trigger': 'diffs_found', 'source': 'resynchronizing', 'dest': 'out_of_sync'},
-
- # Do wildcard 'timeout' trigger that sends us back to start
- {'trigger': 'timeout', 'source': '*', 'dest': 'starting'},
+ {'trigger': 'timeout', 'source': 'resynchronizing', 'dest': 'out_of_sync'},
# Do wildcard 'stop' trigger last so it covers all previous states
{'trigger': 'stop', 'source': '*', 'dest': 'disabled'},
]
DEFAULT_TIMEOUT_RETRY = 5 # Seconds to delay after task failure/timeout
- DEFAULT_AUDIT_DELAY = 60 # Periodic tick to audit the MIB Data Sync
+ DEFAULT_AUDIT_DELAY = 15 # Periodic tick to audit the MIB Data Sync
DEFAULT_RESYNC_DELAY = 300 # Periodically force a resync
def __init__(self, agent, device_id, mib_sync_tasks, db,
@@ -117,7 +115,6 @@
self._get_mds_task = mib_sync_tasks['get-mds']
self._audit_task = mib_sync_tasks['mib-audit']
self._resync_task = mib_sync_tasks['mib-resync']
- self._reconcile_task = mib_sync_tasks['mib-reconcile']
self._advertise_events = advertise_events
self._deferred = None
@@ -126,13 +123,10 @@
self._mib_data_sync = 0
self._last_mib_db_sync_value = None
self._device_in_db = False
- self._next_resync = None
self._on_olt_only_diffs = None
self._on_onu_only_diffs = None
self._attr_diffs = None
- self._audited_olt_db = None
- self._audited_onu_db = None
self._event_bus = EventBusClient()
self._omci_cc_subscriptions = { # RxEvent.enum -> Subscription Object
@@ -304,7 +298,7 @@
def on_enter_starting(self):
"""
- Determine ONU status and start/re-start MIB Synchronization tasks
+ Determine ONU status and start MIB Synchronization tasks
"""
self._device = self._agent.get_device(self._device_id)
self.advertise(OpenOmciEventType.state_change, self.state)
@@ -336,13 +330,6 @@
except Exception as e:
self.log.exception('dev-subscription-setup', e=e)
- # Clear any previous audit results
- self._on_olt_only_diffs = None
- self._on_onu_only_diffs = None
- self._attr_diffs = None
- self._audited_olt_db = None
- self._audited_onu_db = None
-
# Determine if this ONU has ever synchronized
if self.is_new_onu:
# Start full MIB upload
@@ -354,14 +341,13 @@
def on_enter_uploading(self):
"""
- Begin full MIB data upload, starting with a MIB RESET
+ Begin full MIB data sync, starting with a MIB RESET
"""
self.advertise(OpenOmciEventType.state_change, self.state)
def success(results):
self.log.debug('mib-upload-success', results=results)
self._current_task = None
- self._next_resync = datetime.utcnow() + timedelta(seconds=self._resync_delay)
self._deferred = reactor.callLater(0, self.success)
def failure(reason):
@@ -390,7 +376,6 @@
# Examine MDS value
if self.mib_data_sync == onu_mds_value:
- self._next_resync = datetime.utcnow() + timedelta(seconds=self._resync_delay)
self._deferred = reactor.callLater(0, self.success)
else:
self._deferred = reactor.callLater(0, self.mismatch)
@@ -408,7 +393,7 @@
def on_enter_in_sync(self):
"""
- The OLT/OpenOMCI MIB Database is in sync with the ONU MIB Database.
+ Schedule a tick to occur to in the future to request an audit
"""
self.advertise(OpenOmciEventType.state_change, self.state)
self.last_mib_db_sync = datetime.utcnow()
@@ -424,59 +409,75 @@
o the MIB_Data_Sync values are not equal, or
o the MIBs were compared and differences were found.
- Schedule a task to reconcile the differences
+ If all of the *_diff properties are allNone, then we are here after initial
+ startup and MDS did not match, or the MIB Audit/Resync state failed.
+
+ In the second case, one or more of our *_diff properties will be non-None.
+ If that is true, we need to update the ONU accordingly.
+
+ Schedule a tick to occur to in the future to request an audit
"""
self.advertise(OpenOmciEventType.state_change, self.state)
+ self._device.mib_db_in_sync = False
- # We are only out-of-sync if there were differences. If here due to MDS
- # value differences, still run the reconcile so we up date the ONU's MDS
- # value to match ours.
+ if all(diff is None for diff in [self._on_olt_only_diffs,
+ self._on_onu_only_diffs,
+ self._attr_diffs]):
+ # Retry the Audit process
+ self._deferred = reactor.callLater(1, self.audit_mib)
- self._device.mib_db_in_sync = self._attr_diffs is None and \
- self._on_onu_only_diffs is None and \
- self._on_olt_only_diffs is None
+ else:
+ step = 'Nothing'
+ class_id = 0
+ instance_id = 0
+ attribute = ''
- def success(onu_mds_value):
- self.log.debug('examine-mds-success', mds_value=onu_mds_value)
- self._current_task = None
- self._next_resync = datetime.utcnow() + timedelta(seconds=self._resync_delay)
- self._deferred = reactor.callLater(0, self.success)
+ try:
+ # Need to update the ONU accordingly
+ if self._attr_diffs is not None:
+ step = 'attribute-update'
+ pass # TODO: Perform the 'set' commands needed
- def failure(reason):
- self.log.info('examine-mds-failure', reason=reason)
- self._current_task = None
- self._deferred = reactor.callLater(self._timeout_delay, self.timeout)
+ if self._on_onu_only_diffs is not None:
+ step = 'onu-cleanup'
+ #
+ # TODO: May want to watch for ONU only attributes
+ # It is possible that if they are the 'default' value or
+ # are not used if another attribute is set a specific way.
+ #
+ # For instance, no one may set the gal_loopback_configuration
+ # in the GEM Interworking Termination point since its default
+ # values is '0' disable, but when we audit, the ONU will report zero.
+ #
+ # A good way to perhaps fix this is to update our database with the
+ # default. Or perhaps set all defaults in the database in the first
+ # place when we do the initial create/set.
+ #
+ pass # TODO: Perform 'delete' commands as needed, see 'default' note above
- diff_collection = {
- 'onu-only': self._on_onu_only_diffs,
- 'olt-only': self._on_olt_only_diffs,
- 'attributes': self._attr_diffs,
- 'olt-db': self._audited_olt_db,
- 'onu-db': self._audited_onu_db
- }
- # Clear out results since reconciliation task will be handling them
- self._on_olt_only_diffs = None
- self._on_onu_only_diffs = None
- self._attr_diffs = None
- self._audited_olt_db = None
- self._audited_onu_db = None
+ if self._on_olt_only_diffs is not None:
+ step = 'olt-push'
+ pass # TODO: Perform 'create' commands as needed
- self._current_task = self._reconcile_task(self._agent, self._device_id, diff_collection)
- self._task_deferred = self._device.task_runner.queue_task(self._current_task)
- self._task_deferred.addCallbacks(success, failure)
+ self._deferred = reactor.callLater(1, self.audit_mib)
+
+ except Exception as e:
+ self.log.exception('onu-update', e=e, step=step, class_id=class_id,
+ instance_id=instance_id, attribute=attribute)
+ # Retry the Audit process
+ self._deferred = reactor.callLater(1, self.audit_mib)
def on_enter_auditing(self):
"""
Perform a MIB Audit. If our last MIB resync was too long in the
past, perform a resynchronization anyway
"""
+ next_resync = self.last_mib_db_sync + timedelta(seconds=self._resync_delay)\
+ if self.last_mib_db_sync is not None else datetime.utcnow()
+
self.advertise(OpenOmciEventType.state_change, self.state)
- if self._next_resync is None:
- self.log.error('next-forced-resync-error', msg='Next Resync should always be valid at this point')
- self._deferred = reactor.callLater(self._timeout_delay, self.timeout)
-
- if datetime.utcnow() >= self._next_resync:
+ if datetime.utcnow() >= next_resync:
self._deferred = reactor.callLater(0, self.force_resync)
else:
def success(onu_mds_value):
@@ -513,22 +514,25 @@
on_olt_only = results.get('on-olt-only')
on_onu_only = results.get('on-onu-only')
attr_diffs = results.get('attr-diffs')
- olt_db = results.get('olt-db')
- onu_db = results.get('onu-db')
self._current_task = None
self._on_olt_only_diffs = on_olt_only if on_olt_only and len(on_olt_only) else None
self._on_onu_only_diffs = on_onu_only if on_onu_only and len(on_onu_only) else None
self._attr_diffs = attr_diffs if attr_diffs and len(attr_diffs) else None
- self._audited_olt_db = olt_db
- self._audited_onu_db = onu_db
- mds_equal = self.mib_data_sync == self._audited_onu_db[MDS_KEY]
+ if all(diff is None for diff in [self._on_olt_only_diffs,
+ self._on_onu_only_diffs,
+ self._attr_diffs]):
+ # TODO: If here, do we need to make sure OpenOMCI mib_data_sync matches
+ # the ONU. Remember we compared against an ONU snapshot, it may
+ # be different now. Best thing to do is perhaps set it to our
+ # MDS value if different. Also remember that setting the MDS on
+ # the ONU to 'n' is a set command and it will be 'n+1' after the
+ # set.
+ #
+ # TODO: Also look into attributes covered by AVC and treat appropriately
+ # since may have missed the AVC
- if mds_equal and all(diff is None for diff in [self._on_olt_only_diffs,
- self._on_onu_only_diffs,
- self._attr_diffs]):
- self._next_resync = datetime.utcnow() + timedelta(seconds=self._resync_delay)
self._deferred = reactor.callLater(0, self.success)
else:
self._deferred = reactor.callLater(0, self.diffs_found)
@@ -536,6 +540,9 @@
def failure(reason):
self.log.info('resync-failure', reason=reason)
self._current_task = None
+ self._on_olt_only_diffs = None
+ self._on_onu_only_diffs = None
+ self._attr_diffs = None
self._deferred = reactor.callLater(self._timeout_delay, self.timeout)
self._current_task = self._resync_task(self._agent, self._device_id)
@@ -593,29 +600,29 @@
if self.state == 'disabled':
self.log.error('rx-in-invalid-state', state=self.state)
- # Inspect the notification
- omci_msg = notification.fields['omci_message'].fields
- class_id = omci_msg['entity_class']
- instance_id = omci_msg['entity_id']
- data = omci_msg['data']
- attributes = [data.keys()]
+ elif self.state != 'uploading':
+ # Inspect the notification
+ omci_msg = notification.fields['omci_message'].fields
+ class_id = omci_msg['entity_class']
+ instance_id = omci_msg['entity_id']
+ data = omci_msg['data']
+ attributes = [data.keys()]
- # Look up ME Instance in Database. Not-found can occur if a MIB
- # reset has occurred
- info = self._database.query(self.device_id, class_id, instance_id, attributes)
- # TODO: Add old/new info to log message
- self.log.debug('avc-change', class_id=class_id, instance_id=instance_id)
+ # Look up ME Instance in Database. Not-found can occur if a MIB
+ # reset has occurred
+ info = self._database.query(self.device_id, class_id, instance_id, attributes)
+ # TODO: Add old/new info to log message
+ self.log.debug('avc-change', class_id=class_id, instance_id=instance_id)
- # Save the changed data to the MIB.
- self._database.set(self.device_id, class_id, instance_id, data)
+ # Save the changed data to the MIB.
+ changed = self._database.set(self.device_id, class_id, instance_id, data)
- # Autonomous creation and deletion of managed entities do not
- # result in an increment of the MIB data sync value. However,
- # AVC's in response to a change by the Operator do incur an
- # increment of the MIB Data Sync. If here during uploading,
- # we issued a MIB-Reset which may generate AVC. (TODO: Focus testing during hardening)
- if self.state == 'uploading':
- self.increment_mib_data_sync()
+ if changed:
+ # Autonomous creation and deletion of managed entities do not
+ # result in an increment of the MIB data sync value. However,
+ # AVC's in response to a change by the Operator do incur an
+ # increment of the MIB Data Sync
+ pass
except KeyError:
pass # NOP
@@ -842,11 +849,11 @@
entity_id = omci_msg['entity_id']
attributes = {k: v for k, v in omci_msg['data'].items()}
- # Save to the database (Do not save 'sets' of the mib-data-sync however)
- if class_id != OntData.class_id:
- modified = self._database.set(self._device_id, class_id, entity_id, attributes)
- if modified:
- self.increment_mib_data_sync()
+ # Save to the database
+ modified = self._database.set(self._device_id, class_id, entity_id, attributes)
+
+ if modified:
+ self.increment_mib_data_sync()
except KeyError as _e:
pass # NOP
@@ -917,18 +924,3 @@
if isinstance(attributes, dict) and len(attributes) and\
self.query_mib(class_id, entity_id) is not None:
self._database.set(self._device_id, class_id, entity_id, attributes)
-
- def mib_delete(self, class_id, entity_id):
- """
- Delete an existing ME Class instance
-
- This method is primarily used by other state machines to delete an ME
- from the MIB database
-
- :param class_id: (int) ME Class ID
- :param entity_id: (int) ME Class entity ID
-
- :raises KeyError: If device does not exist
- :raises DatabaseStateError: If the database is not enabled
- """
- self._database.delete(self._device_id, class_id, entity_id)
diff --git a/voltha/extensions/omci/tasks/get_mds_task.py b/voltha/extensions/omci/tasks/get_mds_task.py
index 1560c83..57a3bf5 100644
--- a/voltha/extensions/omci/tasks/get_mds_task.py
+++ b/voltha/extensions/omci/tasks/get_mds_task.py
@@ -88,20 +88,15 @@
omci_msg = results.fields['omci_message'].fields
status = omci_msg['success_code']
-
- # Note: Currently the data reported by the Scapy decode is 16-bits since we need
- # the data field that large in order to support MIB and Alarm Upload Next
- # commands. Select only the first 8-bits since that is the size of the MIB
- # Data Sync attribute
- mds = (omci_msg['data']['mib_data_sync'] >> 8) & 0xFF \
- if 'data' in omci_msg and 'mib_data_sync' in omci_msg['data'] else -1
-
- self.log.debug('ont-data-mds', status=status, mib_data_sync=mds)
+ self.log.debug('ont-data-mds', status=status,
+ mib_data_sync=omci_msg['data']['mib_data_sync']
+ if 'data' in omci_msg and 'mib_data_sync' in omci_msg['data']
+ else None)
assert status == RC.Success, 'Unexpected Response Status: {}'.format(status)
# Successful if here
- self.deferred.callback(mds)
+ self.deferred.callback(omci_msg['data']['mib_data_sync'])
except TimeoutError as e:
self.log.warn('get-mds-timeout', e=e)
diff --git a/voltha/extensions/omci/tasks/mib_reconcile_task.py b/voltha/extensions/omci/tasks/mib_reconcile_task.py
deleted file mode 100644
index 38e29dc..0000000
--- a/voltha/extensions/omci/tasks/mib_reconcile_task.py
+++ /dev/null
@@ -1,693 +0,0 @@
-#
-# Copyright 2018 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from common.utils.asleep import asleep
-from voltha.extensions.omci.tasks.task import Task
-from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, failure, returnValue, TimeoutError
-from voltha.extensions.omci.omci_defs import *
-from voltha.extensions.omci.omci_me import OntDataFrame
-from voltha.extensions.omci.omci_frame import OmciFrame, OmciDelete, OmciCreate, OmciSet
-from voltha.extensions.omci.database.mib_db_api import ATTRIBUTES_KEY
-
-OP = EntityOperations
-RC = ReasonCodes
-AA = AttributeAccess
-
-
-class MibReconcileException(Exception):
- pass
-
-
-class MibPartialSuccessException(Exception):
- pass
-
-
-class MibReconcileTask(Task):
- """
- OpenOMCI MIB Reconcile Task
-
- This task attempts to resynchronize the MIB. Note that it runs in exclusive
- OMCI-CC mode so that it can query the current database/ONU to verify the
- differences still exist before correcting them.
- """
- task_priority = 240
- name = "MIB Reconcile Task"
- max_sequential_db_updates = 5 # Be kind, rewind
- db_update_pause = 0.05 # 50mS
-
- def __init__(self, omci_agent, device_id, diffs):
- """
- Class initialization
-
- :param omci_agent: (OpenOMCIAgent) OMCI Adapter agent
- :param device_id: (str) ONU Device ID
- :param diffs: (dict) Dictionary of what was found to be invalid
- """
- super(MibReconcileTask, self).__init__(MibReconcileTask.name,
- omci_agent,
- device_id,
- priority=MibReconcileTask.task_priority,
- exclusive=False)
- self._local_deferred = None
- self._diffs = diffs
- self._device = None
- self._sync_sm = None
- self._db_updates = 0 # For tracking sequential blocking consul/etcd updates
-
- def cancel_deferred(self):
- super(MibReconcileTask, self).cancel_deferred()
-
- d, self._local_deferred = self._local_deferred, None
- try:
- if d is not None and not d.called:
- d.cancel()
- except:
- pass
-
- def start(self):
- """
- Start MIB Reconcile task
- """
- super(MibReconcileTask, self).start()
-
- self._device = self.omci_agent.get_device(self.device_id)
-
- if self._device is None:
- e = MibReconcileException('Device {} no longer exists'.format(self.device_id))
- self.deferred.errback(failure.Failure(e))
- return
-
- self._sync_sm = self._device.mib_synchronizer
-
- if self._device is None:
- e = MibReconcileException('Device {} MIB State machine no longer exists'.format(self.device_id))
- self.deferred.errback(failure.Failure(e))
- return
-
- self._local_deferred = reactor.callLater(0, self.perform_mib_reconcile)
-
- def stop(self):
- """
- Shutdown MIB Reconcile task
- """
- self.log.debug('stopping')
-
- self.cancel_deferred()
- self._device = None
- super(MibReconcileTask, self).stop()
-
- @inlineCallbacks
- def perform_mib_reconcile(self):
- """
- Perform the MIB Reconciliation sequence.
-
- The sequence to reconcile will be to clean up ONU only MEs, followed by
- OLT/OpenOMCI-only MEs, and then finally correct common MEs with differing
- attributes.
- """
- self.log.debug('perform-mib-reconcile')
-
- try:
- successes = 0
- failures = 0
-
- if self._diffs['onu-only'] is not None and len(self._diffs['onu-only']):
- results = yield self.fix_onu_only(self._diffs['onu-only'],
- self._diffs['onu-db'])
- self.log.debug('onu-only-results', good=results[0], bad=results[1])
- successes += results[0]
- failures += results[1]
-
- if self._diffs['olt-only'] is not None and len(self._diffs['olt-only']):
- results = yield self.fix_olt_only(self._diffs['olt-only'],
- self._diffs['onu-db'],
- self._diffs['olt-db'])
- self.log.debug('olt-only-results', good=results[0], bad=results[1])
- successes += results[0]
- failures += results[1]
-
- if self._diffs['attributes'] is not None and len(self._diffs['attributes']):
- results = yield self.fix_attributes_only(self._diffs['attributes'],
- self._diffs['onu-db'],
- self._diffs['olt-db'])
- self.log.debug('attributes-results', good=results[0], bad=results[1])
- successes += results[0]
- failures += results[1]
-
- # Success? Update MIB-data-sync
- if failures == 0:
- results = yield self.update_mib_data_sync()
- successes += results[0]
- failures += results[1]
-
- # Send back final status
- if failures > 0:
- msg = '{} Successful updates, {} failures'.format(successes, failure)
- error = MibPartialSuccessException(msg) if successes \
- else MibReconcileException(msg)
- self.deferred.errback(failure.Failure(error))
- else:
- self.deferred.callback('{} Successful updates'.format(successes))
-
- except Exception as e:
- if not self.deferred.called:
- self.log.exception('reconcile', e=e)
- self.deferred.errback(failure.Failure(e))
-
- @inlineCallbacks
- def fix_onu_only(self, onu, onu_db):
- """
- Fix ME's that were only found on the ONU. For ONU only MEs there are
- the following things that will be checked.
-
- o ME's that do not have an OpenOMCI class decoder. These are stored
- as binary blobs in the MIB database. Since we do not ever set them
- (since no encoder as well), just store them in the OLT/OpenOMCI MIB
- Database.
-
- o For ME's that are created by the ONU (no create/delete access), the
- MEs 'may' be due to a firmware upgrade and reboot or in response to
- an OLT creating another ME entity and then creating this ME. Place
- these 'new' into the database.
-
- o For ME's that are created by the OLT/OpenOMCI, delete them from the
- ONU
-
- :param onu: (list(int,int)) List of tuples where (class_id, inst_id)
- :param onu_db: (dict) ONU Database snapshot at time of audit
-
- :return: (int, int) successes, failures
- """
- successes = 0
- failures = 0
- me_map = self._device.me_map
-
- ####################################################################
- # First the undecodables and onu-created (treated the same)
- undecodable = self._undecodable(onu, me_map)
- onu_created = self._onu_created(onu, me_map)
-
- if len(undecodable) or len(onu_created):
- results = yield self.fix_onu_only_save_to_db(undecodable, onu_created, onu_db)
- successes += results[0]
- failures += results[1]
-
- ####################################################################
- # Last the OLT created values, resend these to the ONU
-
- olt_created = self._olt_created(onu, me_map)
- if len(olt_created):
- results = yield self.fix_onu_only_remove_from_onu(olt_created)
- successes += results[0]
- failures += results[1]
-
- returnValue((successes, failures))
-
- @inlineCallbacks
- def fix_onu_only_save_to_db(self, undecodable, onu_created, onu_db):
- """
- In ONU database and needs to be saved to OLT/OpenOMCI database.
-
- Note that some, perhaps all, of these instances could be ONU create
- in response to the OLT creating some other ME instance. So treat
- the Database operation as a create.
- """
- successes = 0
- failures = 0
-
- for cid, eid in undecodable + onu_created:
- if self.deferred.called: # Check if task canceled
- break
- try:
- # If in current MIB, had an audit issue or other MIB operation
- # put it into the database, declare it a failure so we audit again
- try:
- olt_entry = self._sync_sm.query_mib(class_id=cid, instance_id=eid)
-
- except KeyError: # Common for ONU created MEs during audit
- olt_entry = None
-
- if olt_entry is not None and len(olt_entry):
- self.log.debug('onu-only-in-current', cid=cid, eid=eid)
- failures += 1 # Mark as failure so we audit again
-
- elif cid not in onu_db:
- self.log.warn('onu-only-not-in-audit', cid=cid, eid=eid)
- failures += 1
-
- else:
- entry = onu_db[cid][eid]
- self.strobe_watchdog()
- self._sync_sm.mib_set(cid, eid, entry[ATTRIBUTES_KEY])
- successes += 1
-
- # If we do nothing but DB updates for ALOT of MEs, we are
- # blocking other async twisted tasks, be kind and pause
- self._db_updates += 1
-
- if self._db_updates >= MibReconcileTask.max_sequential_db_updates:
- self._db_updates = 0
- self._local_deferred = yield asleep(MibReconcileTask.db_update_pause)
-
- except Exception as e:
- self.log.warn('onu-only-error', e=e)
- failures += 1
-
- returnValue((successes, failures))
-
- @inlineCallbacks
- def fix_onu_only_remove_from_onu(self, olt_created,):
- """ On ONU, but no longer on OLT/OpenOMCI, delete it """
- successes = 0
- failures = 0
-
- for cid, eid in olt_created:
- if self.deferred.called: # Check if task canceled
- break
- try:
- # If in current MIB, had an audit issue, declare it an error
- # and next audit should clear it up
- try:
- current_entry = self._sync_sm.query_mib(class_id=cid, instance_id=eid)
-
- except KeyError:
- # Expected if no other entities with same class present in MIB
- current_entry = None
-
- if current_entry is not None and len(current_entry):
- self.log.debug('onu-only-in-current', cid=cid, eid=eid)
- failures += 1
-
- else:
- # Delete it from the ONU. Assume success
- frame = OmciFrame(transaction_id=None,
- message_type=OmciDelete.message_id,
- omci_message=OmciDelete(entity_class=cid, entity_id=eid))
-
- self._local_deferred = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(self._local_deferred, 'onu-attribute-update')
- successes += 1
- self._db_updates = 0
-
- except Exception as e:
- self.log.warn('olt-only-error', e=e)
- failures += 1
- self.strobe_watchdog()
-
- returnValue((successes, failures))
-
- @inlineCallbacks
- def fix_olt_only(self, olt, onu_db, olt_db):
- """
- Fix ME's that were only found on the OLT. For OLT only MEs there are
- the following things that will be checked.
-
- o ME's that do not have an OpenOMCI class decoder. These are stored
- as binary blobs in the MIB database. Since the OLT will never
- create these (all are learned from ONU), it is assumed the ONU
- has removed them for some purpose. So delete them from the OLT
- database.
-
- o For ME's that are created by the ONU (no create/delete access), the
- MEs 'may' not be on the ONU because of a reboot or an OLT created
- ME was deleted and the ONU gratuitously removes it. So delete them
- from the OLT database.
-
- o For ME's that are created by the OLT/OpenOMCI, delete them from the
- ONU
-
- :param olt: (list(int,int)) List of tuples where (class_id, inst_id)
- :param onu_db: (dict) ONU Database snapshot at time of audit
- :param olt_db: (dict) OLT Database snapshot at time of audit
-
- :return: (int, int) successes, failures
- """
- successes = 0
- failures = 0
- me_map = self._device.me_map
-
- ####################################################################
- # First the undecodables and onu-created (treated the same) remove
- # from OpenOMCI database
- undecodable = self._undecodable(olt, me_map)
- onu_created = self._onu_created(olt, me_map)
-
- if len(undecodable) or len(onu_created):
- good, bad = self.fix_olt_only_remove_from_db(undecodable, onu_created)
- successes += good
- failures += bad
-
- ####################################################################
- # Last the OLT created
-
- olt_created = self._olt_created(olt, me_map)
- if len(olt_created):
- results = yield self.fix_olt_only_create_on_onu(olt_created, me_map)
- successes += results[0]
- failures += results[1]
-
- returnValue((successes, failures))
-
- def fix_olt_only_remove_from_db(self, undecodable, onu_created):
- """ On OLT, but not on ONU and are ONU created, delete from OLT/OpenOMCI DB """
- successes = 0
- failures = 0
-
- for cid, eid in undecodable + onu_created:
- if self.deferred.called: # Check if task canceled
- break
- try:
- # Delete it. If already deleted (KeyError), then that is okay
- self._sync_sm.mib_delete(cid, eid)
- self.strobe_watchdog()
-
- except KeyError:
- successes += 1 # Not found in DB anymore, assume success
-
- except Exception as e:
- self.log.warn('olt-only-db-error', cid=cid, eid=eid, e=e)
- failures += 1
-
- return successes, failures
-
- @inlineCallbacks
- def fix_olt_only_create_on_onu(self, olt_created, me_map):
- """ Found on OLT and created by OLT, so create on ONU"""
- successes = 0
- failures = 0
-
- for cid, eid in olt_created:
- if self.deferred.called: # Check if task canceled
- break
-
- try:
- # Get current entry, use it if found
- olt_entry = self._sync_sm.query_mib(class_id=cid, instance_id=eid)
- me_entry = me_map[cid]
-
- if olt_entry is None or len(olt_entry) == 0:
- successes += 1 # Deleted before task got to run
- else:
- # Create it in the ONU. Only set-by-create attributes allowed
- sbc_data = {k: v for k, v in olt_entry[ATTRIBUTES_KEY].items()
- if AA.SetByCreate in
- next((attr.access for attr in me_entry.attributes
- if attr.field.name == k), set())}
-
- frame = OmciFrame(transaction_id=None,
- message_type=OmciCreate.message_id,
- omci_message=OmciCreate(entity_class=cid,
- entity_id=eid,
- data=sbc_data))
-
- self._local_deferred = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(self._local_deferred, 'olt-create-sbc')
- successes += 1
- self._db_updates = 0
-
- # Try any writeable attributes now (but not set-by-create)
- writeable_data = {k: v for k, v in olt_entry[ATTRIBUTES_KEY].items()
- if AA.Writable in
- next((attr.access for attr in me_entry.attributes
- if attr.field.name == k), set())
- and AA.SetByCreate not in
- next((attr.access for attr in me_entry.attributes
- if attr.field.name == k), set())}
-
- if len(writeable_data):
- attributes_mask = me_entry.mask_for(*writeable_data.keys())
- frame = OmciFrame(transaction_id=None,
- message_type=OmciSet.message_id,
- omci_message=OmciSet(entity_class=cid,
- entity_id=eid,
- attributes_mask=attributes_mask,
- data=writeable_data))
-
- self._local_deferred = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(self._local_deferred, 'olt-set-writeable')
- successes += 1
-
- except Exception as e:
- self.log.exception('olt-only-fix', e=e, cid=cid, eid=eid)
- failures += 1
- self.strobe_watchdog()
-
- returnValue((successes, failures))
-
- @inlineCallbacks
- def fix_attributes_only(self, attrs, onu_db, olt_db):
- """
- Fix ME's that were found on both the ONU and OLT, but had differing
- attribute values. There are several cases to handle here
-
- o For ME's created on the ONU that have write attributes that
- only exist in the ONU's database, copy these to the OLT/OpenOMCI
- database
-
- o For all other writeable attributes, the OLT value takes precedence
-
- :param attrs: (list(int,int,str)) List of tuples where (class_id, inst_id, attribute)
- points to the specific ME instance where attributes
- are different
- :param onu_db: (dict) ONU Database snapshot at time of audit
- :param olt_db: (dict) OLT Database snapshot at time of audit
-
- :return: (int, int) successes, failures
- """
- successes = 0
- failures = 0
- me_map = self._device.me_map
-
- # Collect up attributes on a per CID/EID basis. This will result in
- # the minimal number of operations to either the database of over
- # the OMCI-CC to the ONU
-
- attr_map = dict()
- for cid, eid, attribute in attrs:
- if (cid, eid) not in attr_map:
- attr_map[(cid, eid)] = {attribute}
- else:
- attr_map[(cid, eid)].add(attribute)
-
- for entity_pair, attributes in attr_map.items():
- cid = entity_pair[0]
- eid = entity_pair[1]
-
- # Skip MEs we cannot encode/decode
- if cid not in me_map:
- self.log.warn('no-me-map-decoder', class_id=cid)
- failures += 1
- continue
-
- if self.deferred.called: # Check if task canceled
- break
-
- # Build up MIB set commands and ONU Set (via OMCI) commands
- # based of the attributes
- me_entry = me_map[cid]
- mib_data_to_save = dict()
- onu_data_to_set = dict()
- olt_attributes = olt_db[cid][eid][ATTRIBUTES_KEY]
- onu_attributes = onu_db[cid][eid][ATTRIBUTES_KEY]
-
- for attribute in attributes:
- map_access = next((attr.access for attr in me_entry.attributes
- if attr.field.name == attribute), set())
- writeable = AA.Writable in map_access or AA.SetByCreate in map_access
-
- # If only in ONU database snapshot, save it to OLT
- if attribute in onu_attributes and attribute not in olt_attributes:
- # On onu only
- mib_data_to_save[attribute] = onu_attributes[attribute]
-
- elif writeable:
- # On olt only or in both. Either way OLT wins
- onu_data_to_set[attribute] = olt_attributes[attribute]
-
- # Now do the bulk operations For both, check to see if the target
- # is still the same as when the audit was performed. If it is, do
- # the commit. If not, mark as a failure so an expedited audit will
- # occur and check again.
-
- if len(mib_data_to_save):
- results = yield self.fix_attributes_only_in_mib(cid, eid, mib_data_to_save)
- successes += results[0]
- failures += results[1]
-
- if len(onu_data_to_set):
- results = yield self.fix_attributes_only_on_olt(cid, eid, onu_data_to_set, olt_db, me_entry)
- successes += results[0]
- failures += results[1]
-
- returnValue((successes, failures))
-
- @inlineCallbacks
- def fix_attributes_only_in_mib(self, cid, eid, mib_data):
- successes = 0
- failures = 0
- try:
- # Get current and verify same as during audit it is missing from our DB
- attributes = mib_data.keys()
- current_entry = self._device.query_mib(cid, eid, attributes)
-
- if current_entry is not None and len(current_entry):
- clashes = {k: v for k, v in current_entry.items()
- if k in attributes and v != mib_data[k]}
-
- if len(clashes):
- raise ValueError('Existing DB entry for {}/{} attributes clash with audit data. Clash: {}'.
- format(cid, eid, clashes))
-
- self._sync_sm.mib_set(cid, eid, mib_data)
- successes += len(mib_data)
- self.strobe_watchdog()
-
- # If we do nothing but DB updates for ALOT of MEs, we are
- # blocking other async twisted tasks, be kind and yield
- self._db_updates += 1
- if self._db_updates >= MibReconcileTask.max_sequential_db_updates:
- self._db_updates = 0
- self._local_deferred = yield asleep(MibReconcileTask.db_update_pause)
-
- except ValueError as e:
- self.log.debug('attribute-changed', e)
- failures += len(mib_data)
-
- except Exception as e:
- self.log.exception('attribute-only-fix-mib', e=e, cid=cid, eid=eid)
- failures += len(mib_data)
-
- returnValue((successes, failures))
-
- @inlineCallbacks
- def fix_attributes_only_on_olt(self, cid, eid, onu_data, olt_db, me_entry):
- successes = 0
- failures = 0
-
- try:
- # On olt only or in both. Either way OLT wins, first verify that
- # the OLT version is still the same data that we want to
- # update on the ONU. Verify the data for the OLT is the same as
- # at time of audit
- olt_db_entries = {k: v for k, v in olt_db[cid][eid][ATTRIBUTES_KEY].items()
- if k in onu_data.keys()}
- current_entries = self._sync_sm.query_mib(class_id=cid, instance_id=eid,
- attributes=onu_data.keys())
-
- still_the_same = all(current_entries.get(k) == v for k, v in olt_db_entries.items())
- if not still_the_same:
- returnValue((0, len(onu_data))) # Wait for it to stabilize
-
- # OLT data still matches, do the set operations now
- # while len(onu_data):
- attributes_mask = me_entry.mask_for(*onu_data.keys())
- frame = OmciFrame(transaction_id=None,
- message_type=OmciSet.message_id,
- omci_message=OmciSet(entity_class=cid,
- entity_id=eid,
- attributes_mask=attributes_mask,
- data=onu_data))
-
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'onu-attribute-update')
- successes += len(onu_data)
- self._db_updates = 0
-
- except Exception as e:
- self.log.exception('attribute-only-fix-onu', e=e, cid=cid, eid=eid)
- failures += len(onu_data)
- self.strobe_watchdog()
-
- returnValue((successes, failures))
-
- @inlineCallbacks
- def update_mib_data_sync(self):
- """
- As the final step of MIB resynchronization, the OLT sets the MIB data sync
- attribute of the ONU data ME to some suitable value of its own choice. It
- then sets its own record of the same attribute to the same value,
- incremented by 1, as explained in clause
-
- :return: (int, int) success, failure counts
- """
- # Get MDS to set, do not user zero
-
- new_mds_value = self._sync_sm.mib_data_sync
- if new_mds_value == 0:
- self._sync_sm.increment_mib_data_sync()
- new_mds_value = self._sync_sm.mib_data_sync
-
- # Update it. The set response will be sent on the OMCI-CC pub/sub bus
- # and the MIB Synchronizer will update this MDS value in the database
- # if successful.
- try:
- frame = OntDataFrame(mib_data_sync=new_mds_value).set()
-
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'ont-data-mbs-update')
- returnValue((1, 0))
-
- except TimeoutError as e:
- self.log.debug('ont-data-send-timeout', e=e)
- returnValue((0, 1))
-
- except Exception as e:
- self.log.exception('ont-data-send', e=e, mds=new_mds_value)
- returnValue((0, 1))
-
- def check_status_and_state(self, results, operation=''):
- """
- Check the results of an OMCI response. An exception is thrown
- if the task was cancelled or an error was detected.
-
- :param results: (OmciFrame) OMCI Response frame
- :param operation: (str) what operation was being performed
- :return: True if successful, False if the entity existed (already created)
- """
- omci_msg = results.fields['omci_message'].fields
- status = omci_msg['success_code']
- error_mask = omci_msg.get('parameter_error_attributes_mask', 'n/a')
- failed_mask = omci_msg.get('failed_attributes_mask', 'n/a')
- unsupported_mask = omci_msg.get('unsupported_attributes_mask', 'n/a')
- self.strobe_watchdog()
-
- self.log.debug(operation, status=status, error_mask=error_mask,
- failed_mask=failed_mask, unsupported_mask=unsupported_mask)
-
- if status == RC.Success:
- return True
-
- elif status == RC.InstanceExists:
- return False
-
- msg = '{} failed with a status of {}, error_mask: {}, failed_mask: {}, unsupported_mask: {}'.\
- format(operation, status, error_mask, failed_mask, unsupported_mask)
-
- raise MibReconcileException(msg)
-
- def _undecodable(self, cid_eid_list, me_map):
- return [(cid, eid) for cid, eid in cid_eid_list if cid not in me_map]
-
- def _onu_created(self, cid_eid_list, me_map):
- return [(cid, eid) for cid, eid in cid_eid_list if cid in me_map and
- (OP.Create not in me_map[cid].mandatory_operations and
- OP.Create not in me_map[cid].optional_operations)]
-
- def _olt_created(self, cid_eid_list, me_map):
- return [(cid, eid) for cid, eid in cid_eid_list if cid in me_map and
- (OP.Create in me_map[cid].mandatory_operations or
- OP.Create in me_map[cid].optional_operations)]
diff --git a/voltha/extensions/omci/tasks/mib_resync_task.py b/voltha/extensions/omci/tasks/mib_resync_task.py
index ef9c531..f28ffb4 100644
--- a/voltha/extensions/omci/tasks/mib_resync_task.py
+++ b/voltha/extensions/omci/tasks/mib_resync_task.py
@@ -19,10 +19,9 @@
from common.utils.asleep import asleep
from voltha.extensions.omci.database.mib_db_dict import *
from voltha.extensions.omci.omci_entities import OntData
-from voltha.extensions.omci.omci_defs import AttributeAccess, EntityOperations
-
+from voltha.extensions.omci.omci_defs import AttributeAccess
AA = AttributeAccess
-OP = EntityOperations
+
class MibCopyException(Exception):
pass
@@ -60,7 +59,7 @@
"""
Class initialization
- :param omci_agent: (OpenOMCIAgent) OMCI Adapter agent
+ :param omci_agent: (OmciAdapterAgent) OMCI Adapter agent
:param device_id: (str) ONU Device ID
"""
super(MibResyncTask, self).__init__(MibResyncTask.name,
@@ -145,17 +144,14 @@
self.deferred.errback(failure.Failure(e))
else:
# Compare the databases
- active_copy = self._db_active.query(self.device_id)
on_olt_only, on_onu_only, attr_diffs = \
- self.compare_mibs(db_copy, active_copy)
+ self.compare_mibs(db_copy, self._db_active.query(self.device_id))
self.deferred.callback(
{
'on-olt-only': on_olt_only if len(on_olt_only) else None,
'on-onu-only': on_onu_only if len(on_onu_only) else None,
- 'attr-diffs': attr_diffs if len(attr_diffs) else None,
- 'olt-db': db_copy,
- 'onu-db': active_copy
+ 'attr-diffs': attr_diffs if len(attr_diffs) else None
})
except Exception as e:
@@ -257,13 +253,8 @@
# Filter out the 'mib_data_sync' from the database. We save that at
# the device level and do not want it showing up during a re-sync
# during data comparison
- from binascii import hexlify
- if class_id == OntData.class_id:
- break
- # The T&W ONU reports an ME with class ID 0 but only on audit. Perhaps others do as well.
- if class_id == 0 or class_id > 0xFFFF:
- self.log.warn('invalid-class-id', class_id=class_id)
+ if class_id == OntData.class_id:
break
attributes = {k: v for k, v in omci_msg['object_data'].items()}
@@ -294,34 +285,21 @@
:param db_copy: (dict) OpenOMCI's copy of the database
:param db_active: (dict) ONU's database snapshot
- :return: (dict), (dict), (list) Differences
+ :return: (dict), (dict), dict() Differences
"""
self.strobe_watchdog()
- me_map = self.omci_agent.get_device(self.device_id).me_map
# Class & Entities only in local copy (OpenOMCI)
- on_olt_temp = self.get_lhs_only_dict(db_copy, db_active)
-
- # Remove any entries that are not reported during an upload (but could
- # be in our database copy. Retain undecodable class IDs.
- on_olt_only = [(cid, eid) for cid, eid in on_olt_temp
- if cid not in me_map or not me_map[cid].hidden]
-
- # Further reduce the on_olt_only MEs reported in an audit to not
- # include missed MEs that are ONU created. Not all ONUs report MEs
- # that are ONU created unless we are doing the initial MIB upload.
- # Adtran does report them, T&W may not as well as a few others
- on_olt_only = [(cid, eid) for cid, eid in on_olt_only if cid in me_map and
- (OP.Create in me_map[cid].mandatory_operations or
- OP.Create in me_map[cid].optional_operations)]
+ on_olt_only = self.get_lsh_only_dict(db_copy, db_active)
# Class & Entities only on remote (ONU)
- on_onu_only = self.get_lhs_only_dict(db_active, db_copy)
+ on_onu_only = self.get_lsh_only_dict(db_active, db_copy)
# Class & Entities on both local & remote, but one or more attributes
# are different on the ONU. This is the value that the local (OpenOMCI)
# thinks should be on the remote (ONU)
+ me_map = self.omci_agent.get_device(self.device_id).me_map
attr_diffs = self.get_attribute_diffs(db_copy, db_active, me_map)
# TODO: Note that certain MEs are excluded from the MIB upload. In particular,
@@ -332,7 +310,7 @@
return on_olt_only, on_onu_only, attr_diffs
- def get_lhs_only_dict(self, lhs, rhs):
+ def get_lsh_only_dict(self, lhs, rhs):
"""
Compare two MIB database dictionaries and return the ME Class ID and
instances that are unique to the lhs dictionary. Both parameters
@@ -398,7 +376,7 @@
# Weed out read-only attributes. Attributes on onu may be read-only. These
# will only show up it the OpenOMCI (OLT-side) database if it changed and
# an AVC Notification was sourced by the ONU
- # TODO: These class IDs could be calculated once at ONU startup (at device add)
+ # TODO: These could be calculated once at ONU startup (device add)
if cls_id in me_map:
ro_attrs = {attr.field.name for attr in me_map[cls_id].attributes
if attr.access == ro_set}
diff --git a/voltha/extensions/omci/tasks/omci_get_request.py b/voltha/extensions/omci/tasks/omci_get_request.py
index 45c1db4..1ddb477 100644
--- a/voltha/extensions/omci/tasks/omci_get_request.py
+++ b/voltha/extensions/omci/tasks/omci_get_request.py
@@ -15,7 +15,7 @@
#
from task import Task
from twisted.internet import reactor
-from twisted.internet.defer import failure, inlineCallbacks, TimeoutError, returnValue
+from twisted.internet.defer import inlineCallbacks, failure, returnValue
from voltha.extensions.omci.omci_defs import ReasonCodes, EntityOperations
from voltha.extensions.omci.omci_me import MEFrame
from voltha.extensions.omci.omci_frame import OmciFrame
@@ -195,9 +195,6 @@
self.log.debug('get-completed')
self.deferred.callback(self)
- except TimeoutError as e:
- self.deferred.errback(failure.Failure(e))
-
except Exception as e:
self.log.exception('perform-get', e=e, class_id=self._entity_class,
entity_id=self._entity_id, attributes=self._attributes)
@@ -249,9 +246,6 @@
results_omci['data'].update(get_omci['data'])
- except TimeoutError:
- self.log.debug('missing-timeout')
-
except Exception as e:
self.log.exception('missing-failure', e=e)
@@ -297,9 +291,6 @@
tmp_results.fields['omci_message'].fields['data'][attr] = \
results.fields['omci_message'].fields['data'][attr]
- except TimeoutError as e:
- self.log.debug('attr-timeout')
-
except Exception as e:
self.log.exception('attr-failure', e=e)