Add common methods to use for sending notification
This patch adds the methods that masakari uses when sending notifications. Co-Authored-By: Shilpa Devharakar <Shilpa.Devharakar@nttdata.com> Change-Id: Iee57249b5bc2659e41589b5c6c98eb7eec0bc1b3 Partial-Implements: bp notifications-in-masakari
This commit is contained in:
parent
00d11056ba
commit
da942db7a6
|
@ -0,0 +1,110 @@
|
|||
# Copyright (c) 2018 NTT DATA
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT 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 socket
|
||||
|
||||
from masakari.notifications.objects import base as notification_base
|
||||
from masakari.notifications.objects import exception as notification_exception
|
||||
from masakari.notifications.objects import notification as event_notification
|
||||
from masakari.objects import fields
|
||||
|
||||
|
||||
def _get_fault_and_priority_from_exc_and_tb(exception, tb):
|
||||
fault = None
|
||||
priority = fields.EventNotificationPriority.INFO
|
||||
|
||||
if exception:
|
||||
priority = fields.EventNotificationPriority.ERROR
|
||||
fault = notification_exception.ExceptionPayload.from_exc_and_traceback(
|
||||
exception, tb)
|
||||
|
||||
return fault, priority
|
||||
|
||||
|
||||
def notify_about_segment_api(context, segment, action, phase=None,
|
||||
binary='masakari-api', exception=None, tb=None):
|
||||
"""Send versioned notification about a segment API.
|
||||
|
||||
:param segment: FailoverSegment object
|
||||
:param action: the name of the action
|
||||
:param phase: the phase of the action
|
||||
:param binary: the binary emitting the notification
|
||||
:param exception: the thrown exception (used in error notifications)
|
||||
:param tb: the traceback (used in error notifications)
|
||||
"""
|
||||
fault, priority = _get_fault_and_priority_from_exc_and_tb(exception, tb)
|
||||
payload = event_notification.SegmentApiPayload(
|
||||
segment=segment, fault=fault)
|
||||
api_notification = event_notification.SegmentApiNotification(
|
||||
context=context,
|
||||
priority=priority,
|
||||
publisher=notification_base.NotificationPublisher(
|
||||
context=context, host=socket.gethostname(), binary=binary),
|
||||
event_type=notification_base.EventType(
|
||||
action=action,
|
||||
phase=phase),
|
||||
payload=payload)
|
||||
api_notification.emit(context)
|
||||
|
||||
|
||||
def notify_about_host_api(context, host, action, phase=None,
|
||||
binary='masakari-api', exception=None, tb=None):
|
||||
"""Send versioned notification about a host API.
|
||||
|
||||
:param host: Host object
|
||||
:param action: the name of the action
|
||||
:param phase: the phase of the action
|
||||
:param binary: the binary emitting the notification
|
||||
:param exception: the thrown exception (used in error notifications)
|
||||
:param tb: the traceback (used in error notifications)
|
||||
"""
|
||||
fault, priority = _get_fault_and_priority_from_exc_and_tb(exception, tb)
|
||||
payload = event_notification.HostApiPayload(host=host, fault=fault)
|
||||
api_notification = event_notification.HostApiNotification(
|
||||
context=context,
|
||||
priority=priority,
|
||||
publisher=notification_base.NotificationPublisher(
|
||||
context=context, host=socket.gethostname(), binary=binary),
|
||||
event_type=notification_base.EventType(
|
||||
action=action,
|
||||
phase=phase),
|
||||
payload=payload)
|
||||
api_notification.emit(context)
|
||||
|
||||
|
||||
def notify_about_notification_api(context, notification, action, phase=None,
|
||||
binary='masakari-api', exception=None, tb=None):
|
||||
"""Send versioned notification about a notification api.
|
||||
|
||||
:param notification: Notification object
|
||||
:param action: the name of the action
|
||||
:param phase: the phase of the action
|
||||
:param binary: the binary emitting the notification
|
||||
:param exception: the thrown exception (used in error notifications)
|
||||
:param tb: the traceback (used in error notifications)
|
||||
"""
|
||||
fault, priority = _get_fault_and_priority_from_exc_and_tb(exception, tb)
|
||||
payload = event_notification.NotificationApiPayload(
|
||||
notification=notification, fault=fault)
|
||||
api_notification = event_notification.NotificationApiNotification(
|
||||
context=context,
|
||||
priority=priority,
|
||||
publisher=notification_base.NotificationPublisher(
|
||||
context=context, host=socket.gethostname(), binary=binary),
|
||||
event_type=notification_base.EventType(
|
||||
action=action,
|
||||
phase=phase),
|
||||
payload=payload)
|
||||
api_notification.emit(context)
|
|
@ -0,0 +1,59 @@
|
|||
# Copyright (c) 2018 NTT DATA
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT 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 socket
|
||||
|
||||
from masakari.notifications.objects import base as notification_base
|
||||
from masakari.notifications.objects import exception as notification_exception
|
||||
from masakari.notifications.objects import notification as event_notification
|
||||
from masakari.objects import fields
|
||||
|
||||
|
||||
def _get_fault_and_priority_from_exc_and_tb(exception, tb):
|
||||
fault = None
|
||||
priority = fields.EventNotificationPriority.INFO
|
||||
|
||||
if exception:
|
||||
priority = fields.EventNotificationPriority.ERROR
|
||||
fault = notification_exception.ExceptionPayload.from_exc_and_traceback(
|
||||
exception, tb)
|
||||
|
||||
return fault, priority
|
||||
|
||||
|
||||
def notify_about_notification_update(context, notification, action, phase=None,
|
||||
binary='masakari-engine', exception=None, tb=None):
|
||||
"""Send versioned notification about a notification update.
|
||||
|
||||
:param notification: Notification object
|
||||
:param action: the name of the action
|
||||
:param phase: the phase of the action
|
||||
:param binary: the binary emitting the notification
|
||||
:param exception: the thrown exception (used in error notifications)
|
||||
:param tb: the traceback (used in error notifications)
|
||||
"""
|
||||
fault, priority = _get_fault_and_priority_from_exc_and_tb(exception, tb)
|
||||
payload = event_notification.NotificationApiPayload(
|
||||
notification=notification, fault=fault)
|
||||
engine_notification = event_notification.NotificationApiNotification(
|
||||
context=context,
|
||||
priority=priority,
|
||||
publisher=notification_base.NotificationPublisher(
|
||||
context=context, host=socket.gethostname(), binary=binary),
|
||||
event_type=notification_base.EventType(
|
||||
action=action,
|
||||
phase=phase),
|
||||
payload=payload)
|
||||
engine_notification.emit(context)
|
|
@ -30,13 +30,14 @@ class ExceptionPayload(base.NotificationPayloadBase):
|
|||
'module_name': fields.StringField(),
|
||||
'function_name': fields.StringField(),
|
||||
'exception': fields.StringField(),
|
||||
'exception_message': fields.StringField()
|
||||
'exception_message': fields.StringField(),
|
||||
'traceback': fields.StringField()
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_exception(cls, fault):
|
||||
def from_exc_and_traceback(cls, fault, traceback):
|
||||
trace = inspect.trace()[-1]
|
||||
# apply strutils.mask_password on exception_message and
|
||||
# TODO(gibi): apply strutils.mask_password on exception_message and
|
||||
# consider emitting the exception_message only if the safe flag is
|
||||
# true in the exception like in the REST API
|
||||
module = inspect.getmodule(trace[0])
|
||||
|
@ -45,10 +46,11 @@ class ExceptionPayload(base.NotificationPayloadBase):
|
|||
function_name=trace[3],
|
||||
module_name=module_name,
|
||||
exception=fault.__class__.__name__,
|
||||
exception_message=six.text_type(fault))
|
||||
exception_message=six.text_type(fault),
|
||||
traceback=traceback)
|
||||
|
||||
|
||||
@base.notification_sample('engine-exception.json')
|
||||
@base.notification_sample('error-exception.json')
|
||||
@masakari_base.MasakariObjectRegistry.register_notification
|
||||
class ExceptionNotification(base.NotificationBase):
|
||||
# Version 1.0: Initial version
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
# Copyright (c) 2018 NTT DATA
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT 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 mock
|
||||
import socket
|
||||
import testtools
|
||||
|
||||
from masakari.api import utils as api_utils
|
||||
from masakari.notifications.objects import base as notification_base
|
||||
from masakari.notifications.objects import exception as notification_exception
|
||||
from masakari.notifications.objects import notification as event_notification
|
||||
from masakari import objects
|
||||
from masakari.objects import fields
|
||||
from masakari.objects import host as host_obj
|
||||
from masakari.objects import notification as notification_obj
|
||||
|
||||
|
||||
class TestApiUtils(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(TestApiUtils, self).setUp()
|
||||
|
||||
@mock.patch.object(notification_base, 'EventType')
|
||||
@mock.patch.object(notification_base, 'NotificationPublisher')
|
||||
@mock.patch.object(event_notification, 'SegmentApiNotification')
|
||||
@mock.patch.object(event_notification, 'SegmentApiPayload')
|
||||
@mock.patch.object(notification_exception.ExceptionPayload,
|
||||
'from_exc_and_traceback')
|
||||
def test_notify_about_segment_api(
|
||||
self, mock_from_exception, mock_SegmentApiPayload,
|
||||
mock_SegmentApiNotification, mock_NotificationPublisher,
|
||||
mock_EventType):
|
||||
mock_fault = mock.Mock()
|
||||
mock_from_exception.return_value = mock_fault
|
||||
mock_payload = mock.Mock()
|
||||
mock_SegmentApiPayload.return_value = mock_payload
|
||||
mock_api_notification = mock.Mock()
|
||||
mock_SegmentApiNotification.return_value = mock_api_notification
|
||||
mock_api_notification.emit.return_value = None
|
||||
mock_publisher = mock.Mock()
|
||||
mock_NotificationPublisher.return_value = mock_publisher
|
||||
mock_event_type = mock.Mock()
|
||||
mock_EventType.return_value = mock_event_type
|
||||
|
||||
mock_context = mock.Mock()
|
||||
segment = objects.FailoverSegment()
|
||||
action = fields.EventNotificationAction.SEGMENT_CREATE
|
||||
phase = fields.EventNotificationPhase.ERROR
|
||||
e = Exception()
|
||||
|
||||
api_utils.notify_about_segment_api(mock_context, segment,
|
||||
action=action, phase=phase, exception=e)
|
||||
|
||||
mock_from_exception.assert_called_once_with(e, None)
|
||||
mock_SegmentApiPayload.assert_called_once_with(
|
||||
segment=segment, fault=mock_fault)
|
||||
mock_SegmentApiNotification.assert_called_once_with(
|
||||
context=mock_context,
|
||||
priority=fields.EventNotificationPriority.ERROR,
|
||||
publisher=mock_publisher,
|
||||
event_type=mock_event_type,
|
||||
payload=mock_payload)
|
||||
mock_NotificationPublisher.assert_called_once_with(
|
||||
context=mock_context, host=socket.gethostname(),
|
||||
binary='masakari-api')
|
||||
mock_EventType.assert_called_once_with(
|
||||
action=action, phase=phase)
|
||||
mock_api_notification.emit.assert_called_once_with(mock_context)
|
||||
|
||||
@mock.patch.object(notification_base, 'EventType')
|
||||
@mock.patch.object(notification_base, 'NotificationPublisher')
|
||||
@mock.patch.object(event_notification, 'HostApiNotification')
|
||||
@mock.patch.object(event_notification, 'HostApiPayload')
|
||||
@mock.patch.object(notification_exception.ExceptionPayload,
|
||||
'from_exc_and_traceback')
|
||||
def test_notify_about_host_api(
|
||||
self, mock_from_exception, mock_HostApiPayload,
|
||||
mock_HostApiNotification, mock_NotificationPublisher, mock_EventType):
|
||||
mock_fault = mock.Mock()
|
||||
mock_from_exception.return_value = mock_fault
|
||||
mock_payload = mock.Mock()
|
||||
mock_HostApiPayload.return_value = mock_payload
|
||||
mock_api_notification = mock.Mock()
|
||||
mock_HostApiNotification.return_value = mock_api_notification
|
||||
mock_api_notification.emit.return_value = None
|
||||
mock_publisher = mock.Mock()
|
||||
mock_NotificationPublisher.return_value = mock_publisher
|
||||
mock_event_type = mock.Mock()
|
||||
mock_EventType.return_value = mock_event_type
|
||||
|
||||
mock_context = mock.Mock()
|
||||
host = host_obj.Host()
|
||||
action = fields.EventNotificationAction.HOST_CREATE
|
||||
phase = fields.EventNotificationPhase.ERROR
|
||||
e = Exception()
|
||||
|
||||
api_utils.notify_about_host_api(mock_context, host, action=action,
|
||||
phase=phase, exception=e)
|
||||
|
||||
mock_from_exception.assert_called_once_with(e, None)
|
||||
mock_HostApiPayload.assert_called_once_with(
|
||||
host=host, fault=mock_fault)
|
||||
mock_HostApiNotification.assert_called_once_with(
|
||||
context=mock_context,
|
||||
priority=fields.EventNotificationPriority.ERROR,
|
||||
publisher=mock_publisher,
|
||||
event_type=mock_event_type,
|
||||
payload=mock_payload)
|
||||
mock_NotificationPublisher.assert_called_once_with(
|
||||
context=mock_context, host=socket.gethostname(),
|
||||
binary='masakari-api')
|
||||
mock_api_notification.emit.assert_called_once_with(mock_context)
|
||||
mock_EventType.assert_called_once_with(
|
||||
action=action, phase=phase)
|
||||
|
||||
@mock.patch.object(notification_base, 'EventType')
|
||||
@mock.patch.object(notification_base, 'NotificationPublisher')
|
||||
@mock.patch.object(event_notification, 'NotificationApiNotification')
|
||||
@mock.patch.object(event_notification, 'NotificationApiPayload')
|
||||
@mock.patch.object(notification_exception.ExceptionPayload,
|
||||
'from_exc_and_traceback')
|
||||
def test_notify_about_notification_api(
|
||||
self, mock_from_exception, mock_NotificationApiPayload,
|
||||
mock_NotificationApiNotification, mock_NotificationPublisher,
|
||||
mock_EventType):
|
||||
mock_fault = mock.Mock()
|
||||
mock_from_exception.return_value = mock_fault
|
||||
mock_payload = mock.Mock()
|
||||
mock_NotificationApiPayload.return_value = mock_payload
|
||||
mock_api_notification = mock.Mock()
|
||||
mock_NotificationApiNotification.return_value = mock_api_notification
|
||||
mock_api_notification.emit.return_value = None
|
||||
mock_publisher = mock.Mock()
|
||||
mock_NotificationPublisher.return_value = mock_publisher
|
||||
mock_event_type = mock.Mock()
|
||||
mock_EventType.return_value = mock_event_type
|
||||
|
||||
mock_context = mock.Mock()
|
||||
notification = notification_obj.Notification()
|
||||
action = fields.EventNotificationAction.NOTIFICATION_CREATE
|
||||
phase = fields.EventNotificationPhase.ERROR
|
||||
e = Exception()
|
||||
|
||||
api_utils.notify_about_notification_api(mock_context, notification,
|
||||
action=action, phase=phase, exception=e)
|
||||
|
||||
mock_from_exception.assert_called_once_with(e, None)
|
||||
mock_NotificationApiPayload.assert_called_once_with(
|
||||
notification=notification, fault=mock_fault)
|
||||
mock_NotificationApiNotification.assert_called_once_with(
|
||||
context=mock_context,
|
||||
priority=fields.EventNotificationPriority.ERROR,
|
||||
publisher=mock_publisher,
|
||||
event_type=mock_event_type,
|
||||
payload=mock_payload)
|
||||
mock_NotificationPublisher.assert_called_once_with(
|
||||
context=mock_context, host=socket.gethostname(),
|
||||
binary='masakari-api')
|
||||
mock_api_notification.emit.assert_called_once_with(mock_context)
|
|
@ -0,0 +1,76 @@
|
|||
# Copyright (c) 2018 NTT DATA
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT 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 mock
|
||||
import socket
|
||||
import testtools
|
||||
|
||||
from masakari.engine import utils as engine_utils
|
||||
from masakari.notifications.objects import base as notification_base
|
||||
from masakari.notifications.objects import exception as notification_exception
|
||||
from masakari.notifications.objects import notification as event_notification
|
||||
from masakari.objects import fields
|
||||
from masakari.objects import notification as notification_obj
|
||||
|
||||
|
||||
class TestApiUtils(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(TestApiUtils, self).setUp()
|
||||
|
||||
@mock.patch.object(notification_base, 'EventType')
|
||||
@mock.patch.object(notification_base, 'NotificationPublisher')
|
||||
@mock.patch.object(event_notification, 'NotificationApiNotification')
|
||||
@mock.patch.object(event_notification, 'NotificationApiPayload')
|
||||
@mock.patch.object(notification_exception.ExceptionPayload,
|
||||
'from_exc_and_traceback')
|
||||
def test_notify_about_notification_update(
|
||||
self, mock_from_exception, mock_NotificationApiPayload,
|
||||
mock_NotificationApiNotification, mock_NotificationPublisher,
|
||||
mock_EventType):
|
||||
mock_fault = mock.Mock()
|
||||
mock_from_exception.return_value = mock_fault
|
||||
mock_payload = mock.Mock()
|
||||
mock_NotificationApiPayload.return_value = mock_payload
|
||||
mock_engine_notification = mock.Mock()
|
||||
mock_NotificationApiNotification.return_value = (
|
||||
mock_engine_notification)
|
||||
mock_engine_notification.emit.return_value = None
|
||||
mock_publisher = mock.Mock()
|
||||
mock_NotificationPublisher.return_value = mock_publisher
|
||||
mock_event_type = mock.Mock()
|
||||
mock_EventType.return_value = mock_event_type
|
||||
|
||||
mock_context = mock.Mock()
|
||||
notification = notification_obj.Notification()
|
||||
action = fields.EventNotificationAction.NOTIFICATION_PROCESS
|
||||
phase = fields.EventNotificationPhase.ERROR
|
||||
e = Exception()
|
||||
|
||||
engine_utils.notify_about_notification_update(mock_context,
|
||||
notification, action=action, phase=phase, exception=e)
|
||||
|
||||
mock_from_exception.assert_called_once_with(e, None)
|
||||
mock_NotificationApiPayload.assert_called_once_with(
|
||||
notification=notification, fault=mock_fault)
|
||||
mock_NotificationApiNotification.assert_called_once_with(
|
||||
context=mock_context,
|
||||
priority=fields.EventNotificationPriority.ERROR,
|
||||
publisher=mock_publisher,
|
||||
event_type=mock_event_type,
|
||||
payload=mock_payload)
|
||||
mock_NotificationPublisher.assert_called_once_with(
|
||||
context=mock_context, host=socket.gethostname(),
|
||||
binary='masakari-engine')
|
||||
mock_engine_notification.emit.assert_called_once_with(mock_context)
|
|
@ -661,7 +661,7 @@ object_data = {
|
|||
'NotificationList': '1.0-25ebe1b17fbd9f114fae8b6a10d198c0',
|
||||
'EventType': '1.0-d1d2010a7391fa109f0868d964152607',
|
||||
'ExceptionNotification': '1.0-1187e93f564c5cca692db76a66cda2a6',
|
||||
'ExceptionPayload': '1.0-4516ae282a55fe2fd5c754967ee6248b',
|
||||
'ExceptionPayload': '1.0-96f178a12691e3ef0d8e3188fc481b90',
|
||||
'HostApiNotification': '1.0-1187e93f564c5cca692db76a66cda2a6',
|
||||
'HostApiPayload': '1.0-ca9035d81cec6697f12dd4cac4c8f027',
|
||||
'HostApiPayloadBase': '1.0-211379087a876212df6194b011207339',
|
||||
|
|
Loading…
Reference in New Issue