nsr_id=nsr_id,
vnf_member_index=vnfr["member-vnf-index-ref"],
vdu_name=vdur["name"],
+ last_action='insufficient-data',
+ id_suffix=0,
+ ok_ack=False,
+ alarm_ack=False
)
for action_type in ["ok", "insufficient-data", "alarm"]:
if (
"Handling vnf alarm %s with status %s", alarm.alarm_id, status
)
for action in alarm.actions:
+ """
+ Compares the current status with the last_action status.
+ If both the status are 'alarm', it avoid sending repetitive alarm notification.
+ If both the status are 'ok', it avoid sending repetitive ok notification.
+ """
if action.type == status:
- log.info(
- "Executing request to url %s for vnf alarm %s with status %s",
- action.url,
- alarm.alarm_id,
- status,
- )
- try:
- requests.post(url=action.url, json=json.dumps(payload), timeout=alert_timeout)
- except RequestException as e:
- log.info("Error: RequestException while connecting to url %s", action.url)
- log.debug("RequestException %s", e)
- except ConnectionError:
- log.exception("Error connecting to url %s", action.url)
+ if bool(self.conf.get('alert', 'enhanced_alarms')):
+ if ((status != "ok" or (status == "ok" and alarm.ok_ack is False)) and
+ (status != "alarm" or (status == "alarm" and alarm.alarm_ack is False))):
+ log.info(
+ "Executing request to url %s for vnf alarm %s with status %s",
+ action.url,
+ alarm.alarm_id,
+ status
+ )
+ try:
+ if status == "alarm" and alarm.last_action == "ok":
+ alarm.id_suffix += 1
+ alarm.ok_ack = False
+ if status == "ok" and alarm.last_action == "alarm":
+ alarm.alarm_ack = False
+ alarm.last_action = status
+ alarm.save()
+ except Exception as e:
+ log.exception(e)
+
+ payload["notify_details"]["alarm_number"] = alarm.id_suffix
+ headers = {"content-type": "application/json"}
+ try:
+ resp = requests.post(url=action.url, data=json.dumps(payload),
+ headers=headers, verify=False, timeout=alert_timeout)
+ log.info("Response %s", resp)
+ if resp.status_code == 200:
+ if status == "ok":
+ alarm.ok_ack = True
+ alarm.save()
+ if status == "alarm":
+ alarm.alarm_ack = True
+ alarm.save()
+ if status == "insufficient-data":
+ alarm.alarm_ack = False
+ alarm.ok_ack = False
+ alarm.save()
+ except RequestException as e:
+ log.info("Error: RequestException while connecting to url %s", action.url)
+ log.debug("RequestException %s", e)
+
+ except ConnectionError:
+ log.exception("Error connecting to url %s", action.url)
+ else:
+ log.info(
+ "Executing request to url %s for vnf alarm %s with status %s",
+ action.url,
+ alarm.alarm_id,
+ status
+ )
+ try:
+ requests.post(url=action.url, json=json.dumps(payload), timeout=alert_timeout)
+ except RequestException as e:
+ log.info("Error: RequestException while connecting to url %s", action.url)
+ log.debug("RequestException %s", e)
+ except ConnectionError:
+ log.exception("Error connecting to url %s", action.url)
except VnfAlarm.DoesNotExist:
log.debug(
def setUp(self):
self.config = Config()
self.loop = asyncio.new_event_loop()
+ self.payload = {
+ "notify_details": {
+ "alarm_number": 0
+ }
+ }
+ self.headers = {"content-type": "application/json"}
@mock.patch.object(VnfAlarmRepository, "get")
@mock.patch("requests.post")
@mock.patch("osm_policy_module.core.database.db")
- def test_handle_alarm(self, database, requests_post, get_alarm):
+ def test_handle_alarm_suppression(self, database, requests_post, get_alarm):
alert_timeout = int(self.config.get('alert', 'timeout'))
- mock_alarm = self._build_mock_alarm("test_id")
+ mock_alarm = self._build_mock_alarm("test_id", last_action="ok")
get_alarm.return_value = mock_alarm
-
service = AlarmingService(self.config)
- self.loop.run_until_complete(service.handle_alarm("test_id", "alarm", {}))
- requests_post.assert_called_once_with(json="{}", url="http://alarm-url/", timeout=alert_timeout)
+ if bool(self.config.get('alert', 'enhanced_alarms')):
+ self.loop.run_until_complete(service.handle_alarm("test_id", "alarm", self.payload))
+ requests_post.assert_called_once_with(
+ url='http://alarm-url/', data='{"notify_details": {"alarm_number": 1}}',
+ headers={'content-type': 'application/json'}, verify=False, timeout=alert_timeout
+ )
+ else:
+ self.loop.run_until_complete(service.handle_alarm("test_id", "alarm", {}))
+ requests_post.assert_called_once_with(json="{}", url="http://alarm-url/", timeout=alert_timeout)
- requests_post.reset_mock()
- self.loop.run_until_complete(service.handle_alarm("test_id", "ok", {}))
- requests_post.assert_called_once_with(json="{}", url="http://ok-url/", timeout=alert_timeout)
+ @mock.patch.object(VnfAlarmRepository, "get")
+ @mock.patch("requests.post")
+ @mock.patch("osm_policy_module.core.database.db")
+ def test_handle_ok_suppression(self, database, requests_post, get_alarm):
+ alert_timeout = int(self.config.get('alert', 'timeout'))
+ mock_alarm = self._build_mock_alarm("test_id", last_action="alarm")
+ get_alarm.return_value = mock_alarm
+ service = AlarmingService(self.config)
+ if bool(self.config.get('alert', 'enhanced_alarms')):
+ self.loop.run_until_complete(service.handle_alarm("test_id", "ok", self.payload))
+ requests_post.assert_called_once_with(
+ url='http://ok-url/', data='{"notify_details": {"alarm_number": 0}}',
+ headers={'content-type': 'application/json'}, verify=False, timeout=alert_timeout
+ )
+ else:
+ self.loop.run_until_complete(service.handle_alarm("test_id", "ok", {}))
+ requests_post.assert_called_once_with(json="{}", url="http://ok-url/", timeout=alert_timeout)
- requests_post.reset_mock()
- self.loop.run_until_complete(
- service.handle_alarm("test_id", "insufficient-data", {})
- )
- requests_post.assert_called_once_with(
- json="{}", url="http://insufficient-data-url/", timeout=alert_timeout
- )
+ @mock.patch.object(VnfAlarmRepository, "get")
+ @mock.patch("requests.post")
+ @mock.patch("osm_policy_module.core.database.db")
+ def test_handle_insufficientalarm(self, database, requests_post, get_alarm):
+ alert_timeout = int(self.config.get('alert', 'timeout'))
+ mock_alarm = self._build_mock_alarm("test_id")
+ get_alarm.return_value = mock_alarm
+ service = AlarmingService(self.config)
+ if bool(self.config.get('alert', 'enhanced_alarms')):
+ self.loop.run_until_complete(
+ service.handle_alarm("test_id", "insufficient-data", self.payload)
+ )
+ requests_post.assert_called_once_with(
+ url='http://insufficient-data-url/', data='{"notify_details": {"alarm_number": 0}}',
+ headers={'content-type': 'application/json'}, verify=False, timeout=alert_timeout
+ )
+ else:
+ self.loop.run_until_complete(
+ service.handle_alarm("test_id", "insufficient-data", {})
+ )
+ requests_post.assert_called_once_with(
+ json="{}", url='http://insufficient-data-url/', timeout=alert_timeout
+ )
@mock.patch.object(VnfAlarmRepository, "get")
@mock.patch("requests.post")
def test_handle_alarm_unknown_status(self, database, requests_post, get_alarm):
mock_alarm = self._build_mock_alarm("test_id")
get_alarm.return_value = mock_alarm
-
service = AlarmingService(self.config)
self.loop.run_until_complete(service.handle_alarm("test_id", "unknown", {}))
requests_post.assert_not_called()
alarm_url="http://alarm-url/",
insufficient_data_url="http://insufficient-data-url/",
ok_url="http://ok-url/",
+ id_suffix=0,
+ last_action="insufficient-data"
):
mock_alarm = mock.Mock()
mock_alarm.alarm_id = alarm_id
ok_action = mock.Mock()
ok_action.type = "ok"
ok_action.url = ok_url
+ mock_alarm.ok_ack = False
+ mock_alarm.alarm_ack = False
+ mock_alarm.id_suffix = id_suffix
+ mock_alarm.last_action = last_action
mock_alarm.actions = [insufficient_data_action, alarm_action, ok_action]
return mock_alarm