From 481e6151affbce38056603c1cb5463974ac35d33 Mon Sep 17 00:00:00 2001 From: zhangxuanyuan Date: Tue, 12 Sep 2017 17:10:36 +0800 Subject: [PATCH] Remove class HttpDispatcher Remove class HttpDispatcher and use http publisher instead Change-Id: If4174431c9a09e237fb79c9643a54748afe797b0 --- ceilometer/dispatcher/http.py | 175 ------------- ceilometer/opts.py | 2 - ceilometer/publisher/direct.py | 2 +- ceilometer/tests/unit/dispatcher/test_http.py | 229 ------------------ setup.cfg | 2 - 5 files changed, 1 insertion(+), 409 deletions(-) delete mode 100644 ceilometer/dispatcher/http.py delete mode 100644 ceilometer/tests/unit/dispatcher/test_http.py diff --git a/ceilometer/dispatcher/http.py b/ceilometer/dispatcher/http.py deleted file mode 100644 index 3b8fb339d5..0000000000 --- a/ceilometer/dispatcher/http.py +++ /dev/null @@ -1,175 +0,0 @@ -# Copyright 2013 IBM Corp -# -# 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 json - -from debtcollector import removals -from oslo_config import cfg -from oslo_log import log -from oslo_utils import strutils -import requests - -from ceilometer import dispatcher - -LOG = log.getLogger(__name__) - -http_dispatcher_opts = [ - cfg.StrOpt('target', - default='', - help='The target where the http request will be sent. ' - 'If this is not set, no data will be posted. For ' - 'example: target = http://hostname:1234/path'), - cfg.StrOpt('event_target', - help='The target for event data where the http request ' - 'will be sent to. If this is not set, it will default ' - 'to same as Sample target.'), - cfg.IntOpt('timeout', - default=5, - help='The max time in seconds to wait for a request to ' - 'timeout.'), - cfg.StrOpt('verify_ssl', - help='The path to a server certificate or directory if the ' - 'system CAs are not used or if a self-signed certificate ' - 'is used. Set to False to ignore SSL cert verification.'), - cfg.BoolOpt('batch_mode', - default=False, - help='Indicates whether samples are published in a batch.'), -] - - -@removals.removed_class("HttpDispatcher", message="Use http publisher instead", - removal_version="9.0.0") -class HttpDispatcher(dispatcher.MeterDispatcherBase, - dispatcher.EventDispatcherBase): - """Dispatcher class for posting metering/event data into a http target. - - To enable this dispatcher, the following option needs to be present in - ceilometer.conf file:: - - [DEFAULT] - meter_dispatchers = http - event_dispatchers = http - - Dispatcher specific options can be added as follows:: - - [dispatcher_http] - target = www.example.com - event_target = www.example.com - timeout = 2 - # No SSL verification - #verify_ssl = False - # SSL verification with system-installed CAs - verify_ssl = True - # SSL verification with specific CA or directory of certs - #verify_ssl = /path/to/ca_certificate.crt - - Instead of publishing events and meters as JSON objects in individual HTTP - requests, they can be batched up and published as JSON arrays of objects:: - - [dispatcher_http] - batch_mode = True - """ - - def __init__(self, conf): - super(HttpDispatcher, self).__init__(conf) - self.headers = {'Content-type': 'application/json'} - self.timeout = self.conf.dispatcher_http.timeout - self.target = self.conf.dispatcher_http.target - self.event_target = (self.conf.dispatcher_http.event_target or - self.target) - - if self.conf.dispatcher_http.batch_mode: - self.post_event_data = self.post_event - self.post_meter_data = self.post_meter - else: - self.post_event_data = self.post_individual_events - self.post_meter_data = self.post_individual_meters - - try: - self.verify_ssl = strutils.bool_from_string( - self.conf.dispatcher_http.verify_ssl, strict=True) - except ValueError: - self.verify_ssl = self.conf.dispatcher_http.verify_ssl or True - - def record_metering_data(self, data): - if self.target == '': - # if the target was not set, do not do anything - LOG.error('Dispatcher target was not set, no meter will ' - 'be posted. Set the target in the ceilometer.conf ' - 'file.') - return - - # We may have receive only one counter on the wire - if not isinstance(data, list): - data = [data] - - self.post_meter_data(data) - - def post_individual_meters(self, meters): - for meter in meters: - self.post_meter(meter) - - def post_meter(self, meter): - meter_json = json.dumps(meter) - res = None - try: - LOG.trace('Meter Message: %s', meter_json) - res = requests.post(self.target, - data=meter_json, - headers=self.headers, - verify=self.verify_ssl, - timeout=self.timeout) - LOG.debug('Meter message posting finished with status code ' - '%d.', res.status_code) - res.raise_for_status() - - except requests.exceptions.HTTPError: - LOG.exception('Status Code: %(code)s. ' - 'Failed to dispatch meter: %(meter)s' % - {'code': res.status_code, 'meter': meter_json}) - - def record_events(self, events): - if self.event_target == '': - # if the event target was not set, do not do anything - LOG.error('Dispatcher event target was not set, no event will ' - 'be posted. Set event_target in the ceilometer.conf ' - 'file.') - return - - if not isinstance(events, list): - events = [events] - - self.post_event_data(events) - - def post_individual_events(self, events): - for event in events: - self.post_event(event) - - def post_event(self, event): - res = None - try: - event_json = json.dumps(event) - LOG.trace('Event Message: %s', event_json) - res = requests.post(self.event_target, - data=event_json, - headers=self.headers, - verify=self.verify_ssl, - timeout=self.timeout) - LOG.debug('Event Message posting to %s: status code %d.', - self.event_target, res.status_code) - res.raise_for_status() - except requests.exceptions.HTTPError: - LOG.exception('Status Code: %(code)s. ' - 'Failed to dispatch event: %(event)s' % - {'code': res.status_code, 'event': event_json}) diff --git a/ceilometer/opts.py b/ceilometer/opts.py index 501a439118..5fb86672f1 100644 --- a/ceilometer/opts.py +++ b/ceilometer/opts.py @@ -28,7 +28,6 @@ import ceilometer.compute.virt.vmware.inspector import ceilometer.compute.virt.xenapi.inspector import ceilometer.dispatcher import ceilometer.dispatcher.gnocchi_opts -import ceilometer.dispatcher.http import ceilometer.event.converter import ceilometer.exchange_control import ceilometer.hardware.discovery @@ -111,7 +110,6 @@ def list_opts(): 'membership has changed'), ]), ('database', ceilometer.storage.OPTS), - ('dispatcher_http', ceilometer.dispatcher.http.http_dispatcher_opts), ('dispatcher_gnocchi', ceilometer.dispatcher.gnocchi_opts.dispatcher_opts), ('event', ceilometer.event.converter.OPTS), diff --git a/ceilometer/publisher/direct.py b/ceilometer/publisher/direct.py index 3d51b1ea7f..7bd4d26a55 100644 --- a/ceilometer/publisher/direct.py +++ b/ceilometer/publisher/direct.py @@ -31,7 +31,7 @@ class DirectPublisher(publisher.ConfigPublisherBase): are required. By default, the database dispatcher is used to select another one we - can use direct://?dispatcher=gnocchi, direct://?dispatcher=http, ... + can use direct://?dispatcher=gnocchi, ... """ def __init__(self, conf, parsed_url): super(DirectPublisher, self).__init__(conf, parsed_url) diff --git a/ceilometer/tests/unit/dispatcher/test_http.py b/ceilometer/tests/unit/dispatcher/test_http.py deleted file mode 100644 index 4b5473c22b..0000000000 --- a/ceilometer/tests/unit/dispatcher/test_http.py +++ /dev/null @@ -1,229 +0,0 @@ -# -# Copyright 2013 IBM Corp -# -# 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 datetime -import uuid - -import mock -from oslotest import base -import requests - -from ceilometer.dispatcher import http -from ceilometer.event.storage import models as event_models -from ceilometer.publisher import utils -from ceilometer import service - - -class TestDispatcherHttp(base.BaseTestCase): - """Test sending meters with the http dispatcher""" - - def setUp(self): - super(TestDispatcherHttp, self).setUp() - self.CONF = service.prepare_service([], []) - self.msg = {'counter_name': 'test', - 'resource_id': self.id(), - 'counter_volume': 1, - } - self.msg['message_signature'] = utils.compute_signature( - self.msg, self.CONF.publisher.telemetry_secret, - ) - - def test_http_dispatcher_config_options(self): - self.CONF.dispatcher_http.target = 'fake' - self.CONF.dispatcher_http.timeout = 2 - dispatcher = http.HttpDispatcher(self.CONF) - - self.assertEqual('fake', dispatcher.target) - self.assertEqual(2, dispatcher.timeout) - - def test_http_dispatcher_with_no_target(self): - self.CONF.dispatcher_http.target = '' - dispatcher = http.HttpDispatcher(self.CONF) - - # The target should be None - self.assertEqual('', dispatcher.target) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_metering_data(self.msg) - - # Since the target is not set, no http post should occur, thus the - # call_count should be zero. - self.assertEqual(0, post.call_count) - - def test_http_dispatcher_with_no_metadata(self): - self.CONF.dispatcher_http.target = 'fake' - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_metering_data(self.msg) - - self.assertEqual(1, post.call_count) - - def test_http_dispatcher_with_ssl_default(self): - self.CONF.dispatcher_http.target = 'https://example.com' - self.CONF.dispatcher_http.verify_ssl = '' - dispatcher = http.HttpDispatcher(self.CONF) - - self.assertEqual(True, dispatcher.verify_ssl) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_metering_data(self.msg) - - self.assertEqual(True, post.call_args[1]['verify']) - - def test_http_dispatcher_with_ssl_true(self): - self.CONF.dispatcher_http.target = 'https://example.com' - self.CONF.dispatcher_http.verify_ssl = 'true' - dispatcher = http.HttpDispatcher(self.CONF) - - self.assertEqual(True, dispatcher.verify_ssl) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_metering_data(self.msg) - - self.assertEqual(True, post.call_args[1]['verify']) - - def test_http_dispatcher_with_ssl_false(self): - self.CONF.dispatcher_http.target = 'https://example.com' - self.CONF.dispatcher_http.verify_ssl = 'false' - dispatcher = http.HttpDispatcher(self.CONF) - - self.assertEqual(False, dispatcher.verify_ssl) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_metering_data(self.msg) - - self.assertEqual(False, post.call_args[1]['verify']) - - def test_http_dispatcher_with_ssl_path(self): - self.CONF.dispatcher_http.target = 'https://example.com' - self.CONF.dispatcher_http.verify_ssl = '/path/to/cert.crt' - dispatcher = http.HttpDispatcher(self.CONF) - - self.assertEqual('/path/to/cert.crt', dispatcher.verify_ssl) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_metering_data(self.msg) - - self.assertEqual('/path/to/cert.crt', post.call_args[1]['verify']) - - def test_http_dispatcher_non_batch(self): - self.CONF.dispatcher_http.target = 'fake' - self.CONF.dispatcher_http.batch_mode = False - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch('requests.post') as post: - dispatcher.record_metering_data([self.msg, self.msg]) - self.assertEqual(2, post.call_count) - - def test_http_dispatcher_batch(self): - self.CONF.dispatcher_http.target = 'fake' - self.CONF.dispatcher_http.batch_mode = True - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch('requests.post') as post: - dispatcher.record_metering_data([self.msg, self.msg, self.msg]) - self.assertEqual(1, post.call_count) - - -class TestEventDispatcherHttp(base.BaseTestCase): - """Test sending events with the http dispatcher""" - def setUp(self): - super(TestEventDispatcherHttp, self).setUp() - self.CONF = service.prepare_service([], []) - - # repr(uuid.uuid4()) is used in test event creation to avoid an - # exception being thrown when the uuid is serialized to JSON - event = event_models.Event(repr(uuid.uuid4()), 'test', - datetime.datetime(2012, 7, 2, 13, 53, 40), - [], {}) - event = utils.message_from_event(event, - self.CONF.publisher.telemetry_secret) - self.event = event - - def test_http_dispatcher(self): - self.CONF.dispatcher_http.event_target = 'fake' - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_events(self.event) - - self.assertEqual(1, post.call_count) - - def test_http_dispatcher_bad_server(self): - self.CONF.dispatcher_http.event_target = 'fake' - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch.object(requests, 'post') as post: - response = requests.Response() - response.status_code = 500 - post.return_value = response - with mock.patch('ceilometer.dispatcher.http.LOG', - mock.MagicMock()) as LOG: - dispatcher.record_events(self.event) - self.assertTrue(LOG.exception.called) - - def test_http_dispatcher_with_no_target(self): - self.CONF.dispatcher_http.event_target = '' - dispatcher = http.HttpDispatcher(self.CONF) - - # The target should be None - self.assertEqual('', dispatcher.event_target) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_events(self.event) - - # Since the target is not set, no http post should occur, thus the - # call_count should be zero. - self.assertEqual(0, post.call_count) - - def test_http_dispatcher_share_target(self): - self.CONF.dispatcher_http.event_target = 'fake' - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_events(self.event) - - self.assertEqual('fake', post.call_args[0][0]) - - def test_http_dispatcher_with_ssl_path(self): - self.CONF.dispatcher_http.event_target = 'https://example.com' - self.CONF.dispatcher_http.verify_ssl = '/path/to/cert.crt' - dispatcher = http.HttpDispatcher(self.CONF) - - self.assertEqual('/path/to/cert.crt', dispatcher.verify_ssl) - - with mock.patch.object(requests, 'post') as post: - dispatcher.record_events(self.event) - - self.assertEqual('/path/to/cert.crt', post.call_args[1]['verify']) - - def test_http_dispatcher_nonbatch_event(self): - self.CONF.dispatcher_http.event_target = 'fake' - self.CONF.dispatcher_http.batch_mode = False - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch('requests.post') as post: - dispatcher.record_events([self.event, self.event]) - self.assertEqual(2, post.call_count) - - def test_http_dispatcher_batch_event(self): - self.CONF.dispatcher_http.event_target = 'fake' - self.CONF.dispatcher_http.batch_mode = True - dispatcher = http.HttpDispatcher(self.CONF) - - with mock.patch('requests.post') as post: - dispatcher.record_events([self.event, self.event]) - self.assertEqual(1, post.call_count) diff --git a/setup.cfg b/setup.cfg index 7646456710..09d8a63a72 100644 --- a/setup.cfg +++ b/setup.cfg @@ -287,11 +287,9 @@ console_scripts = ceilometer.dispatcher.meter = database = ceilometer.dispatcher.database:MeterDatabaseDispatcher - http = ceilometer.dispatcher.http:HttpDispatcher gnocchi = ceilometer.dispatcher.gnocchi:GnocchiDispatcher ceilometer.dispatcher.event = - http = ceilometer.dispatcher.http:HttpDispatcher gnocchi = ceilometer.dispatcher.gnocchi:GnocchiDispatcher network.statistics.drivers =