Switch to common notifiers.
- Added notifier files to openstack-common.conf, merged from common. - Import notifiers from common rather than nova. - Removed nova-specific notifier code. - Update some driver paths to refer to the new location within nova. Should be a no-op, as the common notification code is freshly copied from Nova. Change-Id: Icdf892bc3826b683fc74f22ead00939beda2859f
This commit is contained in:
parent
642ec634c3
commit
aa87cc10d6
@ -62,12 +62,12 @@ from nova import manager
|
||||
from nova import network
|
||||
from nova.network import model as network_model
|
||||
from nova import notifications
|
||||
from nova.notifier import api as notifier
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import jsonutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import api as notifier
|
||||
from nova.openstack.common import rpc
|
||||
from nova.openstack.common import timeutils
|
||||
from nova import utils
|
||||
|
@ -21,9 +21,8 @@ from nova import exception
|
||||
from nova import flags
|
||||
from nova.network import model as network_model
|
||||
from nova import notifications
|
||||
from nova.notifier import api as notifier_api
|
||||
from nova.openstack.common import log
|
||||
from nova import utils
|
||||
from nova.openstack.common.notifier import api as notifier_api
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
@ -316,9 +316,6 @@ global_opts = [
|
||||
cfg.StrOpt('node_availability_zone',
|
||||
default='nova',
|
||||
help='availability zone of this node'),
|
||||
cfg.StrOpt('notification_driver',
|
||||
default='nova.notifier.no_op_notifier',
|
||||
help='Default driver for sending notifications'),
|
||||
cfg.ListOpt('memcached_servers',
|
||||
default=None,
|
||||
help='Memcached servers or None for in process cache.'),
|
||||
|
@ -61,12 +61,12 @@ from nova import ipv6
|
||||
from nova import manager
|
||||
from nova.network import api as network_api
|
||||
from nova.network import model as network_model
|
||||
from nova.notifier import api as notifier
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import jsonutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import api as notifier
|
||||
from nova.openstack.common import rpc
|
||||
from nova.openstack.common import timeutils
|
||||
import nova.policy
|
||||
|
@ -25,9 +25,9 @@ from nova import exception
|
||||
from nova import flags
|
||||
from nova import network
|
||||
from nova.network import model as network_model
|
||||
from nova.notifier import api as notifier_api
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import log
|
||||
from nova.openstack.common.notifier import api as notifier_api
|
||||
from nova.openstack.common import timeutils
|
||||
from nova import utils
|
||||
|
||||
|
@ -1,81 +0,0 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def notify(_context, message):
|
||||
"""Look for specific compute manager events and interprete them
|
||||
so as to keep the Capacity table up to date.
|
||||
|
||||
NOTE: the True/False return codes are only for testing.
|
||||
"""
|
||||
|
||||
# The event_type must start with 'compute.instance.'
|
||||
event_type = message.get('event_type', None)
|
||||
preamble = 'compute.instance.'
|
||||
if not event_type or not event_type.startswith(preamble):
|
||||
return False
|
||||
|
||||
# Events we're interested in end with .start and .end
|
||||
event = event_type[len(preamble):]
|
||||
parts = event.split('.')
|
||||
suffix = parts[-1].lower()
|
||||
event = event[:(-len(suffix) - 1)]
|
||||
|
||||
if suffix not in ['start', 'end']:
|
||||
return False
|
||||
started = suffix == 'start'
|
||||
ended = suffix == 'end'
|
||||
|
||||
if started and event == 'create':
|
||||
# We've already updated this stuff in the scheduler. Don't redo the
|
||||
# work here.
|
||||
return False
|
||||
|
||||
work = 1 if started else -1
|
||||
|
||||
# Extract the host name from the publisher id ...
|
||||
publisher_preamble = 'compute.'
|
||||
publisher = message.get('publisher_id', None)
|
||||
if not publisher or not publisher.startswith(publisher_preamble):
|
||||
return False
|
||||
host = publisher[len(publisher_preamble):]
|
||||
|
||||
# If we deleted an instance, make sure we reclaim the resources.
|
||||
# We may need to do something explicit for rebuild/migrate.
|
||||
free_ram_mb = 0
|
||||
free_disk_gb = 0
|
||||
vms = 0
|
||||
if ended and event == 'delete':
|
||||
vms = -1
|
||||
payload = message.get('payload', {})
|
||||
free_ram_mb = payload.get('memory_mb', 0)
|
||||
free_disk_gb = payload.get('disk_gb', 0)
|
||||
|
||||
LOG.debug("EventType=%(event_type)s -> host %(host)s: "
|
||||
"ram %(free_ram_mb)d, disk %(free_disk_gb)d, "
|
||||
"work %(work)d, vms%(vms)d" % locals())
|
||||
|
||||
db.api.compute_node_utilization_update(context.get_admin_context(), host,
|
||||
free_ram_mb_delta=free_ram_mb, free_disk_gb_delta=free_disk_gb,
|
||||
work_delta=work, vm_delta=vms)
|
||||
|
||||
return True
|
81
nova/openstack/common/context.py
Normal file
81
nova/openstack/common/context.py
Normal file
@ -0,0 +1,81 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Simple class that stores security context information in the web request.
|
||||
|
||||
Projects should subclass this class if they wish to enhance the request
|
||||
context or provide additional information in their specific WSGI pipeline.
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import uuid
|
||||
|
||||
|
||||
def generate_request_id():
|
||||
return 'req-' + str(uuid.uuid4())
|
||||
|
||||
|
||||
class RequestContext(object):
|
||||
|
||||
"""
|
||||
Stores information about the security context under which the user
|
||||
accesses the system, as well as additional request information.
|
||||
"""
|
||||
|
||||
def __init__(self, auth_tok=None, user=None, tenant=None, is_admin=False,
|
||||
read_only=False, show_deleted=False, request_id=None):
|
||||
self.auth_tok = auth_tok
|
||||
self.user = user
|
||||
self.tenant = tenant
|
||||
self.is_admin = is_admin
|
||||
self.read_only = read_only
|
||||
self.show_deleted = show_deleted
|
||||
if not request_id:
|
||||
request_id = generate_request_id()
|
||||
self.request_id = request_id
|
||||
|
||||
def to_dict(self):
|
||||
return {'user': self.user,
|
||||
'tenant': self.tenant,
|
||||
'is_admin': self.is_admin,
|
||||
'read_only': self.read_only,
|
||||
'show_deleted': self.show_deleted,
|
||||
'auth_token': self.auth_tok,
|
||||
'request_id': self.request_id}
|
||||
|
||||
|
||||
def get_admin_context(show_deleted="no"):
|
||||
context = RequestContext(None,
|
||||
tenant=None,
|
||||
is_admin=True,
|
||||
show_deleted=show_deleted)
|
||||
return context
|
||||
|
||||
|
||||
def get_context_from_function_and_args(function, args, kwargs):
|
||||
"""Find an arg of type RequestContext and return it.
|
||||
|
||||
This is useful in a couple of decorators where we don't
|
||||
know much about the function we're wrapping.
|
||||
"""
|
||||
|
||||
for arg in itertools.chain(kwargs.values(), args):
|
||||
if isinstance(arg, RequestContext):
|
||||
return arg
|
||||
|
||||
return None
|
@ -40,10 +40,10 @@ import stat
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from nova import notifier
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import jsonutils
|
||||
from nova.openstack.common import local
|
||||
from nova.openstack.common import notifier
|
||||
|
||||
|
||||
log_opts = [
|
||||
|
@ -13,11 +13,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import inspect
|
||||
import uuid
|
||||
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import context
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import jsonutils
|
||||
from nova.openstack.common import log as logging
|
||||
@ -27,6 +27,9 @@ from nova.openstack.common import timeutils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
notifier_opts = [
|
||||
cfg.StrOpt('notification_driver',
|
||||
default='nova.openstack.common.notifier.no_op_notifier',
|
||||
help='Default driver for sending notifications'),
|
||||
cfg.StrOpt('default_notification_level',
|
||||
default='INFO',
|
||||
help='Default notification level for outgoing notifications'),
|
||||
@ -35,8 +38,8 @@ notifier_opts = [
|
||||
help='Default publisher_id for outgoing notifications'),
|
||||
]
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
FLAGS.register_opts(notifier_opts)
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(notifier_opts)
|
||||
|
||||
WARN = 'WARN'
|
||||
INFO = 'INFO'
|
||||
@ -68,11 +71,11 @@ def notify_decorator(name, fn):
|
||||
for key in kwarg:
|
||||
body['kwarg'][key] = kwarg[key]
|
||||
|
||||
context = exception.get_context_from_function_and_args(fn, args, kwarg)
|
||||
notify(context,
|
||||
FLAGS.default_publisher_id,
|
||||
ctxt = context.get_context_from_function_and_args(fn, args, kwarg)
|
||||
notify(ctxt,
|
||||
CONF.default_publisher_id,
|
||||
name,
|
||||
FLAGS.default_notification_level,
|
||||
CONF.default_notification_level,
|
||||
body)
|
||||
return fn(*args, **kwarg)
|
||||
return wrapped_func
|
||||
@ -80,7 +83,7 @@ def notify_decorator(name, fn):
|
||||
|
||||
def publisher_id(service, host=None):
|
||||
if not host:
|
||||
host = FLAGS.host
|
||||
host = CONF.host
|
||||
return "%s.%s" % (service, host)
|
||||
|
||||
|
||||
@ -123,7 +126,7 @@ def notify(context, publisher_id, event_type, priority, payload):
|
||||
# Ensure everything is JSON serializable.
|
||||
payload = jsonutils.to_primitive(payload, convert_instances=True)
|
||||
|
||||
driver = importutils.import_module(FLAGS.notification_driver)
|
||||
driver = importutils.import_module(CONF.notification_driver)
|
||||
msg = dict(message_id=str(uuid.uuid4()),
|
||||
publisher_id=publisher_id,
|
||||
event_type=event_type,
|
@ -13,18 +13,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova import flags
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
|
||||
list_notifier_drivers_opt = cfg.MultiStrOpt('list_notifier_drivers',
|
||||
default=['nova.notifier.no_op_notifier'],
|
||||
default=['nova.openstack.common.notifier.no_op_notifier'],
|
||||
help='List of drivers to send notifications')
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
FLAGS.register_opt(list_notifier_drivers_opt)
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opt(list_notifier_drivers_opt)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -44,9 +43,9 @@ class ImportFailureNotifier(object):
|
||||
def _get_drivers():
|
||||
"""Instantiates and returns drivers based on the flag values."""
|
||||
global drivers
|
||||
if not drivers:
|
||||
if drivers is None:
|
||||
drivers = []
|
||||
for notification_driver in FLAGS.list_notifier_drivers:
|
||||
for notification_driver in CONF.list_notifier_drivers:
|
||||
try:
|
||||
drivers.append(importutils.import_module(notification_driver))
|
||||
except ImportError as e:
|
||||
@ -54,6 +53,53 @@ def _get_drivers():
|
||||
return drivers
|
||||
|
||||
|
||||
def add_driver(notification_driver):
|
||||
"""Add a notification driver at runtime."""
|
||||
# Make sure the driver list is initialized.
|
||||
_get_drivers()
|
||||
if isinstance(notification_driver, basestring):
|
||||
# Load and add
|
||||
try:
|
||||
drivers.append(importutils.import_module(notification_driver))
|
||||
except ImportError as e:
|
||||
drivers.append(ImportFailureNotifier(e))
|
||||
else:
|
||||
# Driver is already loaded; just add the object.
|
||||
drivers.append(notification_driver)
|
||||
|
||||
|
||||
def _object_name(obj):
|
||||
name = []
|
||||
if hasattr(obj, '__module__'):
|
||||
name.append(obj.__module__)
|
||||
if hasattr(obj, '__name__'):
|
||||
name.append(obj.__name__)
|
||||
else:
|
||||
name.append(obj.__class__.__name__)
|
||||
return '.'.join(name)
|
||||
|
||||
|
||||
def remove_driver(notification_driver):
|
||||
"""Remove a notification driver at runtime."""
|
||||
# Make sure the driver list is initialized.
|
||||
_get_drivers()
|
||||
removed = False
|
||||
if notification_driver in drivers:
|
||||
# We're removing an object. Easy.
|
||||
drivers.remove(notification_driver)
|
||||
removed = True
|
||||
else:
|
||||
# We're removing a driver by name. Search for it.
|
||||
for driver in drivers:
|
||||
if _object_name(driver) == notification_driver:
|
||||
drivers.remove(driver)
|
||||
removed = True
|
||||
|
||||
if not removed:
|
||||
raise ValueError("Cannot remove; %s is not in list" %
|
||||
notification_driver)
|
||||
|
||||
|
||||
def notify(context, message):
|
||||
"""Passes notification to multiple notifiers in a list."""
|
||||
for driver in _get_drivers():
|
@ -13,21 +13,22 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova import flags
|
||||
from nova.openstack.common import jsonutils
|
||||
import json
|
||||
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def notify(_context, message):
|
||||
"""Notifies the recipient of the desired event given the model.
|
||||
Log notifications using nova's default logging system"""
|
||||
Log notifications using openstack's default logging system"""
|
||||
|
||||
priority = message.get('priority',
|
||||
FLAGS.default_notification_level)
|
||||
CONF.default_notification_level)
|
||||
priority = priority.lower()
|
||||
logger = logging.getLogger(
|
||||
'nova.notification.%s' % message['event_type'])
|
||||
getattr(logger, priority)(jsonutils.dumps(message))
|
||||
'nova.openstack.common.notification.%s' % message['event_type'])
|
||||
getattr(logger, priority)(json.dumps(message))
|
@ -14,10 +14,8 @@
|
||||
# under the License.
|
||||
|
||||
|
||||
import nova.context
|
||||
|
||||
from nova import flags
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import context as req_context
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import rpc
|
||||
|
||||
@ -25,20 +23,20 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
notification_topic_opt = cfg.ListOpt('notification_topics',
|
||||
default=['notifications', ],
|
||||
help='AMQP topic used for Nova notifications')
|
||||
help='AMQP topic used for openstack notifications')
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
FLAGS.register_opt(notification_topic_opt)
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opt(notification_topic_opt)
|
||||
|
||||
|
||||
def notify(context, message):
|
||||
"""Sends a notification to the RabbitMQ"""
|
||||
if not context:
|
||||
context = nova.context.get_admin_context()
|
||||
context = req_context.get_admin_context()
|
||||
priority = message.get('priority',
|
||||
FLAGS.default_notification_level)
|
||||
CONF.default_notification_level)
|
||||
priority = priority.lower()
|
||||
for topic in FLAGS.notification_topics:
|
||||
for topic in CONF.notification_topics:
|
||||
topic = '%s.%s' % (topic, priority)
|
||||
try:
|
||||
rpc.notify(context, topic, message)
|
@ -13,9 +13,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova import flags
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
NOTIFICATIONS = []
|
||||
|
@ -23,9 +23,9 @@ import operator
|
||||
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova.notifier import api as notifier
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import api as notifier
|
||||
from nova.scheduler import driver
|
||||
from nova.scheduler import least_cost
|
||||
from nova.scheduler import scheduler_options
|
||||
|
@ -29,11 +29,11 @@ from nova import exception
|
||||
from nova import flags
|
||||
from nova import manager
|
||||
from nova import notifications
|
||||
from nova.notifier import api as notifier
|
||||
from nova.openstack.common import cfg
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import api as notifier
|
||||
from nova import quota
|
||||
|
||||
|
||||
|
@ -39,9 +39,9 @@ from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova.notifier import test_notifier
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import test_notifier
|
||||
from nova.openstack.common import policy as common_policy
|
||||
from nova.openstack.common import rpc
|
||||
from nova.openstack.common.rpc import common as rpc_common
|
||||
@ -109,7 +109,7 @@ class BaseTestCase(test.TestCase):
|
||||
super(BaseTestCase, self).setUp()
|
||||
self.flags(compute_driver='nova.virt.fake.FakeDriver',
|
||||
stub_network=True,
|
||||
notification_driver='nova.notifier.test_notifier',
|
||||
notification_driver='nova.openstack.common.notifier.test_notifier',
|
||||
network_manager='nova.network.manager.FlatManager')
|
||||
self.compute = importutils.import_object(FLAGS.compute_manager)
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from nova.tests import *
|
@ -1,59 +0,0 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 nova.db.api
|
||||
from nova.notifier import capacity_notifier as cn
|
||||
from nova.openstack.common import jsonutils
|
||||
from nova import test
|
||||
|
||||
|
||||
class CapacityNotifierTestCase(test.TestCase):
|
||||
"""Test case for the Capacity updating notifier."""
|
||||
|
||||
def _make_msg(self, host, event):
|
||||
usage_info = dict(memory_mb=123, disk_gb=456)
|
||||
payload = jsonutils.to_primitive(usage_info, convert_instances=True)
|
||||
return dict(
|
||||
publisher_id="compute.%s" % host,
|
||||
event_type="compute.instance.%s" % event,
|
||||
payload=payload
|
||||
)
|
||||
|
||||
def test_event_type(self):
|
||||
msg = self._make_msg("myhost", "mymethod")
|
||||
msg['event_type'] = 'random'
|
||||
self.assertFalse(cn.notify(None, msg))
|
||||
|
||||
def test_bad_event_suffix(self):
|
||||
msg = self._make_msg("myhost", "mymethod.badsuffix")
|
||||
self.assertFalse(cn.notify(None, msg))
|
||||
|
||||
def test_bad_publisher_id(self):
|
||||
msg = self._make_msg("myhost", "mymethod.start")
|
||||
msg['publisher_id'] = 'badpublisher'
|
||||
self.assertFalse(cn.notify(None, msg))
|
||||
|
||||
def test_update_called(self):
|
||||
def _verify_called(host, context, free_ram_mb_delta,
|
||||
free_disk_gb_delta, work_delta, vm_delta):
|
||||
self.assertEquals(free_ram_mb_delta, 123)
|
||||
self.assertEquals(free_disk_gb_delta, 456)
|
||||
self.assertEquals(vm_delta, -1)
|
||||
self.assertEquals(work_delta, -1)
|
||||
|
||||
self.stubs.Set(nova.db.api, "compute_node_utilization_update",
|
||||
_verify_called)
|
||||
msg = self._make_msg("myhost", "delete.end")
|
||||
self.assertTrue(cn.notify(None, msg))
|
@ -1,84 +0,0 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 nova
|
||||
import nova.notifier.api
|
||||
from nova.notifier import list_notifier
|
||||
import nova.notifier.log_notifier
|
||||
import nova.notifier.no_op_notifier
|
||||
from nova.openstack.common import log as logging
|
||||
from nova import test
|
||||
|
||||
|
||||
class NotifierListTestCase(test.TestCase):
|
||||
"""Test case for notifications"""
|
||||
|
||||
def setUp(self):
|
||||
super(NotifierListTestCase, self).setUp()
|
||||
list_notifier._reset_drivers()
|
||||
# Mock log to add one to exception_count when log.exception is called
|
||||
|
||||
def mock_exception(cls, *args):
|
||||
self.exception_count += 1
|
||||
|
||||
self.exception_count = 0
|
||||
list_notifier_log = logging.getLogger('nova.notifier.list_notifier')
|
||||
self.stubs.Set(list_notifier_log, "exception", mock_exception)
|
||||
# Mock no_op notifier to add one to notify_count when called.
|
||||
|
||||
def mock_notify(cls, *args):
|
||||
self.notify_count += 1
|
||||
|
||||
self.notify_count = 0
|
||||
self.stubs.Set(nova.notifier.no_op_notifier, 'notify', mock_notify)
|
||||
# Mock log_notifier to raise RuntimeError when called.
|
||||
|
||||
def mock_notify2(cls, *args):
|
||||
raise RuntimeError("Bad notifier.")
|
||||
|
||||
self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2)
|
||||
|
||||
def tearDown(self):
|
||||
list_notifier._reset_drivers()
|
||||
super(NotifierListTestCase, self).tearDown()
|
||||
|
||||
def test_send_notifications_successfully(self):
|
||||
self.flags(notification_driver='nova.notifier.list_notifier',
|
||||
list_notifier_drivers=['nova.notifier.no_op_notifier',
|
||||
'nova.notifier.no_op_notifier'])
|
||||
nova.notifier.api.notify('contextarg', 'publisher_id', 'event_type',
|
||||
nova.notifier.api.WARN, dict(a=3))
|
||||
self.assertEqual(self.notify_count, 2)
|
||||
self.assertEqual(self.exception_count, 0)
|
||||
|
||||
def test_send_notifications_with_errors(self):
|
||||
|
||||
self.flags(notification_driver='nova.notifier.list_notifier',
|
||||
list_notifier_drivers=['nova.notifier.no_op_notifier',
|
||||
'nova.notifier.log_notifier'])
|
||||
nova.notifier.api.notify('contextarg', 'publisher_id',
|
||||
'event_type', nova.notifier.api.WARN, dict(a=3))
|
||||
self.assertEqual(self.notify_count, 1)
|
||||
self.assertEqual(self.exception_count, 1)
|
||||
|
||||
def test_when_driver_fails_to_import(self):
|
||||
self.flags(notification_driver='nova.notifier.list_notifier',
|
||||
list_notifier_drivers=['nova.notifier.no_op_notifier',
|
||||
'nova.notifier.logo_notifier',
|
||||
'fdsjgsdfhjkhgsfkj'])
|
||||
nova.notifier.api.notify('contextarg', 'publisher_id',
|
||||
'event_type', nova.notifier.api.WARN, dict(a=3))
|
||||
self.assertEqual(self.exception_count, 2)
|
||||
self.assertEqual(self.notify_count, 1)
|
@ -22,9 +22,9 @@ from nova.compute import utils as compute_utils
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova import flags
|
||||
from nova.notifier import test_notifier
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import test_notifier
|
||||
from nova import test
|
||||
from nova.tests import fake_network
|
||||
import nova.tests.image.fake
|
||||
@ -50,7 +50,7 @@ class UsageInfoTestCase(test.TestCase):
|
||||
|
||||
self.flags(compute_driver='nova.virt.fake.FakeDriver',
|
||||
stub_network=True,
|
||||
notification_driver='nova.notifier.test_notifier',
|
||||
notification_driver='nova.openstack.common.notifier.test_notifier',
|
||||
network_manager='nova.network.manager.FlatManager')
|
||||
self.compute = importutils.import_object(FLAGS.compute_manager)
|
||||
self.user_id = 'fake'
|
||||
|
@ -27,8 +27,8 @@ from nova import db
|
||||
from nova import flags
|
||||
import nova.network
|
||||
from nova import notifications
|
||||
from nova.notifier import test_notifier
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import test_notifier
|
||||
from nova import test
|
||||
from nova.tests import fake_network
|
||||
|
||||
@ -52,7 +52,7 @@ class NotificationsTestCase(test.TestCase):
|
||||
|
||||
self.flags(compute_driver='nova.virt.fake.FakeDriver',
|
||||
stub_network=True,
|
||||
notification_driver='nova.notifier.test_notifier',
|
||||
notification_driver='nova.openstack.common.notifier.test_notifier',
|
||||
network_manager='nova.network.manager.FlatManager',
|
||||
notify_on_state_change="vm_and_task_state",
|
||||
host='testhost')
|
||||
|
@ -1,184 +0,0 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 nova
|
||||
from nova import context
|
||||
from nova import flags
|
||||
from nova.notifier import api as notifier_api
|
||||
import nova.notifier.no_op_notifier
|
||||
from nova.openstack.common import log
|
||||
from nova import test
|
||||
|
||||
|
||||
ctxt = context.get_admin_context()
|
||||
ctxt2 = context.get_admin_context()
|
||||
|
||||
|
||||
class NotifierTestCase(test.TestCase):
|
||||
"""Test case for notifications"""
|
||||
def setUp(self):
|
||||
super(NotifierTestCase, self).setUp()
|
||||
self.flags(notification_driver='nova.notifier.no_op_notifier')
|
||||
|
||||
def test_send_notification(self):
|
||||
self.notify_called = False
|
||||
|
||||
def mock_notify(cls, *args):
|
||||
self.notify_called = True
|
||||
|
||||
self.stubs.Set(nova.notifier.no_op_notifier, 'notify',
|
||||
mock_notify)
|
||||
|
||||
notifier_api.notify(ctxt, 'publisher_id', 'event_type',
|
||||
nova.notifier.api.WARN, dict(a=3))
|
||||
self.assertEqual(self.notify_called, True)
|
||||
|
||||
def test_verify_message_format(self):
|
||||
"""A test to ensure changing the message format is prohibitively
|
||||
annoying"""
|
||||
|
||||
def message_assert(context, message):
|
||||
fields = [('publisher_id', 'publisher_id'),
|
||||
('event_type', 'event_type'),
|
||||
('priority', 'WARN'),
|
||||
('payload', dict(a=3))]
|
||||
for k, v in fields:
|
||||
self.assertEqual(message[k], v)
|
||||
self.assertTrue(len(message['message_id']) > 0)
|
||||
self.assertTrue(len(message['timestamp']) > 0)
|
||||
self.assertEqual(context, ctxt)
|
||||
|
||||
self.stubs.Set(nova.notifier.no_op_notifier, 'notify',
|
||||
message_assert)
|
||||
notifier_api.notify(ctxt, 'publisher_id', 'event_type',
|
||||
nova.notifier.api.WARN, dict(a=3))
|
||||
|
||||
def test_send_rabbit_notification(self):
|
||||
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
|
||||
'nova.notifier.rabbit_notifier')
|
||||
self.mock_notify = False
|
||||
|
||||
def mock_notify(cls, *args):
|
||||
self.mock_notify = True
|
||||
|
||||
self.stubs.Set(nova.openstack.common.rpc, 'notify', mock_notify)
|
||||
notifier_api.notify(ctxt, 'publisher_id', 'event_type',
|
||||
nova.notifier.api.WARN, dict(a=3))
|
||||
|
||||
self.assertEqual(self.mock_notify, True)
|
||||
|
||||
def test_invalid_priority(self):
|
||||
self.assertRaises(nova.notifier.api.BadPriorityException,
|
||||
notifier_api.notify, ctxt, 'publisher_id',
|
||||
'event_type', 'not a priority', dict(a=3))
|
||||
|
||||
def test_rabbit_priority_queue(self):
|
||||
flags.DECLARE('notification_topics', 'nova.notifier.rabbit_notifier')
|
||||
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
|
||||
'nova.notifier.rabbit_notifier')
|
||||
self.stubs.Set(nova.flags.FLAGS, 'notification_topics',
|
||||
['testnotify', ])
|
||||
|
||||
self.test_topic = None
|
||||
|
||||
def mock_notify(context, topic, msg):
|
||||
self.test_topic = topic
|
||||
|
||||
self.stubs.Set(nova.openstack.common.rpc, 'notify', mock_notify)
|
||||
notifier_api.notify(ctxt, 'publisher_id',
|
||||
'event_type', 'DEBUG', dict(a=3))
|
||||
self.assertEqual(self.test_topic, 'testnotify.debug')
|
||||
|
||||
def test_error_notification(self):
|
||||
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
|
||||
'nova.notifier.rabbit_notifier')
|
||||
self.stubs.Set(nova.flags.FLAGS, 'publish_errors', True)
|
||||
LOG = log.getLogger('nova')
|
||||
log.setup('nova')
|
||||
msgs = []
|
||||
|
||||
def mock_notify(context, topic, data):
|
||||
msgs.append(data)
|
||||
|
||||
self.stubs.Set(nova.openstack.common.rpc, 'notify', mock_notify)
|
||||
LOG.error('foo')
|
||||
self.assertEqual(1, len(msgs))
|
||||
msg = msgs[0]
|
||||
self.assertEqual(msg['event_type'], 'error_notification')
|
||||
self.assertEqual(msg['priority'], 'ERROR')
|
||||
self.assertEqual(msg['payload']['error'], 'foo')
|
||||
|
||||
def test_send_notification_by_decorator(self):
|
||||
self.notify_called = False
|
||||
|
||||
def example_api(arg1, arg2):
|
||||
return arg1 + arg2
|
||||
|
||||
example_api = nova.notifier.api.notify_decorator(
|
||||
'example_api',
|
||||
example_api)
|
||||
|
||||
def mock_notify(cls, *args):
|
||||
self.notify_called = True
|
||||
|
||||
self.stubs.Set(nova.notifier.no_op_notifier, 'notify',
|
||||
mock_notify)
|
||||
|
||||
self.assertEqual(3, example_api(1, 2))
|
||||
self.assertEqual(self.notify_called, True)
|
||||
|
||||
def test_decorator_context(self):
|
||||
"""Verify that the notify decorator can extract the 'context' arg."""
|
||||
self.notify_called = False
|
||||
self.context_arg = None
|
||||
|
||||
def example_api(arg1, arg2, context):
|
||||
return arg1 + arg2
|
||||
|
||||
def example_api2(arg1, arg2, **kw):
|
||||
return arg1 + arg2
|
||||
|
||||
example_api = nova.notifier.api.notify_decorator(
|
||||
'example_api',
|
||||
example_api)
|
||||
|
||||
example_api2 = nova.notifier.api.notify_decorator(
|
||||
'example_api2',
|
||||
example_api2)
|
||||
|
||||
def mock_notify(context, cls, _type, _priority, _payload):
|
||||
self.notify_called = True
|
||||
self.context_arg = context
|
||||
|
||||
self.stubs.Set(nova.notifier.api, 'notify',
|
||||
mock_notify)
|
||||
|
||||
# Test positional context
|
||||
self.assertEqual(3, example_api(1, 2, ctxt))
|
||||
self.assertEqual(self.notify_called, True)
|
||||
self.assertEqual(self.context_arg, ctxt)
|
||||
|
||||
self.notify_called = False
|
||||
self.context_arg = None
|
||||
|
||||
# Test named context
|
||||
self.assertEqual(3, example_api2(1, 2, context=ctxt2))
|
||||
self.assertEqual(self.notify_called, True)
|
||||
self.assertEqual(self.context_arg, ctxt2)
|
||||
|
||||
# Test missing context
|
||||
self.assertEqual(3, example_api2(1, 2, bananas="delicious"))
|
||||
self.assertEqual(self.notify_called, True)
|
||||
self.assertEqual(self.context_arg, None)
|
@ -28,9 +28,9 @@ from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova.notifier import test_notifier
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import test_notifier
|
||||
from nova.openstack.common import rpc
|
||||
import nova.policy
|
||||
from nova import quota
|
||||
@ -50,7 +50,7 @@ class VolumeTestCase(test.TestCase):
|
||||
self.compute = importutils.import_object(FLAGS.compute_manager)
|
||||
self.flags(compute_driver='nova.virt.fake.FakeDriver')
|
||||
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
|
||||
'nova.notifier.test_notifier')
|
||||
'nova.openstack.common.notifier.test_notifier')
|
||||
self.volume = importutils.import_object(FLAGS.volume_manager)
|
||||
self.context = context.get_admin_context()
|
||||
instance = db.instance_create(self.context, {})
|
||||
|
@ -20,9 +20,9 @@
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova import flags
|
||||
from nova.notifier import test_notifier
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import test_notifier
|
||||
from nova import test
|
||||
from nova.volume import utils as volume_utils
|
||||
|
||||
@ -39,7 +39,7 @@ class UsageInfoTestCase(test.TestCase):
|
||||
stub_network=True,
|
||||
host='fake')
|
||||
self.stubs.Set(flags.FLAGS, 'notification_driver',
|
||||
'nova.notifier.test_notifier')
|
||||
'nova.openstack.common.notifier.test_notifier')
|
||||
self.volume = importutils.import_object(FLAGS.volume_manager)
|
||||
self.user_id = 'fake'
|
||||
self.project_id = 'fake'
|
||||
|
@ -17,8 +17,8 @@
|
||||
"""Volume-related Utilities and helpers."""
|
||||
|
||||
from nova import flags
|
||||
from nova.notifier import api as notifier_api
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common.notifier import api as notifier_api
|
||||
from nova.openstack.common import timeutils
|
||||
from nova import utils
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
[DEFAULT]
|
||||
|
||||
# The list of modules to copy from openstack-common
|
||||
modules=cfg,excutils,gettextutils,importutils,iniparser,jsonutils,local,log,policy,setup,timeutils,rpc
|
||||
modules=cfg,context,excutils,gettextutils,importutils,iniparser,jsonutils,local,log,notifier,policy,setup,timeutils,rpc
|
||||
|
||||
# The base module to hold the copy of openstack.common
|
||||
base=nova
|
||||
|
Loading…
Reference in New Issue
Block a user