Add alarm list resource

Change-Id: Ic0906f1b498644116f43c0fa18608ccc38239619
This commit is contained in:
Deklan Dieterly 2014-11-11 13:18:29 -07:00
parent 52b044bbab
commit fcaf0f8a8e
6 changed files with 219 additions and 22 deletions

View File

@ -36,7 +36,7 @@ class AlarmsV2API(object):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarms/', method='get')
def do_get_alarms(self, req, res, id):
def do_get_alarms(self, req, res):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarms/{id}', method='get')

View File

@ -176,7 +176,7 @@ def api_app(conf):
# load the alarm definitions resource
app.add_resource('alarms',
ALARM_DEFINITIONS_DISPATCHER_NAMESPACE,
ALARMS_DISPATCHER_NAMESPACE,
cfg.CONF.dispatcher.driver, [conf])
return app

View File

@ -14,8 +14,7 @@
import datetime
import pyodbc
from oslo.config import cfg
from monasca.common.repositories import exceptions
from monasca.common.repositories import alarms_repository
from monasca.common.repositories.mysql.mysql_repository import MySQLRepository
from monasca.openstack.common import log
@ -25,9 +24,104 @@ LOG = log.getLogger(__name__)
class AlarmsRepository(MySQLRepository, alarms_repository.AlarmsRepository):
def __init__(self):
super(AlarmsRepository, self).__init__()
def get_alarms(self, tenant_id, query_parms):
try:
parms = [tenant_id]
select_clause = """
select distinct a.id as alarm_id, a.state,
ad.id as alarm_definition_id, ad.name as alarm_definition_name,
ad.severity,
md.name as metric_name, mdg.dimensions as metric_dimensions
from alarm as a
inner join alarm_definition as ad
on ad.id = a.alarm_definition_id
inner join alarm_metric as am on am.alarm_id = a.id
inner join metric_definition_dimensions as mdd
on mdd.id = am.metric_definition_dimensions_id
inner join metric_definition as md
on md.id = mdd.metric_definition_id
left join (select dimension_set_id, name, value,
group_concat(name, '=', value) as dimensions
from metric_dimension group by dimension_set_id) as mdg
on mdg.dimension_set_id = mdd.metric_dimension_set_id
"""
order_by_clause = " order by a.id "
where_clause = " where ad.tenant_id = ? "
if 'alarm_definition_id' in query_parms:
parms.append(query_parms['alarm_definition_id'])
where_clause += " and ad.id = ? "
if 'metric_name' in query_parms:
sub_select_clause = """
and a.id in (select distinct a.id from alarm as a
inner join alarm_metric as am on am.alarm_id
= a.id
inner join metric_definition_dimensions as mdd
on mdd.id =
am.metric_definition_dimensions_id
inner join (select distinct id from
metric_definition
where name = ?) as md
on md.id = mdd.metric_definition_id)
"""
parms.append(query_parms['metric_name'].encode('utf8'))
where_clause += sub_select_clause
if 'state' in query_parms:
parms.append(query_parms['state'].encode('utf8'))
where_clause += " and a.state = ? "
if 'metric_dimensions' in query_parms:
sub_select_clause = """
and a.id in (select distinct a.id from alarm as a
inner join alarm_metric as am on am.alarm_id
= a.id
inner join metric_definition_dimensions as mdd
on mdd.id =
am.metric_definition_dimensions_id
"""
sub_select_parms = []
i = 0
for metric_dimension in query_parms['metric_dimensions'].split(
','):
parsed_dimension = metric_dimension.split(':')
sub_select_clause += """
inner join (select distinct dimension_set_id
from metric_dimension
where name = ? and value = ?) as md{}
on md{}.dimension_set_id = mdd.metric_dimension_set_id
""".format(i, i)
i += 1
sub_select_parms += [parsed_dimension[0].encode('utf8'),
parsed_dimension[1].encode('utf8')]
sub_select_clause += ")"
parms += sub_select_parms
where_clause += sub_select_clause
query = select_clause + where_clause + order_by_clause
cnxn, cursor = self._get_cnxn_cursor_tuple()
cursor.execute(query, parms)
rows = cursor.fetchall()
self._commit_close_cnxn(cnxn)
return rows
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)

View File

@ -36,6 +36,7 @@ LOG = log.getLogger(__name__)
class AlarmDefinitions(AlarmDefinitionsV2API):
def __init__(self, global_conf):
try:
@ -52,9 +53,10 @@ class AlarmDefinitions(AlarmDefinitionsV2API):
cfg.CONF.security.default_authorized_roles + \
cfg.CONF.security.agent_authorized_roles
self._message_queue = resource_api.init_driver('monasca.messaging',
cfg.CONF.messaging.driver,
(['events']))
self._message_queue \
= resource_api.init_driver('monasca.messaging',
cfg.CONF.messaging.driver,
(['events']))
self._alarm_definitions_repo = resource_api.init_driver(
'monasca.repositories',

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
from falcon.util.uri import parse_query_string
from pyparsing import ParseException
import falcon
@ -24,7 +25,8 @@ from monasca.api.alarm_definitions_api_v2 import AlarmDefinitionsV2API
from monasca.expression_parser.alarm_expr_parser import AlarmExprParser
from monasca.openstack.common import log
from monasca.v2.reference import helpers
from monasca.v2.common.schemas import alarm_definition_request_body_schema as schema_alarms
from monasca.v2.common.schemas import \
alarm_definition_request_body_schema as schema_alarms
from monasca.v2.common.schemas import exceptions as schemas_exceptions
from monasca.v2.reference.helpers import read_json_msg_body
from monasca.common.messaging import exceptions as message_queue_exceptions
@ -34,45 +36,141 @@ LOG = log.getLogger(__name__)
class Alarms(AlarmsV2API):
def __init__(self, global_conf):
try:
super(Alarms, self).__init__(global_conf)
self._region = cfg.CONF.region
self._default_authorized_roles = cfg.CONF.security.default_authorized_roles
self._delegate_authorized_roles = cfg.CONF.security.delegate_authorized_roles
self._post_metrics_authorized_roles = cfg.CONF.security.default_authorized_roles + cfg.CONF.security.agent_authorized_roles
self._default_authorized_roles = \
cfg.CONF.security.default_authorized_roles
self._delegate_authorized_roles = \
cfg.CONF.security.delegate_authorized_roles
self._post_metrics_authorized_roles = \
cfg.CONF.security.default_authorized_roles + \
cfg.CONF.security.agent_authorized_roles
self._message_queue = resource_api.init_driver('monasca.messaging',
cfg.CONF.messaging.driver,
(['events']))
self._message_queue \
= resource_api.init_driver('monasca.messaging',
cfg.CONF.messaging.driver,
(['events']))
self._alarms_repo = resource_api.init_driver(
'monasca.repositories',
cfg.CONF.repositories.alarms_driver)
'monasca.repositories', cfg.CONF.repositories.alarms_driver)
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
@resource_api.Restify('/v2.0/alarms/{id}', method='put')
def do_put_alarms(self, req, res, id):
helpers.validate_authorization(req, self._default_authorized_roles)
result = ''
res.body = json.dumps(result, ensure_ascii=False).encode('utf8')
res.status = falcon.HTTP_200
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarms/{id}', method='patch')
def do_patch_alarms(self, req, res, id):
helpers.validate_authorization(req, self._default_authorized_roles)
result = ''
res.body = json.dumps(result, ensure_ascii=False).encode('utf8')
res.status = falcon.HTTP_200
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarms/{id}', method='delete')
def do_delete_alarms(self, req, res, id):
helpers.validate_authorization(req, self._default_authorized_roles)
result = ''
res.body = json.dumps(result, ensure_ascii=False).encode('utf8')
res.status = falcon.HTTP_200
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarms/', method='get')
def do_get_alarms(self, req, res, id):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarms', method='get')
def do_get_alarms(self, req, res):
helpers.validate_authorization(req, self._default_authorized_roles)
tenant_id = helpers.get_tenant_id(req)
query_parms = parse_query_string(req.query_string)
result = self._alarm_list(req.uri, tenant_id, query_parms)
res.body = json.dumps(result, ensure_ascii=False).encode('utf8')
res.status = falcon.HTTP_200
@resource_api.Restify('/v2.0/alarms/{id}', method='get')
def do_get_alarm_by_id(self, req, res, id):
helpers.validate_authorization(req, self._default_authorized_roles)
result = ''
res.body = json.dumps(result, ensure_ascii=False).encode('utf8')
res.status = falcon.HTTP_200
res.status = '501 Not Implemented'
def _alarm_list(self, req_uri, tenant_id, query_parms):
try:
alarm_rows = self._alarms_repo.get_alarms(tenant_id, query_parms)
result = []
if not alarm_rows:
return result
prev_alarm_id = None
for alarm_row in alarm_rows:
if prev_alarm_id != alarm_row.alarm_id:
if prev_alarm_id is not None:
result.append(a)
ad = {u'id': alarm_row.alarm_definition_id,
u'name': alarm_row.alarm_definition_name,
u'severity': alarm_row.severity,
}
helpers.add_links_to_resource(ad, req_uri)
metrics = []
a = {
u'id': alarm_row.alarm_id,
u'metrics': metrics,
u'state': alarm_row.state,
u'alarm_definition': ad
}
helpers.add_links_to_resource(a, req_uri)
prev_alarm_id = alarm_row.alarm_id
dimensions = {}
metric = {u'name': alarm_row.metric_name,
u'dimensions': dimensions}
if alarm_row.metric_dimensions:
for dimension in alarm_row.metric_dimensions.split(','):
parsed_dimension = dimension.split('=')
dimensions[parsed_dimension[0]] = parsed_dimension[1]
metrics.append(metric)
result.append(a)
return result
except exceptions.RepositoryException as ex:
LOG.exception(ex)
msg = "".join(ex.message.args)
raise falcon.HTTPInternalServerError('Service unavailable', msg)
except Exception as ex:
LOG.exception(ex)
raise falcon.HTTPInternalServerError('Service unavailable', ex)

View File

@ -40,6 +40,9 @@ monasca.metrics_dispatcher =
monasca.alarm_definitions_dispatcher =
v2_reference = monasca.v2.reference.alarm_definitions:AlarmDefinitions
monasca.alarms_dispatcher =
v2_reference = monasca.v2.reference.alarms:Alarms
monasca.events_dispatcher =
v2_reference = monasca.v2.reference.events:Events