collector: use an intermediate proxy class for event dispatcher
This makes sure that the base class EventDispatcherBase does not owns any code itself. This makes external plugin easier to implement as they don't _have_ to inherit from EventDispatcherBase, they just need to implement a `record_events(events)' method and that's it. This will allow Panko to provide the database dispatcher without having a hard dependency on Ceilometer. Change-Id: I094aed1e7e081fe1de130d987035a6c9d977d25e
This commit is contained in:
parent
f99cedf11f
commit
984042084f
|
@ -24,7 +24,7 @@ from oslo_utils import netutils
|
|||
from oslo_utils import units
|
||||
|
||||
from ceilometer import dispatcher
|
||||
from ceilometer.i18n import _, _LE
|
||||
from ceilometer.i18n import _, _LE, _LW
|
||||
from ceilometer import messaging
|
||||
from ceilometer import service_base
|
||||
from ceilometer import utils
|
||||
|
@ -94,7 +94,8 @@ class CollectorService(service_base.ServiceBase):
|
|||
self.event_listener = (
|
||||
messaging.get_batch_notification_listener(
|
||||
transport, [event_target],
|
||||
[EventEndpoint(self.event_manager)],
|
||||
[EventEndpoint(
|
||||
EventDispatcherVerificator(self.event_manager))],
|
||||
allow_requeue=True,
|
||||
batch_size=cfg.CONF.collector.batch_size,
|
||||
batch_timeout=cfg.CONF.collector.batch_timeout))
|
||||
|
@ -161,6 +162,23 @@ class SampleEndpoint(CollectorEndpoint):
|
|||
ep_type = 'sample'
|
||||
|
||||
|
||||
class EventDispatcherVerificator(object):
|
||||
def __init__(self, dispatcher):
|
||||
self.dispatcher = dispatcher
|
||||
|
||||
def verify_and_record_events(self, events):
|
||||
"""Verify event signature and record them."""
|
||||
goods = []
|
||||
for event in events:
|
||||
if utils.verify_signature(
|
||||
event, self.conf.publisher.telemetry_secret):
|
||||
goods.append(event)
|
||||
else:
|
||||
LOG.warning(_LW(
|
||||
'event signature invalid, discarding event: %s'), event)
|
||||
return self.dispatcher.record_events(goods)
|
||||
|
||||
|
||||
class EventEndpoint(CollectorEndpoint):
|
||||
method = 'verify_and_record_events'
|
||||
ep_type = 'event'
|
||||
|
|
|
@ -21,7 +21,6 @@ import six
|
|||
from stevedore import named
|
||||
|
||||
from ceilometer.i18n import _LW
|
||||
from ceilometer.publisher import utils
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
@ -108,15 +107,3 @@ class EventDispatcherBase(Base):
|
|||
@abc.abstractmethod
|
||||
def record_events(self, events):
|
||||
"""Record events."""
|
||||
|
||||
def verify_and_record_events(self, events):
|
||||
"""Verify event signature and record them."""
|
||||
goods = []
|
||||
for event in events:
|
||||
if utils.verify_signature(
|
||||
event, self.conf.publisher.telemetry_secret):
|
||||
goods.append(event)
|
||||
else:
|
||||
LOG.warning(_LW(
|
||||
'event signature invalid, discarding event: %s'), event)
|
||||
return self.record_events(goods)
|
||||
|
|
|
@ -44,28 +44,6 @@ class TestDispatcherDB(base.BaseTestCase):
|
|||
self.dispatcher.record_events(event)
|
||||
self.assertEqual(1, len(record_events.call_args_list[0][0][0]))
|
||||
|
||||
@mock.patch('ceilometer.publisher.utils.verify_signature')
|
||||
def test_event_with_bad_signature(self, mocked_verify):
|
||||
event = event_models.Event(uuid.uuid4(), 'test',
|
||||
datetime.datetime(2012, 7, 2, 13, 53, 40),
|
||||
[], {}).serialize()
|
||||
|
||||
def _fake_verify(ev, secret):
|
||||
if ev.get('message_signature') == 'bad_signature':
|
||||
return False
|
||||
return True
|
||||
mocked_verify.side_effect = _fake_verify
|
||||
with mock.patch.object(self.dispatcher.event_conn,
|
||||
'record_events') as record_events:
|
||||
event['message_signature'] = 'bad_signature'
|
||||
self.dispatcher.verify_and_record_events([event])
|
||||
self.assertEqual([], record_events.call_args_list[0][0][0])
|
||||
del event['message_signature']
|
||||
event['message_signature'] = utils.compute_signature(
|
||||
event, self.CONF.publisher.telemetry_secret)
|
||||
self.dispatcher.verify_and_record_events([event])
|
||||
self.assertEqual(1, len(record_events.call_args_list[1][0][0]))
|
||||
|
||||
def test_valid_message(self):
|
||||
msg = {'counter_name': 'test',
|
||||
'resource_id': self.id(),
|
||||
|
|
Loading…
Reference in New Issue