Maple OLT adapter alarm reporting.
Change-Id: If4e8247aa7a3d342dc5adc83676e6666bec246b9
diff --git a/.gitignore b/.gitignore
index 54f698f..8f1c1a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,8 @@
# Editors
*.bak
+*.project
+*.pydevproject
# Docker
.docker-base-built
diff --git a/voltha/adapters/maple_olt/maple_olt.py b/voltha/adapters/maple_olt/maple_olt.py
index 988e6f2..0b89967 100644
--- a/voltha/adapters/maple_olt/maple_olt.py
+++ b/voltha/adapters/maple_olt/maple_olt.py
@@ -43,11 +43,14 @@
from google.protobuf.empty_pb2 import Empty
from voltha.protos.events_pb2 import KpiEvent, MetricValuePairs
from voltha.protos.events_pb2 import KpiEventType
+from voltha.protos.events_pb2 import AlarmEvent, AlarmEventType, \
+ AlarmEventSeverity, AlarmEventState, AlarmEventCategory
from voltha.protos.logical_device_pb2 import LogicalPort, LogicalDevice
-from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, OFPPF_1GB_FD, \
- OFPC_GROUP_STATS, OFPC_PORT_STATS, OFPC_TABLE_STATS, OFPC_FLOW_STATS, \
- OFPP_CONTROLLER, OFPXMC_OPENFLOW_BASIC, ofp_switch_features, ofp_desc, ofp_port
+from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, \
+ OFPPF_1GB_FD, OFPC_GROUP_STATS, OFPC_PORT_STATS, OFPC_TABLE_STATS, \
+ OFPC_FLOW_STATS, OFPP_CONTROLLER, OFPXMC_OPENFLOW_BASIC, \
+ ofp_switch_features, ofp_desc, ofp_port
from voltha.registry import registry
from voltha.extensions.omci.omci import *
@@ -64,11 +67,13 @@
self.device_id = device_id
self.adapter_agent = adapter.adapter_agent
self.adapter_name = adapter.name
- self.pb_server_ip = '192.168.24.20' # registry('main').get_args().external_host_address
+ # registry('main').get_args().external_host_address
+ self.pb_server_ip = '192.168.24.20'
self.pb_server_port = 24497
self.pb_server_factory = pb.PBServerFactory(self)
# start PB server
- self.listen_port = reactor.listenTCP(self.pb_server_port, self.pb_server_factory)
+ self.listen_port = reactor.listenTCP(self.pb_server_port,
+ self.pb_server_factory)
self.omci_rx_queue = DeferredQueue()
log.info('PB-server-started-on-port', port=self.pb_server_port)
@@ -128,7 +133,8 @@
event_str=event,
event_data=event_data)
- def remote_report_alarm(self, object, key, alarm, status, priority, alarm_data=None):
+ def remote_report_alarm(self, object, key, alarm, status, priority,
+ alarm_data=None):
log.info('received-alarm-msg',
object=object,
key=key,
@@ -137,6 +143,40 @@
priority=priority,
alarm_data=alarm_data)
+ id = 'voltha.{}.{}.{}'.format(self.adapter_name, self.device_id, object)
+ description = '{} Alarm - {} - {}'.format(object.upper(), alarm.upper(),
+ 'Raised' if status else 'Cleared')
+
+ if priority == 'low':
+ severity = AlarmEventSeverity.MINOR
+ elif priority == 'medium':
+ severity = AlarmEventSeverity.MAJOR
+ elif priority == 'high':
+ severity = AlarmEventSeverity.CRITICAL
+ else:
+ severity = AlarmEventSeverity.INDETERMINATE
+
+ try:
+ ts = arrow.utcnow().timestamp
+
+ alarm_event = self.adapter_agent.create_alarm(
+ id=id,
+ resource_id=str(key),
+ type=AlarmEventType.EQUIPMENT,
+ category=AlarmEventCategory.PON,
+ severity=severity,
+ state=AlarmEventState.RAISED if status else \
+ AlarmEventState.CLEARED,
+ description=description,
+ context=alarm_data,
+ raised_ts = ts)
+
+ self.adapter_agent.submit_alarm(alarm_event)
+
+ except Exception as e:
+ log.exception('failed-to-submit-alarm', e=e)
+
+
@implementer(IAdapterInterface)
class MapleOltAdapter(object):
@@ -249,14 +289,16 @@
def clientConnectionLost(self, connector, reason, reconnecting=0):
log.info('pb-client-connection-lost')
- pb.PBClientFactory.clientConnectionLost(self, connector, reason, reconnecting=1)
+ pb.PBClientFactory.clientConnectionLost(self, connector, reason,
+ reconnecting=1)
ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
log.info('pb-client-connection-lost-retrying')
def clientConnectionFailed(self, connector, reason):
log.info('pb-client-connection-failed')
pb.PBClientFactory.clientConnectionFailed(self, connector, reason)
- ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
+ ReconnectingClientFactory.clientConnectionFailed(self, connector,
+ reason)
log.info('pb-client-connection-failed-retrying')
def disconnect(self, stopTrying=0):
@@ -328,7 +370,8 @@
self.log.info('set-remote-exception', exc=str(e))
@inlineCallbacks
- def send_config_classifier(self, olt_no, etype, ip_proto=None, dst_port=None):
+ def send_config_classifier(self, olt_no, etype, ip_proto=None,
+ dst_port=None):
self.log.info('configuring-classifier',
olt=olt_no,
etype=etype,
@@ -346,7 +389,8 @@
self.log.info('config-classifier-exception', exc=str(e))
@inlineCallbacks
- def send_config_acflow(self, olt_no, onu_no, etype, ip_proto=None, dst_port=None):
+ def send_config_acflow(self, olt_no, onu_no, etype, ip_proto=None,
+ dst_port=None):
self.log.info('configuring-acflow',
olt=olt_no,
onu=onu_no,
@@ -487,19 +531,20 @@
def heartbeat(self, device_id, state='run'):
"""Heartbeat OLT hardware
- Call PB remote method 'heartbeat' to verify connectivity to OLT hardware.
- If heartbeat missed self.heartbeat_failed_limit times OLT adapter is set
- FAILED/UNREACHABLE.
- No further action from VOLTHA core is expected as result of heartbeat failure.
- Heartbeat continues following failure and once connectivity is restored adapter
- state will be set to ACTIVE/REACHABLE
+ Call PB remote method 'heartbeat' to verify connectivity to OLT
+ hardware. If heartbeat missed self.heartbeat_failed_limit times OLT
+ adapter is set FAILED/UNREACHABLE.
+ No further action from VOLTHA core is expected as result of heartbeat
+ failure. Heartbeat continues following failure and once connectivity is
+ restored adapter state will be set to ACTIVE/REACHABLE
Arguments:
device_id: adapter device id
state: desired state (stop, start, run)
"""
- self.log.debug('olt-heartbeat', device=device_id, state=state, count=self.heartbeat_count)
+ self.log.debug('olt-heartbeat', device=device_id, state=state,
+ count=self.heartbeat_count)
def add_timeout(d, duration):
return reactor.callLater(duration, d.cancel)
@@ -509,6 +554,31 @@
t.cancel()
self.log.debug('olt-heartbeat-timeout-cancelled')
+ def heartbeat_alarm(device_id, status, heartbeat_misses=0):
+ try:
+ ts = arrow.utcnow().timestamp
+
+ alarm_data = {'heartbeats_missed':str(heartbeat_misses)}
+
+ alarm_event = self.adapter_agent.create_alarm(
+ id='voltha.{}.{}.olt'.format(self.adapter.name, device_id),
+ resource_id='olt',
+ type=AlarmEventType.EQUIPMENT,
+ category=AlarmEventCategory.PON,
+ severity=AlarmEventSeverity.CRITICAL,
+ state=AlarmEventState.RAISED if status else
+ AlarmEventState.CLEARED,
+ description='OLT Alarm - Heartbeat - {}'.format('Raised'
+ if status
+ else 'Cleared'),
+ context=alarm_data,
+ raised_ts = ts)
+
+ self.adapter_agent.submit_alarm(alarm_event)
+
+ except Exception as e:
+ log.exception('failed-to-submit-alarm', e=e)
+
if state == 'stop':
return
@@ -528,12 +598,14 @@
cancel_timeout(timeout)
except Exception as e:
data = -1
- self.log.info('olt-heartbeat-exception', data=data, count=self.heartbeat_miss, exc=str(e))
+ self.log.info('olt-heartbeat-exception', data=data,
+ count=self.heartbeat_miss, exc=str(e))
if data != self.heartbeat_count:
# something is not right
self.heartbeat_miss += 1
- self.log.info('olt-heartbeat-miss', data=data, count=self.heartbeat_count, miss=self.heartbeat_miss)
+ self.log.info('olt-heartbeat-miss', data=data,
+ count=self.heartbeat_count, miss=self.heartbeat_miss)
else:
if self.heartbeat_miss > 0:
self.heartbeat_miss = 0
@@ -542,17 +614,21 @@
_device.oper_status = OperStatus.ACTIVE
_device.reason = ''
self.adapter_agent.update_device(_device)
+ heartbeat_alarm(device_id, 0)
_device = self.adapter_agent.get_device(device_id)
- if (self.heartbeat_miss >= self.heartbeat_failed_limit) and (_device.connect_status == ConnectStatus.REACHABLE):
- self.log.info('olt-heartbeat-failed', data=data, count=self.heartbeat_miss)
+ if (self.heartbeat_miss >= self.heartbeat_failed_limit) and \
+ (_device.connect_status == ConnectStatus.REACHABLE):
+ self.log.info('olt-heartbeat-failed', data=data,
+ count=self.heartbeat_miss)
_device = self.adapter_agent.get_device(device_id)
_device.connect_status = ConnectStatus.UNREACHABLE
_device.oper_status = OperStatus.FAILED
_device.reason = 'Lost connectivity to OLT'
self.adapter_agent.update_device(_device)
+ heartbeat_alarm(device_id, 1, self.heartbeat_miss)
- self.heartbeat_count += 1
+ self.heartbeat_count += 1
reactor.callLater(self.heartbeat_interval, self.heartbeat, device_id)
@inlineCallbacks
@@ -588,7 +664,8 @@
))
ld = LogicalDevice(
- # not setting id and datapth_id will let the adapter agent pick id
+ # not setting id and datapth_id will let the adapter
+ # agent pick id
desc=ofp_desc(
mfr_desc='cord project',
hw_desc='n/a',
@@ -846,8 +923,10 @@
action_type=action.type, in_port=_in_port)
if is_upstream(_in_port):
- yield self.send_config_classifier(0, _type, _ip_proto, _udp_dst)
- yield self.send_config_acflow(0, _in_port, _type, _ip_proto, _udp_dst)
+ yield self.send_config_classifier(0, _type, _ip_proto,
+ _udp_dst)
+ yield self.send_config_acflow(0, _in_port, _type, _ip_proto,
+ _udp_dst)
except Exception as e:
log.exception('failed-to-install-flow', e=e, flow=flow)
@@ -890,10 +969,12 @@
@inlineCallbacks
def send_configure_stats_collection_interval(self, olt_no, interval):
- self.log.info('configuring-stats-collect-interval', olt=olt_no, interval=interval)
+ self.log.info('configuring-stats-collect-interval', olt=olt_no,
+ interval=interval)
try:
remote = yield self.get_channel()
- data = yield remote.callRemote('set_stats_collection_interval', interval)
+ data = yield remote.callRemote('set_stats_collection_interval',
+ interval)
self.log.info('configured-stats-collect-interval', data=data)
except Exception as e:
- self.log.info('configure-stats-collect-interval', exc=str(e))
+ self.log.exception('configure-stats-collect-interval', exc=str(e))