From a4154ea85f1f5102674cde0273e26ca77e5612c3 Mon Sep 17 00:00:00 2001 From: Joe Keen Date: Fri, 17 Apr 2015 11:57:18 -0600 Subject: [PATCH] Added two GET api methods for events Change-Id: I5fdbee17dd7c1b171b6cd099537d33b8146400ef --- .../common/repositories/events_repository.py | 7 +- .../repositories/mysql/events_repository.py | 93 +++++++++++++++++++ monasca/v2/reference/events.py | 71 +++++++++++++- requirements.txt | 3 +- setup.cfg | 1 + 5 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 monasca/common/repositories/mysql/events_repository.py diff --git a/monasca/common/repositories/events_repository.py b/monasca/common/repositories/events_repository.py index f2a521f0c..2d021e018 100644 --- a/monasca/common/repositories/events_repository.py +++ b/monasca/common/repositories/events_repository.py @@ -19,7 +19,10 @@ import six @six.add_metaclass(abc.ABCMeta) class EventsRepository(object): + @abc.abstractmethod + def list_event(self, tenant_id, event_id): + return @abc.abstractmethod - def list_events(self, tenant_id, name, dimensions): - return \ No newline at end of file + def list_events(self, tenant_id, offset, limit): + return diff --git a/monasca/common/repositories/mysql/events_repository.py b/monasca/common/repositories/mysql/events_repository.py new file mode 100644 index 000000000..a2617045c --- /dev/null +++ b/monasca/common/repositories/mysql/events_repository.py @@ -0,0 +1,93 @@ +# Copyright 2015 Hewlett-Packard +# +# 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. + +from monasca.common.repositories import constants +from monasca.common.repositories import events_repository as er +from monasca.common.repositories.mysql import mysql_repository +from monasca.openstack.common import log + + +LOG = log.getLogger(__name__) + + +class EventsRepository(mysql_repository.MySQLRepository, + er.EventsRepository): + + def __init__(self): + super(EventsRepository, self).__init__() + + self.database_name = "winchester" + self._base_query = """ + select event.message_id, + event.generated, + event_type.desc, + trait.name, + trait.t_string, + trait.t_float, + trait.t_int, + trait.t_datetime + from event + inner join event_type on event.event_type_id=event_type.id + inner join trait on event.id=trait.event_id""" + + @mysql_repository.mysql_try_catch_block + def list_event(self, tenant_id, event_id): + query = self._base_query + " where event.message_id=%s" + rows = self._execute_query(query, [event_id]) + return rows + + @mysql_repository.mysql_try_catch_block + def list_events(self, tenant_id, offset, limit): + where_clause = "" + order_by_clause = " order by event.generated asc" + + event_ids = self._find_event_ids(offset, limit) + + if event_ids: + ids = ",".join([str(event_id['id']) for event_id in event_ids]) + + where_clause = """ + where trait.event_id + IN ({})""".format(ids) + + query = self._base_query + where_clause + order_by_clause + + rows = self._execute_query(query, []) + + return rows + + def _find_event_ids(self, offset, limit): + if not limit: + limit = constants.PAGE_LIMIT + + parameters = [] + + if offset: + parameters.append(offset.encode('utf8')) + offset_clause = """ + where generated > (select generated + from event + where message_id = %s)""" + else: + offset_clause = "" + + parameters.append(int(limit)) + limit_clause = " limit %s" + + id_query = ('select id from event ' + + offset_clause + + ' order by generated ' + + limit_clause) + + return self._execute_query(id_query, parameters) diff --git a/monasca/v2/reference/events.py b/monasca/v2/reference/events.py index e2a7ebeae..f753c76c1 100644 --- a/monasca/v2/reference/events.py +++ b/monasca/v2/reference/events.py @@ -15,7 +15,8 @@ import json import falcon -from oslo.config import cfg + +import collections from monasca.api import monasca_events_api_v2 from monasca.common.messaging import exceptions as message_queue_exceptions @@ -27,6 +28,9 @@ from monasca.v2.common.schemas import ( from monasca.v2.common.schemas import exceptions as schemas_exceptions from monasca.v2.common import utils from monasca.v2.reference import helpers +from monasca.v2.reference import resource + +from oslo.config import cfg LOG = log.getLogger(__name__) @@ -51,6 +55,8 @@ class Events(monasca_events_api_v2.EventsV2API): resource_api.init_driver('monasca.messaging', cfg.CONF.messaging.driver, ['raw-events'])) + self._events_repo = resource_api.init_driver( + 'monasca.repositories', cfg.CONF.repositories.events_driver) def _validate_event(self, event): """Validates the event @@ -79,6 +85,49 @@ class Events(monasca_events_api_v2.EventsV2API): raise falcon.HTTPInternalServerError('Service unavailable', ex.message) + @resource.resource_try_catch_block + def _list_events(self, tenant_id, uri, offset, limit): + rows = self._events_repo.list_events(tenant_id, offset, limit) + return helpers.paginate(self._build_events(rows), uri, offset) + + @resource.resource_try_catch_block + def _list_event(self, tenant_id, event_id, uri): + rows = self._events_repo.list_event(tenant_id, event_id) + return self._build_events(rows) + + def _build_events(self, rows): + result = collections.OrderedDict() + for row in rows: + event_id, event_data = self._build_event_data(row) + + if event_id['id'] in result: + result[event_id['id']]['data'].update(event_data) + else: + result[event_id['id']] = {'id': event_id['id'], + 'description': event_id['desc'], + 'generated': event_id['generated'], + 'data': event_data} + return result.values() + + def _build_event_data(self, event_row): + event_data = {} + name = event_row['name'] + + if event_row['t_string']: + event_data[name] = event_row['t_string'] + if event_row['t_int']: + event_data[name] = event_row['t_int'] + if event_row['t_float']: + event_data[name] = event_row['t_float'] + if event_row['t_datetime']: + event_data[name] = float(event_row['t_datetime']) + + event_id = {'id': event_row['message_id'], + 'desc': event_row['desc'], + 'generated': float(event_row['generated'])} + + return event_id, event_data + @resource_api.Restify('/v2.0/events/', method='post') def do_post_events(self, req, res): helpers.validate_json_content_type(req) @@ -90,3 +139,23 @@ class Events(monasca_events_api_v2.EventsV2API): self._region) self._send_event(transformed_event) res.status = falcon.HTTP_204 + + @resource_api.Restify('/v2.0/events/', method='get') + def do_get_events(self, req, res): + helpers.validate_authorization(req, self._default_authorized_roles) + tenant_id = helpers.get_tenant_id(req) + offset = helpers.normalize_offset(helpers.get_query_param(req, + 'offset')) + limit = helpers.get_query_param(req, 'limit') + + result = self._list_events(tenant_id, req.uri, offset, limit) + res.body = helpers.dumpit_utf8(result) + res.status = falcon.HTTP_200 + + @resource_api.Restify('/v2.0/events/{event_id}', method='get') + def do_get_event(self, req, res, event_id): + helpers.validate_authorization(req, self._default_authorized_roles) + tenant_id = helpers.get_tenant_id(req) + result = self._list_event(tenant_id, event_id, req.uri) + res.body = helpers.dumpit_utf8(result) + res.status = falcon.HTTP_200 diff --git a/requirements.txt b/requirements.txt index dbe89eac4..8246127bf 100755 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,7 @@ # The above command will install monasca-api base and elasticsearch # implementation while leave other implementation dependencies alone. -falcon>=0.1.9 +falcon==0.1.9 gunicorn>=19.1.0 keystonemiddleware oslo.config>=1.2.1 @@ -38,3 +38,4 @@ pyparsing>=2.0.3 voluptuous>=0.8.7 MySQL-python>=1.2.3 influxdb>=0.2.0 +eventlet diff --git a/setup.cfg b/setup.cfg index 0f43acfaa..d87002c1f 100755 --- a/setup.cfg +++ b/setup.cfg @@ -64,6 +64,7 @@ monasca.repositories = mysql_alarm_definitions_repo = monasca.common.repositories.mysql.alarm_definitions_repository:AlarmDefinitionsRepository mysql_alarms_repo = monasca.common.repositories.mysql.alarms_repository:AlarmsRepository mysql_notifications_repo = monasca.common.repositories.mysql.notifications_repository:NotificationsRepository + mysql_events_repo = monasca.common.repositories.mysql.events_repository:EventsRepository [pbr] warnerrors = True