Remove the notify_alarm method and refactor related tests
The AlarmNotifierService.notify_alarm method is only used in tests, this change remove the method and refactor the related tests. Change-Id: I44f5c0fc14805d38c35108c848f7dc7c3321eb21 Signed-off-by: liusheng <liusheng@huawei.com>
This commit is contained in:
@@ -22,7 +22,7 @@ from oslo_utils import netutils
|
||||
import six
|
||||
from stevedore import extension
|
||||
|
||||
from aodh.i18n import _
|
||||
from aodh.i18n import _LE
|
||||
from aodh import messaging
|
||||
|
||||
|
||||
@@ -80,75 +80,6 @@ class AlarmNotifierService(os_service.Service):
|
||||
self.listener.wait()
|
||||
super(AlarmNotifierService, self).stop()
|
||||
|
||||
def notify_alarm(self, context, data):
|
||||
process_alarm(self.notifiers, data)
|
||||
|
||||
|
||||
def _handle_action(notifiers, action, alarm_id, alarm_name, severity,
|
||||
previous, current, reason, reason_data):
|
||||
"""Process action on alarm
|
||||
|
||||
:param notifiers: list of possible notifiers.
|
||||
:param action: The action that is being attended, as a parsed URL.
|
||||
:param alarm_id: The triggered alarm.
|
||||
:param alarm_name: The name of triggered alarm.
|
||||
:param severity: The level of triggered alarm
|
||||
:param previous: The previous state of the alarm.
|
||||
:param current: The current state of the alarm.
|
||||
:param reason: The reason the alarm changed its state.
|
||||
:param reason_data: A dict representation of the reason.
|
||||
"""
|
||||
|
||||
try:
|
||||
action = netutils.urlsplit(action)
|
||||
except Exception:
|
||||
LOG.error(
|
||||
_("Unable to parse action %(action)s for alarm %(alarm_id)s"),
|
||||
{'action': action, 'alarm_id': alarm_id})
|
||||
return
|
||||
|
||||
try:
|
||||
notifier = notifiers[action.scheme].obj
|
||||
except KeyError:
|
||||
scheme = action.scheme
|
||||
LOG.error(
|
||||
_("Action %(scheme)s for alarm %(alarm_id)s is unknown, "
|
||||
"cannot notify"),
|
||||
{'scheme': scheme, 'alarm_id': alarm_id})
|
||||
return
|
||||
|
||||
try:
|
||||
LOG.debug("Notifying alarm %(id)s with action %(act)s",
|
||||
{'id': alarm_id, 'act': action})
|
||||
notifier.notify(action, alarm_id, alarm_name, severity,
|
||||
previous, current, reason, reason_data)
|
||||
except Exception:
|
||||
LOG.exception(_("Unable to notify alarm %s"), alarm_id)
|
||||
return
|
||||
|
||||
|
||||
def process_alarm(notifiers, data):
|
||||
"""Notify that alarm has been triggered.
|
||||
|
||||
:param notifiers: list of possible notifiers
|
||||
:param data: (dict): alarm data
|
||||
"""
|
||||
|
||||
actions = data.get('actions')
|
||||
if not actions:
|
||||
LOG.error(_("Unable to notify for an alarm with no action"))
|
||||
return
|
||||
|
||||
for action in actions:
|
||||
_handle_action(notifiers, action,
|
||||
data.get('alarm_id'),
|
||||
data.get('alarm_name'),
|
||||
data.get('severity'),
|
||||
data.get('previous'),
|
||||
data.get('current'),
|
||||
data.get('reason'),
|
||||
data.get('reason_data'))
|
||||
|
||||
|
||||
class AlarmEndpoint(object):
|
||||
|
||||
@@ -157,4 +88,70 @@ class AlarmEndpoint(object):
|
||||
|
||||
def sample(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||
"""Endpoint for alarm notifications"""
|
||||
process_alarm(self.notifiers, payload)
|
||||
self._process_alarm(self.notifiers, payload)
|
||||
|
||||
@staticmethod
|
||||
def _handle_action(notifiers, action, alarm_id, alarm_name, severity,
|
||||
previous, current, reason, reason_data):
|
||||
"""Process action on alarm
|
||||
|
||||
:param notifiers: list of possible notifiers.
|
||||
:param action: The action that is being attended, as a parsed URL.
|
||||
:param alarm_id: The triggered alarm.
|
||||
:param alarm_name: The name of triggered alarm.
|
||||
:param severity: The level of triggered alarm
|
||||
:param previous: The previous state of the alarm.
|
||||
:param current: The current state of the alarm.
|
||||
:param reason: The reason the alarm changed its state.
|
||||
:param reason_data: A dict representation of the reason.
|
||||
"""
|
||||
|
||||
try:
|
||||
action = netutils.urlsplit(action)
|
||||
except Exception:
|
||||
LOG.error(
|
||||
_LE("Unable to parse action %(action)s for alarm "
|
||||
"%(alarm_id)s"), {'action': action, 'alarm_id': alarm_id})
|
||||
return
|
||||
|
||||
try:
|
||||
notifier = notifiers[action.scheme].obj
|
||||
except KeyError:
|
||||
scheme = action.scheme
|
||||
LOG.error(
|
||||
_LE("Action %(scheme)s for alarm %(alarm_id)s is unknown, "
|
||||
"cannot notify"),
|
||||
{'scheme': scheme, 'alarm_id': alarm_id})
|
||||
return
|
||||
|
||||
try:
|
||||
LOG.debug("Notifying alarm %(id)s with action %(act)s",
|
||||
{'id': alarm_id, 'act': action})
|
||||
notifier.notify(action, alarm_id, alarm_name, severity,
|
||||
previous, current, reason, reason_data)
|
||||
except Exception:
|
||||
LOG.exception(_LE("Unable to notify alarm %s"), alarm_id)
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
def _process_alarm(notifiers, data):
|
||||
"""Notify that alarm has been triggered.
|
||||
|
||||
:param notifiers: list of possible notifiers
|
||||
:param data: (dict): alarm data
|
||||
"""
|
||||
|
||||
actions = data.get('actions')
|
||||
if not actions:
|
||||
LOG.error(_LE("Unable to notify for an alarm with no action"))
|
||||
return
|
||||
|
||||
for action in actions:
|
||||
AlarmEndpoint._handle_action(notifiers, action,
|
||||
data.get('alarm_id'),
|
||||
data.get('alarm_name'),
|
||||
data.get('severity'),
|
||||
data.get('previous'),
|
||||
data.get('current'),
|
||||
data.get('reason'),
|
||||
data.get('reason_data'))
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import time
|
||||
|
||||
import mock
|
||||
from oslo_config import fixture as fixture_config
|
||||
import oslo_messaging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslotest import mockpatch
|
||||
import requests
|
||||
@@ -55,17 +57,21 @@ class TestAlarmNotifierService(tests_base.BaseTestCase):
|
||||
|
||||
|
||||
class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAlarmNotifier, self).setUp()
|
||||
conf = service.prepare_service(argv=[], config_files=[])
|
||||
self.CONF = self.useFixture(fixture_config.Config(conf)).conf
|
||||
self.setup_messaging(self.CONF)
|
||||
self._msg_notifier = oslo_messaging.Notifier(
|
||||
self.transport, topics=['alarming'], driver='messaging',
|
||||
publisher_id='testpublisher')
|
||||
self.zaqar = FakeZaqarClient(self)
|
||||
self.useFixture(mockpatch.Patch(
|
||||
'aodh.notifier.zaqar.ZaqarAlarmNotifier.get_zaqar_client',
|
||||
return_value=self.zaqar))
|
||||
self.service = notifier.AlarmNotifierService(self.CONF)
|
||||
self.service.start()
|
||||
self.addCleanup(self.service.stop)
|
||||
|
||||
def test_notify_alarm(self):
|
||||
data = {
|
||||
@@ -78,7 +84,8 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
'reason': 'Everything is on fire',
|
||||
'reason_data': {'fire': 'everywhere'}
|
||||
}
|
||||
self.service.notify_alarm({}, data)
|
||||
self._msg_notifier.sample({}, 'alarm.update', data)
|
||||
time.sleep(1)
|
||||
notifications = self.service.notifiers['test'].obj.notifications
|
||||
self.assertEqual(1, len(notifications))
|
||||
self.assertEqual((urlparse.urlsplit(data['actions'][0]),
|
||||
@@ -91,16 +98,6 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
data['reason_data']),
|
||||
notifications[0])
|
||||
|
||||
def test_notify_alarm_no_action(self):
|
||||
self.service.notify_alarm({}, {})
|
||||
|
||||
def test_notify_alarm_log_action(self):
|
||||
self.service.notify_alarm({},
|
||||
{
|
||||
'actions': ['log://'],
|
||||
'alarm_id': 'foobar',
|
||||
'condition': {'threshold': 42}})
|
||||
|
||||
@staticmethod
|
||||
def _notification(action):
|
||||
notification = {}
|
||||
@@ -112,8 +109,10 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
action = 'http://host/action'
|
||||
|
||||
with mock.patch.object(requests.Session, 'post') as poster:
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({},
|
||||
'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
poster.assert_called_with(action, data=mock.ANY,
|
||||
headers=mock.ANY)
|
||||
args, kwargs = poster.call_args
|
||||
@@ -133,8 +132,10 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
self.CONF.set_override("rest_notifier_certificate_file", certificate)
|
||||
|
||||
with mock.patch.object(requests.Session, 'post') as poster:
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({},
|
||||
'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
poster.assert_called_with(action, data=mock.ANY,
|
||||
headers=mock.ANY,
|
||||
cert=certificate, verify=True)
|
||||
@@ -157,8 +158,10 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
self.CONF.set_override("rest_notifier_certificate_key", key)
|
||||
|
||||
with mock.patch.object(requests.Session, 'post') as poster:
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({},
|
||||
'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
poster.assert_called_with(action, data=mock.ANY,
|
||||
headers=mock.ANY,
|
||||
cert=(certificate, key), verify=True)
|
||||
@@ -177,8 +180,10 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
self.CONF.set_override("rest_notifier_ssl_verify", False)
|
||||
|
||||
with mock.patch.object(requests.Session, 'post') as poster:
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({},
|
||||
'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
poster.assert_called_with(action, data=mock.ANY,
|
||||
headers=mock.ANY,
|
||||
verify=False)
|
||||
@@ -196,8 +201,10 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
action = 'https://host/action?aodh-alarm-ssl-verify=0'
|
||||
|
||||
with mock.patch.object(requests.Session, 'post') as poster:
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({},
|
||||
'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
poster.assert_called_with(action, data=mock.ANY,
|
||||
headers=mock.ANY,
|
||||
verify=False)
|
||||
@@ -217,8 +224,10 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
self.CONF.set_override("rest_notifier_ssl_verify", False)
|
||||
|
||||
with mock.patch.object(requests.Session, 'post') as poster:
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({},
|
||||
'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
poster.assert_called_with(action, data=mock.ANY,
|
||||
headers=mock.ANY,
|
||||
verify=True)
|
||||
@@ -241,25 +250,27 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
self._fake_urlsplit):
|
||||
LOG = mock.MagicMock()
|
||||
with mock.patch('aodh.notifier.LOG', LOG):
|
||||
self.service.notify_alarm(
|
||||
{},
|
||||
self._msg_notifier.sample(
|
||||
{}, 'alarm.update',
|
||||
{
|
||||
'actions': ['no-such-action-i-am-sure'],
|
||||
'alarm_id': 'foobar',
|
||||
'condition': {'threshold': 42},
|
||||
})
|
||||
time.sleep(1)
|
||||
self.assertTrue(LOG.error.called)
|
||||
|
||||
def test_notify_alarm_invalid_action(self):
|
||||
LOG = mock.MagicMock()
|
||||
with mock.patch('aodh.notifier.LOG', LOG):
|
||||
self.service.notify_alarm(
|
||||
{},
|
||||
self._msg_notifier.sample(
|
||||
{}, 'alarm.update',
|
||||
{
|
||||
'actions': ['no-such-action-i-am-sure://'],
|
||||
'alarm_id': 'foobar',
|
||||
'condition': {'threshold': 42},
|
||||
})
|
||||
time.sleep(1)
|
||||
self.assertTrue(LOG.error.called)
|
||||
|
||||
def test_notify_alarm_trust_action(self):
|
||||
@@ -273,8 +284,9 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
lambda **kwargs: client))
|
||||
|
||||
with mock.patch.object(requests.Session, 'post') as poster:
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({}, 'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
poster.assert_called_with(
|
||||
url, data=mock.ANY, headers=mock.ANY)
|
||||
args, kwargs = poster.call_args
|
||||
@@ -292,8 +304,9 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
def test_zaqar_notifier_action(self):
|
||||
action = 'zaqar://?topic=critical&subscriber=http://example.com/data' \
|
||||
'&subscriber=mailto:foo@example.com&ttl=7200'
|
||||
self.service.notify_alarm({},
|
||||
self._msg_notifier.sample({}, 'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
self.assertEqual(self.zaqar,
|
||||
self.service.notifiers['zaqar'].obj.client)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user