refactor DefinitionException classes

We use debtcollector to mark some DefinitionException classes, such as
EventDefinitionException, deprecated to declarative.DefinitionException,
while we never use them. In fact, declarative.DefinitionException is
the deprecated one, we should use precise Exception such as
MeterDefinitionException.

This patch refactor all the DefinitionException classes.

Change-Id: I8147e593adf3a3213de165c6bbd118f882f00ab7
This commit is contained in:
ZhiQiang Fan 2016-04-19 06:21:22 +08:00
parent 2f718d08e3
commit d59f099372
7 changed files with 44 additions and 64 deletions

View File

@ -26,8 +26,21 @@ LOG = log.getLogger(__name__)
class DefinitionException(Exception): class DefinitionException(Exception):
def __init__(self, message, definition_cfg): def __init__(self, message, definition_cfg):
super(DefinitionException, self).__init__(message) msg = '%s %s: %s' % (self.__class__.__name__, definition_cfg, message)
self.definition_cfg = definition_cfg super(DefinitionException, self).__init__(msg)
self.brief_message = message
class MeterDefinitionException(DefinitionException):
pass
class EventDefinitionException(DefinitionException):
pass
class ResourceDefinitionException(DefinitionException):
pass
class Definition(object): class Definition(object):

View File

@ -73,12 +73,6 @@ def cache_key_mangler(key):
return uuid.uuid5(CACHE_NAMESPACE, key).hex return uuid.uuid5(CACHE_NAMESPACE, key).hex
class ResourcesDefinitionException(Exception):
def __init__(self, message, definition_cfg):
msg = '%s %s: %s' % (self.__class__.__name__, definition_cfg, message)
super(ResourcesDefinitionException, self).__init__(msg)
class ResourcesDefinition(object): class ResourcesDefinition(object):
MANDATORY_FIELDS = {'resource_type': six.string_types, MANDATORY_FIELDS = {'resource_type': six.string_types,
@ -90,10 +84,10 @@ class ResourcesDefinition(object):
for field, field_type in self.MANDATORY_FIELDS.items(): for field, field_type in self.MANDATORY_FIELDS.items():
if field not in self.cfg: if field not in self.cfg:
raise declarative.DefinitionException( raise declarative.ResourceDefinitionException(
_LE("Required field %s not specified") % field, self.cfg) _LE("Required field %s not specified") % field, self.cfg)
if not isinstance(self.cfg[field], field_type): if not isinstance(self.cfg[field], field_type):
raise declarative.DefinitionException( raise declarative.ResourceDefinitionException(
_LE("Required field %(field)s should be a %(type)s") % _LE("Required field %(field)s should be a %(type)s") %
{'field': field, 'type': field_type}, self.cfg) {'field': field, 'type': field_type}, self.cfg)

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from debtcollector import moves
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
from oslo_utils import fnmatch from oslo_utils import fnmatch
@ -44,12 +43,6 @@ cfg.CONF.register_opts(OPTS, group='event')
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
EventDefinitionException = moves.moved_class(declarative.DefinitionException,
'EventDefinitionException',
__name__,
version=6.0,
removal_version="?")
class TraitDefinition(declarative.Definition): class TraitDefinition(declarative.Definition):
def __init__(self, name, trait_cfg, plugin_manager): def __init__(self, name, trait_cfg, plugin_manager):
@ -58,7 +51,7 @@ class TraitDefinition(declarative.Definition):
if isinstance(trait_cfg, dict) else 'text') if isinstance(trait_cfg, dict) else 'text')
self.trait_type = models.Trait.get_type_by_name(type_name) self.trait_type = models.Trait.get_type_by_name(type_name)
if self.trait_type is None: if self.trait_type is None:
raise declarative.DefinitionException( raise declarative.EventDefinitionException(
_("Invalid trait type '%(type)s' for trait %(trait)s") _("Invalid trait type '%(type)s' for trait %(trait)s")
% dict(type=type_name, trait=name), self.cfg) % dict(type=type_name, trait=name), self.cfg)
@ -102,7 +95,7 @@ class EventDefinition(object):
event_type = definition_cfg['event_type'] event_type = definition_cfg['event_type']
traits = definition_cfg['traits'] traits = definition_cfg['traits']
except KeyError as err: except KeyError as err:
raise declarative.DefinitionException( raise declarative.EventDefinitionException(
_("Required field %s not specified") % err.args[0], self.cfg) _("Required field %s not specified") % err.args[0], self.cfg)
if isinstance(event_type, six.string_types): if isinstance(event_type, six.string_types):

View File

@ -40,17 +40,6 @@ cfg.CONF.register_opts(OPTS, group='hardware')
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class MeterDefinitionException(Exception):
def __init__(self, message, definition_cfg):
super(MeterDefinitionException, self).__init__(message)
self.message = message
self.definition_cfg = definition_cfg
def __str__(self):
return '%s %s: %s' % (self.__class__.__name__,
self.definition_cfg, self.message)
class MeterDefinition(object): class MeterDefinition(object):
required_fields = ['name', 'unit', 'type'] required_fields = ['name', 'unit', 'type']
@ -65,10 +54,10 @@ class MeterDefinition(object):
LOG.warning(_LW("Ignore unrecognized field %s"), fname) LOG.warning(_LW("Ignore unrecognized field %s"), fname)
for fname in self.required_fields: for fname in self.required_fields:
if not getattr(self, fname, None): if not getattr(self, fname, None):
raise MeterDefinitionException( raise declarative.MeterDefinitionException(
_LE("Missing field %s") % fname, self.cfg) _LE("Missing field %s") % fname, self.cfg)
if self.type not in sample.TYPES: if self.type not in sample.TYPES:
raise MeterDefinitionException( raise declarative.MeterDefinitionException(
_LE("Unrecognized type value %s") % self.type, self.cfg) _LE("Unrecognized type value %s") % self.type, self.cfg)
@ -223,8 +212,7 @@ def load_definition(config_def):
try: try:
meter = MeterDefinition(meter_def) meter = MeterDefinition(meter_def)
mappings[meter.name] = meter mappings[meter.name] = meter
except MeterDefinitionException as me: except declarative.DefinitionException as e:
errmsg = (_LE("Error loading meter definition : %(err)s") errmsg = _LE("Error loading meter definition: %s")
% dict(err=me.message)) LOG.error(errmsg, e.brief_message)
LOG.error(errmsg)
return mappings return mappings

View File

@ -15,7 +15,6 @@ import itertools
import pkg_resources import pkg_resources
import six import six
from debtcollector import moves
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
import oslo_messaging import oslo_messaging
@ -41,13 +40,6 @@ cfg.CONF.import_opt('disable_non_metric_meters', 'ceilometer.notification',
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
MeterDefinitionException = moves.moved_class(declarative.DefinitionException,
'MeterDefinitionException',
__name__,
version=6.0,
removal_version="?")
class MeterDefinition(object): class MeterDefinition(object):
SAMPLE_ATTRIBUTES = ["name", "type", "volume", "unit", "timestamp", SAMPLE_ATTRIBUTES = ["name", "type", "volume", "unit", "timestamp",
@ -61,7 +53,7 @@ class MeterDefinition(object):
missing = [field for field in self.REQUIRED_FIELDS missing = [field for field in self.REQUIRED_FIELDS
if not self.cfg.get(field)] if not self.cfg.get(field)]
if missing: if missing:
raise declarative.DefinitionException( raise declarative.MeterDefinitionException(
_LE("Required fields %s not specified") % missing, self.cfg) _LE("Required fields %s not specified") % missing, self.cfg)
self._event_type = self.cfg.get('event_type') self._event_type = self.cfg.get('event_type')
@ -70,7 +62,7 @@ class MeterDefinition(object):
if ('type' not in self.cfg.get('lookup', []) and if ('type' not in self.cfg.get('lookup', []) and
self.cfg['type'] not in sample.TYPES): self.cfg['type'] not in sample.TYPES):
raise declarative.DefinitionException( raise declarative.MeterDefinitionException(
_LE("Invalid type %s specified") % self.cfg['type'], self.cfg) _LE("Invalid type %s specified") % self.cfg['type'], self.cfg)
self._fallback_user_id = declarative.Definition( self._fallback_user_id = declarative.Definition(
@ -193,10 +185,9 @@ class ProcessMeterNotifications(plugin_base.NotificationBase):
or not cfg.CONF.notification.disable_non_metric_meters): or not cfg.CONF.notification.disable_non_metric_meters):
try: try:
md = MeterDefinition(meter_cfg, plugin_manager) md = MeterDefinition(meter_cfg, plugin_manager)
except declarative.DefinitionException as me: except declarative.DefinitionException as e:
errmsg = (_LE("Error loading meter definition : %(err)s") errmsg = _LE("Error loading meter definition: %s")
% dict(err=six.text_type(me))) LOG.error(errmsg, six.text_type(e))
LOG.error(errmsg)
else: else:
definitions[meter_cfg['name']] = md definitions[meter_cfg['name']] = md
return definitions.values() return definitions.values()

View File

@ -44,8 +44,8 @@ class TestMeterDefinition(test_base.BaseTestCase):
cfg = dict(name='test', type='gauge') cfg = dict(name='test', type='gauge')
try: try:
generic.MeterDefinition(cfg) generic.MeterDefinition(cfg)
except generic.MeterDefinitionException as e: except declarative.MeterDefinitionException as e:
self.assertEqual("Missing field unit", e.message) self.assertEqual("Missing field unit", e.brief_message)
def test_config_invalid_field(self): def test_config_invalid_field(self):
cfg = dict(name='test', cfg = dict(name='test',
@ -62,8 +62,9 @@ class TestMeterDefinition(test_base.BaseTestCase):
snmp_inspector={}) snmp_inspector={})
try: try:
generic.MeterDefinition(cfg) generic.MeterDefinition(cfg)
except generic.MeterDefinitionException as e: except declarative.MeterDefinitionException as e:
self.assertEqual("Unrecognized type value invalid", e.message) self.assertEqual("Unrecognized type value invalid",
e.brief_message)
@mock.patch('ceilometer.hardware.pollsters.generic.LOG') @mock.patch('ceilometer.hardware.pollsters.generic.LOG')
def test_bad_metric_skip(self, LOG): def test_bad_metric_skip(self, LOG):
@ -82,7 +83,7 @@ class TestMeterDefinition(test_base.BaseTestCase):
data = generic.load_definition(cfg) data = generic.load_definition(cfg)
self.assertEqual(2, len(data)) self.assertEqual(2, len(data))
LOG.error.assert_called_with( LOG.error.assert_called_with(
"Error loading meter definition : " "Error loading meter definition: %s",
"Unrecognized type value invalid") "Unrecognized type value invalid")

View File

@ -242,10 +242,10 @@ class TestMeterDefinition(test.BaseTestCase):
try: try:
notifications.MeterDefinition(cfg, mock.Mock()) notifications.MeterDefinition(cfg, mock.Mock())
except declarative.DefinitionException as e: except declarative.DefinitionException as e:
self.assertEqual("Required fields ['name', 'type', 'event_type'," self.assertIn("Required fields ['name', 'type', 'event_type',"
" 'unit', 'volume', 'resource_id']" " 'unit', 'volume', 'resource_id']"
" not specified", " not specified",
encodeutils.exception_to_unicode(e)) encodeutils.exception_to_unicode(e))
def test_bad_type_cfg_definition(self): def test_bad_type_cfg_definition(self):
cfg = dict(name="test", type="foo", event_type="bar.create", cfg = dict(name="test", type="foo", event_type="bar.create",
@ -254,8 +254,8 @@ class TestMeterDefinition(test.BaseTestCase):
try: try:
notifications.MeterDefinition(cfg, mock.Mock()) notifications.MeterDefinition(cfg, mock.Mock())
except declarative.DefinitionException as e: except declarative.DefinitionException as e:
self.assertEqual("Invalid type foo specified", self.assertIn("Invalid type foo specified",
encodeutils.exception_to_unicode(e)) encodeutils.exception_to_unicode(e))
class TestMeterProcessing(test.BaseTestCase): class TestMeterProcessing(test.BaseTestCase):
@ -312,9 +312,9 @@ class TestMeterProcessing(test.BaseTestCase):
project_id="$.payload.project_id")]}) project_id="$.payload.project_id")]})
self._load_meter_def_file(cfg) self._load_meter_def_file(cfg)
self.assertEqual(2, len(self.handler.definitions)) self.assertEqual(2, len(self.handler.definitions))
LOG.error.assert_called_with( args, kwargs = LOG.error.call_args_list[0]
"Error loading meter definition : " self.assertEqual("Error loading meter definition: %s", args[0])
"Invalid type bad_type specified") self.assertTrue(args[1].endswith("Invalid type bad_type specified"))
def test_jsonpath_values_parsed(self): def test_jsonpath_values_parsed(self):
cfg = yaml.dump( cfg = yaml.dump(