blob: 3adce23e748bffcef8c82069e065bb50468352c7 [file] [log] [blame]
Scott Baker12687732019-03-19 15:40:57 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
17import datetime
18import json
19import time
20from xossynchronizer.event_steps.eventstep import EventStep
21from xosconfig import Config
22from xoskafka import XOSKafkaProducer
23from multistructlog import create_logger
24
25log = create_logger(Config().get('logging'))
26
27
28class OnosPortEventStep(EventStep):
29 topics = ["onos.events.port"]
30 technology = "kafka"
31
32 def __init__(self, *args, **kwargs):
33 super(OnosPortEventStep, self).__init__(*args, **kwargs)
34
35 def subscriber_olt_closure(self, olt):
36 subscribers = []
37 for pon_port in olt.pon_ports.all():
38 for onu_device in pon_port.onu_devices.all():
39 for si in onu_device.volt_service_instances.all():
40 for subscriber in si.westbound_service_instances:
41 subscribers.append(subscriber)
42 return subscribers
43
Scott Baker12687732019-03-19 15:40:57 -070044 def send_alarm(self, olt, value):
45 timestamp = time.mktime(datetime.datetime.strptime(value["timestamp"], "%Y-%m-%dT%H:%M:%S.%fZ").timetuple())
46 state = "RAISED" if olt.link_status == "down" else "CLEARED"
47
48 # Hypothetically, a maximum of 64 subscribers per pon port, 16 pon ports, and 32 characters
49 # per subscriber name = 32KB of subscriber names in the event.
50 subscribers = self.subscriber_olt_closure(olt)
51 subscribers = [x.name for x in subscribers]
52
53 alarm = {"category": "OLT",
54 "reported_ts": time.time(),
55 "raised_ts": timestamp,
56 "state": state,
Scott Baker2a4dacb2019-04-03 13:00:35 -070057 "alarm_type_name": "OLT.PORT_LOS",
Scott Baker12687732019-03-19 15:40:57 -070058 "severity": "MAJOR",
59 "resource_id": olt.device_id,
60 "logical_device_id": olt.dp_id,
Scott Baker2a4dacb2019-04-03 13:00:35 -070061 "context": {"affected_subscribers": subscribers,
62 "switch_datapath_id": olt.switch_datapath_id,
63 "switch_port": olt.switch_port,
64 "oltdevice.name": olt.name},
Scott Baker12687732019-03-19 15:40:57 -070065 "type": "COMMUNICATION",
Scott Baker2a4dacb2019-04-03 13:00:35 -070066 "id": "xos.voltservice.%s.OLT_PORT_LOS" % olt.device_id,
67 "description": "xos.voltservice.%s - OLT PORT LOS Alarm -"
68 " OLT_PORT_LOS - %s" % (olt.device_id, state)}
Scott Baker12687732019-03-19 15:40:57 -070069
70 topic = "xos.alarms.olt-service"
71 key = olt.device_id
72 value = json.dumps(alarm, default=lambda o: repr(o))
73
74 XOSKafkaProducer.produce(topic, key, value)
75
76 def process_event(self, event):
77 log.info("Received ONOS Port Event", kafka_event=event)
78
79 value = json.loads(event.value)
80
81 olt = self.model_accessor.OLTDevice.objects.filter(switch_datapath_id=value["deviceId"],
82 switch_port=value["portId"])
83 if not olt:
84 log.info("Onos port event not for a known olt", deviceId=value["deviceId"], portId=value["portId"])
85 return
86
87 olt = olt[0]
88
89 link_status = "up" if value["enabled"] else "down"
90 if link_status != olt.link_status:
91 olt.link_status = link_status
92 olt.save_changed_fields()
93 self.send_alarm(olt, value)