Merge "Revert "Add support for posting samples to notification-agent via API""

This commit is contained in:
Jenkins 2015-06-26 20:45:10 +00:00 committed by Gerrit Code Review
commit 917fea99bc
7 changed files with 65 additions and 55 deletions

View File

@ -62,7 +62,7 @@ def setup_app(pecan_config=None, extra_hooks=None):
# FIXME: Replace DBHook with a hooks.TransactionHook
app_hooks = [hooks.ConfigHook(),
hooks.DBHook(),
hooks.NotifierHook(),
hooks.PipelineHook(),
hooks.TranslationHook()]
if extra_hooks:
app_hooks.extend(extra_hooks)

View File

@ -21,10 +21,8 @@
import base64
import datetime
from oslo_config import cfg
from oslo_context import context
from oslo_log import log
from oslo_utils import strutils
from oslo_utils import timeutils
import pecan
from pecan import rest
@ -37,7 +35,6 @@ from ceilometer.api.controllers.v2 import base
from ceilometer.api.controllers.v2 import utils as v2_utils
from ceilometer.api import rbac
from ceilometer.i18n import _
from ceilometer.publisher import utils as publisher_utils
from ceilometer import sample
from ceilometer import storage
from ceilometer import utils
@ -294,20 +291,14 @@ class MeterController(rest.RestController):
for e in pecan.request.storage_conn.get_samples(f, limit=limit)
]
@wsme_pecan.wsexpose([OldSample], str, body=[OldSample], status_code=201)
def post(self, direct='', samples=None):
@wsme_pecan.wsexpose([OldSample], body=[OldSample], status_code=201)
def post(self, samples):
"""Post a list of new Samples to Telemetry.
:param direct: a flag indicates whether the samples will be posted
directly to storage or not.
:param samples: a list of samples within the request body.
"""
rbac.enforce('create_samples', pecan.request)
direct = strutils.bool_from_string(direct)
if not samples:
msg = _('Samples should be included in request body')
raise base.ClientSideError(msg)
rbac.enforce('create_samples', pecan.request)
now = timeutils.utcnow()
auth_project = rbac.get_limited_to_project(pecan.request.headers)
@ -317,6 +308,14 @@ class MeterController(rest.RestController):
published_samples = []
for s in samples:
for p in pecan.request.pipeline_manager.pipelines:
if p.support_meter(s.counter_name):
break
else:
message = _("The metric %s is not supported by metering "
"pipeline configuration.") % s.counter_name
raise base.ClientSideError(message, status_code=409)
if self.meter_name != s.counter_name:
raise wsme.exc.InvalidInput('counter_name', s.counter_name,
'should be %s' % self.meter_name)
@ -353,22 +352,13 @@ class MeterController(rest.RestController):
resource_metadata=utils.restore_nesting(s.resource_metadata,
separator='.'),
source=s.source)
published_samples.append(published_sample)
s.message_id = published_sample.id
sample_dict = publisher_utils.meter_message_from_counter(
published_sample, cfg.CONF.publisher.telemetry_secret)
if direct:
ts = timeutils.parse_isotime(sample_dict['timestamp'])
sample_dict['timestamp'] = timeutils.normalize_time(ts)
pecan.request.storage_conn.record_metering_data(sample_dict)
else:
published_samples.append(sample_dict)
if not direct:
ctxt = context.RequestContext(user=def_user_id,
tenant=def_project_id,
is_admin=True)
notifier = pecan.request.notifier
notifier.info(ctxt, 'telemetry.api', published_samples)
with pecan.request.pipeline_manager.publisher(
context.get_admin_context()) as publisher:
publisher(published_samples)
return samples

View File

@ -21,7 +21,7 @@ from oslo_log import log
from pecan import hooks
from ceilometer.i18n import _LE
from ceilometer import messaging
from ceilometer import pipeline
from ceilometer import storage
LOG = log.getLogger(__name__)
@ -67,20 +67,19 @@ class DBHook(hooks.PecanHook):
"retry later: %(err)s") % params)
class NotifierHook(hooks.PecanHook):
"""Create and attach a notifier to the request.
class PipelineHook(hooks.PecanHook):
"""Create and attach a pipeline to the request.
Usually, samples will be push to notification bus by notifier when they
are posted via /v2/meters/ API.
That allows new samples to be posted via the /v2/meters/ API.
"""
def __init__(self):
transport = messaging.get_transport()
self.notifier = messaging.get_notifier(transport,
publisher_id="ceilometer.api")
# this is done here as the cfg options are not available
# when the file is imported.
self.pipeline_manager = pipeline.setup_pipeline()
def before(self, state):
state.request.notifier = self.notifier
state.request.pipeline_manager = self.pipeline_manager
class TranslationHook(hooks.PecanHook):

View File

@ -39,6 +39,7 @@ class TestApp(base.BaseTestCase):
@mock.patch('ceilometer.storage.get_connection_from_config',
mock.MagicMock())
@mock.patch('ceilometer.api.hooks.PipelineHook', mock.MagicMock())
@mock.patch('pecan.make_app')
def test_pecan_debug(self, mocked):
def _check_pecan_debug(g_debug, p_debug, expected, workers=1):

View File

@ -22,6 +22,7 @@ import mock
from oslo_utils import timeutils
from oslotest import mockpatch
from ceilometer import pipeline
from ceilometer.tests.api import v2
from ceilometer.tests import db as tests_db
@ -36,11 +37,30 @@ class TestPostSamples(v2.FunctionalTest,
def setUp(self):
self.published = []
notifier = mock.Mock()
notifier.info.side_effect = self.fake_notifier_sample
self.useFixture(mockpatch.Patch('ceilometer.messaging.get_notifier',
notifier.sample.side_effect = self.fake_notifier_sample
self.useFixture(mockpatch.Patch('oslo_messaging.Notifier',
return_value=notifier))
super(TestPostSamples, self).setUp()
@mock.patch.object(pipeline.SampleSource, "support_meter")
def test_post_not_supported_sample(self, mocked):
mocked.return_value = False
s = [{'counter_name': 'apples',
'counter_type': 'gauge',
'counter_unit': 'instance',
'counter_volume': 1,
'resource_id': 'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36',
'project_id': '35b17138-b364-4e6a-a131-8f3099c5be68',
'user_id': 'efd87807-12d2-4b38-9c70-5f5c2ac427ff',
'resource_metadata': {'name1': 'value1',
'name2': 'value2'}}]
resp = self.post_json('/meters/apples/', s, expect_errors=True)
self.assertEqual(409, resp.status_code)
expected_msg = ("The metric apples is not supported by metering "
"pipeline configuration.")
self.assertEqual(expected_msg,
resp.json['error_message']['faultstring'])
def test_one(self):
s1 = [{'counter_name': 'apples',
'counter_type': 'gauge',

View File

@ -8,7 +8,7 @@ tests:
- name: post sample for meter
desc: post a single sample
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -41,7 +41,7 @@ tests:
- name: post a sample expect location
desc: https://bugs.launchpad.net/ceilometer/+bug/1426426
xfail: true
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json

View File

@ -45,7 +45,7 @@ tests:
- "[]"
- name: meter bad accept
url: /v2/meters/noexist?direct=True
url: /v2/meters/noexist
request_headers:
accept: text/plain
status: 406
@ -56,7 +56,7 @@ tests:
status: "404 || 405"
- name: post meter no data
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -66,7 +66,7 @@ tests:
- name: post meter error is JSON
desc: https://bugs.launchpad.net/ceilometer/+bug/1426483
xfail: true
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -81,7 +81,7 @@ tests:
- name: post meter bad content-type
desc: https://bugs.launchpad.net/wsme/+bug/1419110
xfail: true
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: text/plain
@ -91,7 +91,7 @@ tests:
- name: post bad samples to meter
desc: https://bugs.launchpad.net/ceilometer/+bug/1428185
xfail: true
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -105,7 +105,7 @@ tests:
# POST variations on a malformed sample
- name: post limited counter to meter
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -118,7 +118,7 @@ tests:
- "Invalid input for field/attribute counter_name"
- name: post mismatched counter name to meter
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -134,7 +134,7 @@ tests:
- "should be apples"
- name: post counter no resource to meter
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -149,7 +149,7 @@ tests:
- "Mandatory field missing."
- name: post counter bad type to meter
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -167,7 +167,7 @@ tests:
# Manipulate samples
- name: post counter to meter
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -207,7 +207,7 @@ tests:
- unable to convert to int
- name: post counter to meter different resource
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
status: 201
request_headers:
@ -230,7 +230,7 @@ tests:
- name: post counter with bad timestamp
desc: https://bugs.launchpad.net/wsme/+bug/1428624
xfail: true
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -243,7 +243,7 @@ tests:
timestamp: "2013-01-bad 23:23:20"
- name: post counter with good timestamp
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
status: 201
request_headers:
@ -259,7 +259,7 @@ tests:
- name: post counter with wrong metadata
desc: https://bugs.launchpad.net/ceilometer/+bug/1428628
xfail: true
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
request_headers:
content-type: application/json
@ -273,7 +273,7 @@ tests:
resource_metadata: "a string"
- name: post counter with empty metadata
url: /v2/meters/apples?direct=True
url: /v2/meters/apples
method: POST
status: 201
request_headers: