blob: 19f317db050d9f6844019014e3e87ce2bc1326c8 [file] [log] [blame]
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -03001# -*- coding: utf-8 -*-
2
3# Copyright 2018 Whitestack, LLC
4# *************************************************************
5
6# This file is part of OSM Monitoring module
7# All Rights Reserved to Whitestack, LLC
8
9# Licensed under the Apache License, Version 2.0 (the "License"); you may
10# not use this file except in compliance with the License. You may obtain
11# a copy of the License at
12
13# http://www.apache.org/licenses/LICENSE-2.0
14
15# Unless required by applicable law or agreed to in writing, software
16# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18# License for the specific language governing permissions and limitations
19# under the License.
20
21# For those usages not covered by the Apache License, Version 2.0 please
22# contact: bdiaz@whitestack.com or glavado@whitestack.com
23##
Benjamin Diaz16256cb2018-10-11 12:34:20 -030024import asyncio
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -030025import json
26import logging
27import random
Benjamin Diaz127bbba2018-11-26 18:05:53 -030028from json import JSONDecodeError
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -030029
Benjamin Diaz127bbba2018-11-26 18:05:53 -030030import yaml
Benjamin Diaz16256cb2018-10-11 12:34:20 -030031from aiokafka import AIOKafkaProducer, AIOKafkaConsumer
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -030032
33from osm_policy_module.core.config import Config
34
35log = logging.getLogger(__name__)
36
37
38class MonClient:
Benjamin Diaza14cf162019-02-01 13:31:47 -030039 def __init__(self, config: Config, loop=None):
40 self.kafka_server = '{}:{}'.format(config.get('message', 'host'),
41 config.get('message', 'port'))
Benjamin Diaz16256cb2018-10-11 12:34:20 -030042 if not loop:
43 loop = asyncio.get_event_loop()
44 self.loop = loop
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -030045
Benjamin Diaz3736ad82019-06-05 16:24:34 -030046 async def create_alarm(self, metric_name: str, ns_id: str, vdu_name: str, vnf_member_index: str, threshold: int,
Benjamin Diaz16256cb2018-10-11 12:34:20 -030047 statistic: str, operation: str):
48 cor_id = random.randint(1, 10e7)
Benjamin Diazf7451f82019-04-01 14:56:26 -030049 msg = self._build_create_alarm_payload(cor_id,
50 metric_name,
51 ns_id,
52 vdu_name,
53 vnf_member_index,
54 threshold,
Benjamin Diazf35f9142018-10-08 16:25:36 -030055 statistic,
56 operation)
Benjamin Diazf7451f82019-04-01 14:56:26 -030057 log.debug("Sending create_alarm_request %s", msg)
Benjamin Diaz16256cb2018-10-11 12:34:20 -030058 producer = AIOKafkaProducer(loop=self.loop,
59 bootstrap_servers=self.kafka_server,
60 key_serializer=str.encode,
61 value_serializer=str.encode)
62 await producer.start()
Benjamin Diaz16256cb2018-10-11 12:34:20 -030063 try:
64 await producer.send_and_wait("alarm_request", key="create_alarm_request", value=json.dumps(msg))
65 finally:
66 await producer.stop()
Benjamin Diazf7451f82019-04-01 14:56:26 -030067 log.debug("Waiting for create_alarm_response...")
Benjamin Diaz127bbba2018-11-26 18:05:53 -030068 consumer = AIOKafkaConsumer(
69 "alarm_response_" + str(cor_id),
70 loop=self.loop,
71 bootstrap_servers=self.kafka_server,
72 key_deserializer=bytes.decode,
73 value_deserializer=bytes.decode,
74 auto_offset_reset='earliest')
75 await consumer.start()
76 alarm_uuid = None
Benjamin Diaz16256cb2018-10-11 12:34:20 -030077 try:
78 async for message in consumer:
Benjamin Diaz127bbba2018-11-26 18:05:53 -030079 try:
Benjamin Diaz16256cb2018-10-11 12:34:20 -030080 content = json.loads(message.value)
Benjamin Diaz127bbba2018-11-26 18:05:53 -030081 except JSONDecodeError:
82 content = yaml.safe_load(message.value)
Benjamin Diazf7451f82019-04-01 14:56:26 -030083 log.debug("Received create_alarm_response %s", content)
Benjamin Diaz127bbba2018-11-26 18:05:53 -030084 if content['alarm_create_response']['correlation_id'] == cor_id:
85 if not content['alarm_create_response']['status']:
86 raise ValueError("Error creating alarm in MON")
87 alarm_uuid = content['alarm_create_response']['alarm_uuid']
88 break
Benjamin Diaz16256cb2018-10-11 12:34:20 -030089 finally:
90 await consumer.stop()
Benjamin Diaz127bbba2018-11-26 18:05:53 -030091 if not alarm_uuid:
92 raise ValueError('No alarm deletion response from MON. Is MON up?')
93 return alarm_uuid
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -030094
Benjamin Diaz3736ad82019-06-05 16:24:34 -030095 async def delete_alarm(self, ns_id: str, vnf_member_index: str, vdu_name: str, alarm_uuid: str):
Benjamin Diaz16256cb2018-10-11 12:34:20 -030096 cor_id = random.randint(1, 10e7)
Benjamin Diazf35f9142018-10-08 16:25:36 -030097 msg = self._build_delete_alarm_payload(cor_id, ns_id, vdu_name, vnf_member_index, alarm_uuid)
Benjamin Diazf7451f82019-04-01 14:56:26 -030098 log.debug("Sending delete_alarm_request %s", msg)
Benjamin Diaz16256cb2018-10-11 12:34:20 -030099 producer = AIOKafkaProducer(loop=self.loop,
100 bootstrap_servers=self.kafka_server,
101 key_serializer=str.encode,
102 value_serializer=str.encode)
103 await producer.start()
Benjamin Diaz16256cb2018-10-11 12:34:20 -0300104 try:
105 await producer.send_and_wait("alarm_request", key="delete_alarm_request", value=json.dumps(msg))
106 finally:
107 await producer.stop()
Benjamin Diazf7451f82019-04-01 14:56:26 -0300108 log.debug("Waiting for delete_alarm_response...")
Benjamin Diaz127bbba2018-11-26 18:05:53 -0300109 consumer = AIOKafkaConsumer(
110 "alarm_response_" + str(cor_id),
111 loop=self.loop,
112 bootstrap_servers=self.kafka_server,
113 key_deserializer=bytes.decode,
114 value_deserializer=bytes.decode,
115 auto_offset_reset='earliest')
116 await consumer.start()
117 alarm_uuid = None
Benjamin Diaz16256cb2018-10-11 12:34:20 -0300118 try:
119 async for message in consumer:
Benjamin Diaz127bbba2018-11-26 18:05:53 -0300120 try:
Benjamin Diaz16256cb2018-10-11 12:34:20 -0300121 content = json.loads(message.value)
Benjamin Diaz127bbba2018-11-26 18:05:53 -0300122 except JSONDecodeError:
123 content = yaml.safe_load(message.value)
124 if content['alarm_delete_response']['correlation_id'] == cor_id:
Benjamin Diazf7451f82019-04-01 14:56:26 -0300125 log.debug("Received delete_alarm_response %s", content)
Benjamin Diaz127bbba2018-11-26 18:05:53 -0300126 if not content['alarm_delete_response']['status']:
127 raise ValueError("Error deleting alarm in MON. Response status is False.")
128 alarm_uuid = content['alarm_delete_response']['alarm_uuid']
129 break
Benjamin Diaz16256cb2018-10-11 12:34:20 -0300130 finally:
131 await consumer.stop()
Benjamin Diaz127bbba2018-11-26 18:05:53 -0300132 if not alarm_uuid:
133 raise ValueError('No alarm deletion response from MON. Is MON up?')
134 return alarm_uuid
Benjamin Diazf35f9142018-10-08 16:25:36 -0300135
Benjamin Diazf7451f82019-04-01 14:56:26 -0300136 def _build_create_alarm_payload(self, cor_id: int,
137 metric_name: str,
138 ns_id: str,
139 vdu_name: str,
Benjamin Diaz3736ad82019-06-05 16:24:34 -0300140 vnf_member_index: str,
Benjamin Diazf7451f82019-04-01 14:56:26 -0300141 threshold: int,
142 statistic: str,
143 operation: str):
144
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -0300145 alarm_create_request = {
146 'correlation_id': cor_id,
Benjamin Diaz127bbba2018-11-26 18:05:53 -0300147 'alarm_name': 'osm_alarm_{}_{}_{}_{}'.format(ns_id, vnf_member_index, vdu_name, metric_name),
Benjamin Diaz7f11ecf2018-09-14 12:03:38 -0300148 'metric_name': metric_name,
149 'ns_id': ns_id,
150 'vdu_name': vdu_name,
151 'vnf_member_index': vnf_member_index,
152 'operation': operation,
153 'severity': 'critical',
154 'threshold_value': threshold,
155 'statistic': statistic
156 }
157 msg = {
158 'alarm_create_request': alarm_create_request,
159 }
160 return msg
161
Benjamin Diazf35f9142018-10-08 16:25:36 -0300162 def _build_delete_alarm_payload(self, cor_id: int, ns_id: str, vdu_name: str,
Benjamin Diaz3736ad82019-06-05 16:24:34 -0300163 vnf_member_index: str, alarm_uuid: str):
Benjamin Diazf35f9142018-10-08 16:25:36 -0300164 alarm_delete_request = {
165 'correlation_id': cor_id,
166 'alarm_uuid': alarm_uuid,
167 'ns_id': ns_id,
168 'vdu_name': vdu_name,
169 'vnf_member_index': vnf_member_index
170 }
171 msg = {
172 'alarm_delete_request': alarm_delete_request,
173 }
174 return msg