Fix install O2 on subcloud failed
[pti/o2.git] / o2ims / service / command / purge_alarm_handler.py
1 # Copyright (C) 2024 Wind River Systems, Inc.
2 #
3 #  Licensed under the Apache License, Version 2.0 (the "License");
4 #  you may not use this file except in compliance with the License.
5 #  You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #  Unless required by applicable law or agreed to in writing, software
10 #  distributed under the License is distributed on an "AS IS" BASIS,
11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 #  See the License for the specific language governing permissions and
13 #  limitations under the License.
14
15 import json
16
17 from o2common.adapter.notifications import AbstractNotifications
18 from o2common.config import conf
19 from o2common.domain.filter import gen_orm_filter
20 from o2common.helper import o2logging
21 from o2common.service.unit_of_work import AbstractUnitOfWork
22 from o2ims.adapter.clients.fault_client import StxAlarmClient
23 from o2ims.domain import commands, alarm_obj
24 logger = o2logging.get_logger(__name__)
25
26
27 def purge_alarm_event(
28     cmd: commands.PubAlarm2SMO,
29     uow: AbstractUnitOfWork,
30     notifications: AbstractNotifications,
31 ):
32     """
33     Purges an alarm event and notifies relevant subscribers.
34
35     This method performs the following steps:
36     1. Retrieves data from the command object and initializes the fault client.
37     2. Uses the Unit of Work pattern to find and delete the corresponding
38        alarm event record.
39     3. Updates the alarm event record's hash, extensions, changed time,
40        and perceived severity.
41     4. Commits the changes to the database.
42     5. Finds and processes all alarm subscriptions, deciding whether to
43        send notifications based on subscription filters.
44
45     Parameters:
46     - cmd (commands.PubAlarm2SMO): Command object containing the alarm
47       event data.
48     - uow (AbstractUnitOfWork): Unit of Work object for managing
49       database transactions.
50     - notifications (AbstractNotifications): Abstract notifications
51       object for sending notifications.
52
53     Exceptions:
54     - Any exceptions that might occur during database operations or
55       notification sending.
56     """
57     fault_client = StxAlarmClient(uow)
58     data = cmd.data
59     with uow:
60         alarm_event_record = uow.alarm_event_records.get(data.id)
61         alarm = fault_client.delete(alarm_event_record.alarmEventRecordId)
62         alarm_event_record.hash = alarm.hash
63         alarm_event_record.extensions = json.dumps(alarm.filtered)
64         alarm_event_record.alarmChangedTime = alarm.updatetime.\
65             strftime("%Y-%m-%dT%H:%M:%S")
66         alarm_event_record.perceivedSeverity = \
67             alarm_obj.PerceivedSeverityEnum.CLEARED
68
69         uow.alarm_event_records.update(alarm_event_record)
70
71         uow.commit()
72
73         alarm = uow.alarm_event_records.get(data.id)
74         subs = uow.alarm_subscriptions.list()
75         for sub in subs:
76             sub_data = sub.serialize()
77             logger.debug('Alarm Subscription: {}'.format(
78                 sub_data['alarmSubscriptionId']))
79
80             if not sub_data.get('filter', None):
81                 callback_smo(notifications, sub, data, alarm)
82                 continue
83             try:
84                 args = gen_orm_filter(alarm_obj.AlarmEventRecord,
85                                       sub_data['filter'])
86             except KeyError:
87                 logger.warning(
88                     'Alarm Subscription {} filter {} has wrong attribute '
89                     'name or value. Ignore the filter'.format(
90                         sub_data['alarmSubscriptionId'],
91                         sub_data['filter']))
92                 callback_smo(notifications, sub, data, alarm)
93                 continue
94             args.append(alarm_obj.AlarmEventRecord.
95                         alarmEventRecordId == data.id)
96             count, _ = uow.alarm_event_records.list_with_count(*args)
97             if count != 0:
98                 logger.debug(
99                     'Alarm Event {} skip for subscription {} because of '
100                     'the filter.'
101                     .format(data.id, sub_data['alarmSubscriptionId']))
102                 continue
103             callback_smo(notifications, sub, data, alarm)
104
105
106 def callback_smo(notifications: AbstractNotifications,
107                  sub: alarm_obj.AlarmSubscription,
108                  msg: alarm_obj.AlarmEvent2SMO,
109                  alarm: alarm_obj.AlarmEventRecord):
110     sub_data = sub.serialize()
111     alarm_data = alarm.serialize()
112     callback = {
113         'globalCloudID': conf.DEFAULT.ocloud_global_id,
114         'consumerSubscriptionId': sub_data['consumerSubscriptionId'],
115         'notificationEventType': msg.notificationEventType,
116         'objectRef': msg.objectRef,
117         'alarmEventRecordId': alarm_data['alarmEventRecordId'],
118         'resourceTypeID': alarm_data['resourceTypeId'],
119         'resourceID': alarm_data['resourceId'],
120         'alarmDefinitionID': alarm_data['alarmDefinitionId'],
121         'probableCauseID': alarm_data['probableCauseId'],
122         'alarmRaisedTime': alarm_data['alarmRaisedTime'],
123         'alarmChangedTime': alarm_data['alarmChangedTime'],
124         'alarmAcknowledgeTime': alarm_data['alarmAcknowledgeTime'],
125         'alarmAcknowledged': alarm_data['alarmAcknowledged'],
126         'perceivedSeverity': alarm_data['perceivedSeverity'],
127         'extensions': json.loads(alarm_data['extensions'])
128     }
129     logger.info('callback URL: {}'.format(sub_data['callback']))
130     logger.debug('callback data: {}'.format(json.dumps(callback)))
131
132     return notifications.send(sub_data['callback'], callback)