Fix aggregator _get_unique_key method

This patch fixes the error that occurs in aggregator when project_id and
user_id are missing from aggregated sample. This problem appears for
example when swift incoming/outgoing bytes samples are aggregated and
non-authenticated users access swift publicly readable containers.

Change-Id: I8af201b6cf29b0206b3ffd996990f629d927334e
Closes-bug: #1333230
This commit is contained in:
Ala Rezmerita 2014-06-30 17:24:28 +02:00
parent 09720bf524
commit 3fcdd15c57
2 changed files with 59 additions and 2 deletions

View File

@ -1441,3 +1441,55 @@ class BasePipelineTestCase(test.BaseTestCase):
pipe.flush(None)
publisher = pipeline_manager.pipelines[0].publishers[0]
self.assertEqual(1, len(publisher.samples))
def test_aggregator_without_authentication(self):
transformer_cfg = [
{
'name': 'aggregator',
'parameters': {'size': 2},
},
]
self._set_pipeline_cfg('transformers', transformer_cfg)
self._set_pipeline_cfg('counters', ['storage.objects.outgoing.bytes'])
counters = [
sample.Sample(
name='storage.objects.outgoing.bytes',
type=sample.TYPE_DELTA,
volume=26,
unit='B',
user_id=None,
project_id=None,
resource_id='test_resource',
timestamp=timeutils.utcnow().isoformat(),
resource_metadata={'version': '1.0'}
),
sample.Sample(
name='storage.objects.outgoing.bytes',
type=sample.TYPE_DELTA,
volume=16,
unit='B',
user_id=None,
project_id=None,
resource_id='test_resource',
timestamp=timeutils.utcnow().isoformat(),
resource_metadata={'version': '2.0'}
)
]
pipeline_manager = pipeline.PipelineManager(self.pipeline_cfg,
self.transformer_manager)
pipe = pipeline_manager.pipelines[0]
pipe.publish_samples(None, [counters[0]])
pipe.flush(None)
publisher = pipe.publishers[0]
self.assertEqual(0, len(publisher.samples))
pipe.publish_samples(None, [counters[1]])
pipe.flush(None)
publisher = pipe.publishers[0]
self.assertEqual(1, len(publisher.samples))
self.assertEqual(42, getattr(publisher.samples[0], 'volume'))
self.assertEqual("test_resource", getattr(publisher.samples[0],
'resource_id'))

View File

@ -214,8 +214,13 @@ class AggregatorTransformer(ScalingTransformer):
self.key_attributes.append(name)
def _get_unique_key(self, s):
non_aggregated_keys = "-".join([getattr(s, field)
for field in self.key_attributes])
# NOTE(arezmerita): in samples generated by ceilometer middleware,
# when accessing without authentication publicly readable/writable
# swift containers, the project_id and the user_id are missing.
# They will be replaced by <undefined> for unique key construction.
keys = ['<undefined>' if getattr(s, f) is None else getattr(s, f)
for f in self.key_attributes]
non_aggregated_keys = "-".join(keys)
# NOTE(sileht): it assumes, a meter always have the same unit/type
return "%s-%s-%s" % (s.name, s.resource_id, non_aggregated_keys)