Notifications resource support, helpers.py link functions

Change-Id: I09e69529fe1cd09f824b837887251921f060f640
This commit is contained in:
cindy oneill 2014-10-22 17:29:36 -06:00
parent c6802b8816
commit 4c585dc46e
11 changed files with 637 additions and 89 deletions

View File

@ -39,6 +39,9 @@ events_driver = none
# The driver to use for the transforms repository
transforms_driver = mysql_transforms_repo
# The driver to use for the notifications repository
notifications_driver = mysql_notifications_repo
[dispatcher]
driver = v2_reference

View File

@ -46,33 +46,17 @@ class V2API(object):
def do_get_statistics(self, req, res):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods', method='post')
def do_post_notification_methods(self, req, res):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods/{id}', method='put')
def do_put_notification_methods(self, req, res, id):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods/{id}', method='delete')
def do_delete_notification_methods(self, req, res, id):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods/{id}', method='get')
def do_get_notification_methods(self, req, res, id):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarm-definitions', method='post')
def do_post_alarm_definitions(self, req, res):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarm-definitions/{id}', method='get')
def do_get_alarm_definition(self, req, res, id):
res.status = '501 Not Implemented'
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarm-definitions/{id}', method='put')
def do_put_alarm_definitions(self, req, res, id):
res.status = '501 Not Implemented'
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/alarm-definitions', method='get')
def do_get_alarm_definitions(self, req, res):
@ -112,4 +96,4 @@ class V2API(object):
@resource_api.Restify('/v2.0/alarms/{id}/state-history', method='get')
def do_get_alarm_state_history(self, req, res, id):
res.status = '501 Not Implemented'
res.status = '501 Not Implemented'

View File

@ -0,0 +1,46 @@
# Copyright 2014 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 import resource_api
from monasca.openstack.common import log
LOG = log.getLogger(__name__)
class NotificationsV2API(object):
def __init__(self, global_conf):
LOG.debug('initializing V2API!')
self.global_conf = global_conf
@resource_api.Restify('/v2.0/notification-methods', method='post')
def do_post_notification_methods(self, req, res):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods/{id}', method='delete')
def do_delete_notification_methods(self, req, res, id):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods', method='get')
def do_get_notification_methods(self, req, res):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods/{id}', method='get')
def do_get_notification_method(self, req, res, id):
res.status = '501 Not Implemented'
@resource_api.Restify('/v2.0/notification-methods/{id}', method='put')
def do_put_notification_methods(self, req, res, id):
res.status = '501 Not Implemented'

View File

@ -26,6 +26,7 @@ from wsgiref import simple_server
METRICS_DISPATCHER_NAMESPACE = 'monasca.metrics_dispatcher'
EVENTS_DISPATCHER_NAMESPACE = 'monasca.events_dispatcher'
TRANSFORMS_DISPATCHER_NAMESPACE = 'monasca.transforms_dispatcher'
NOTIFICATIONS_DISPATCHER_NAMESPACE = 'monasca.notifications_dispatcher'
LOG = log.getLogger(__name__)
@ -63,7 +64,8 @@ cfg.CONF.register_opts(messaging_opts, messaging_group)
repositories_opts = [
cfg.StrOpt('metrics_driver', default='influxdb_metrics_repo', help='The repository driver to use for metrics'),
cfg.StrOpt('events_driver', default='fake_events_repo', help='The repository driver to use for events'),
cfg.StrOpt('transforms_driver', default='mysql_transforms_repo', help='The repository driver to use for transforms')
cfg.StrOpt('transforms_driver', default='mysql_transforms_repo', help='The repository driver to use for transforms'),
cfg.StrOpt('notifications_driver', default='mysql_notifications_repo', help='The repository driver to use for notifications')
]
repositories_group = cfg.OptGroup(name='repositories', title='repositories')
@ -161,45 +163,21 @@ def api_app(conf):
# Create the application
app = resource_api.ResourceAPI()
# load the metrics driver specified by dispatcher in the monasca.ini file
metrics_manager = driver.DriverManager(namespace=METRICS_DISPATCHER_NAMESPACE,
name=cfg.CONF.dispatcher.driver,
invoke_on_load=True,
invoke_args=[conf])
# add the metrics resource
app.add_resource('metrics', METRICS_DISPATCHER_NAMESPACE,
cfg.CONF.dispatcher.driver, [conf])
LOG.debug('Metrics dispatcher driver %s is loaded.' % cfg.CONF.dispatcher.driver)
# add the events resource
app.add_resource('events', EVENTS_DISPATCHER_NAMESPACE,
cfg.CONF.dispatcher.driver, [conf])
# add the driver to the application
app.add_route(None, metrics_manager.driver)
# add the transforms resource
app.add_resource('transforms', TRANSFORMS_DISPATCHER_NAMESPACE,
cfg.CONF.dispatcher.driver, [conf])
LOG.debug('Metrics dispatcher driver has been added to the routes!')
# load the events driver specified by dispatcher in the monasca.ini file
events_manager = driver.DriverManager(namespace=EVENTS_DISPATCHER_NAMESPACE,
name=cfg.CONF.dispatcher.driver,
invoke_on_load=True,
invoke_args=[conf])
LOG.debug('Events dispatcher driver %s is loaded.' % cfg.CONF.dispatcher.driver)
# add the driver to the application
app.add_route(None, events_manager.driver)
LOG.debug('Events dispatcher driver has been added to the routes!')
# load the events driver specified by dispatcher in the monasca.ini file
transforms_manager = driver.DriverManager(namespace=TRANSFORMS_DISPATCHER_NAMESPACE,
name=cfg.CONF.dispatcher.driver,
invoke_on_load=True,
invoke_args=[conf])
LOG.debug('Transforms dispatcher driver %s is loaded.' % cfg.CONF.dispatcher.driver)
# add the driver to the application
app.add_route(None, transforms_manager.driver)
LOG.debug('Transforms dispatcher driver has been added to the routes!')
# add the notifications resource
app.add_resource('notifications', NOTIFICATIONS_DISPATCHER_NAMESPACE,
cfg.CONF.dispatcher.driver, [conf])
return app
@ -207,4 +185,4 @@ def api_app(conf):
if __name__ == '__main__':
wsgi_app = loadapp('config:etc/monasca.ini', relative_to=os.getcwd())
httpd = simple_server.make_server('127.0.0.1', 9000, wsgi_app)
httpd.serve_forever()
httpd.serve_forever()

View File

@ -0,0 +1,133 @@
# Copyright 2014 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.
import datetime
from monasca.common.repositories import notifications_repository
from monasca.common.repositories import exceptions
from monasca.openstack.common import log
import peewee
import model
LOG = log.getLogger(__name__)
class Notification_Method(model.Model):
id = peewee.TextField(36)
tenant_id = peewee.TextField(36)
name = peewee.TextField()
type = peewee.TextField()
address = peewee.TextField()
created_at = peewee.DateTimeField()
updated_at = peewee.DateTimeField()
class NotificationsRepository(
notifications_repository.NotificationsRepository):
def notification_from_result(self, result):
notification = dict(id=result.id,
name=result.name,
type=result.type,
address=result.address)
return notification
def exists(self, tenant_id, name):
try:
return (Notification_Method.select().where(
(Notification_Method.tenant_id == tenant_id) & (
Notification_Method.name == name)).count() > 0)
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
def create_notification(
self, id, tenant_id, name, notification_type, address):
try:
now = datetime.datetime.utcnow()
q = Notification_Method.create(
id=id,
tenant_id=tenant_id,
name=name,
notification_type=notification_type,
address=address,
created_at=now,
updated_at=now)
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
def list_notifications(self, tenant_id):
try:
q = Notification_Method.select().where(
Notification_Method.tenant_id == tenant_id)
results = q.execute()
notifications = []
notifications = [
self.notification_from_result(result) for result in results]
return notifications
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
def delete_notification(self, tenant_id, notification_id):
num_rows_deleted = 0
try:
q = Notification_Method.delete().where(
(Notification_Method.tenant_id == tenant_id) & (
Notification_Method.id == notification_id))
num_rows_deleted = q.execute()
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
if num_rows_deleted < 1:
raise exceptions.DoesNotExistException()
return
def list_notification(self, tenant_id, notification_id):
try:
result = Notification_Method.get(
(Notification_Method.tenant_id == tenant_id) & (
Notification_Method.id == notification_id))
return (self.notification_from_result(result))
except Notification_Method.DoesNotExist as e:
raise exceptions.DoesNotExistException(str(e))
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
def update_notification(
self, id, tenant_id, name, notification_type, address):
now = datetime.datetime.utcnow()
num_rows_updated = 0
try:
q = Notification_Method.update(
name=name,
type=notification_type,
address=address,
created_at=now,
updated_at=now).where(
(Notification_Method.tenant_id == tenant_id) & (
Notification_Method.id == id))
# Execute the query, updating the database.
num_rows_updated = q.execute()
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
else:
if num_rows_updated == 0:
raise exceptions.DoesNotExistException('Not Found')

View File

@ -0,0 +1,42 @@
# Copyright 2014 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.
import abc
import six
@six.add_metaclass(abc.ABCMeta)
class NotificationsRepository(object):
@abc.abstractmethod
def create_notification(self, id, tenant_id, name, notification_type,
address):
return
@abc.abstractmethod
def list_notifications(self, tenant_id):
return
@abc.abstractmethod
def delete_notification(self, tenant_id, notification_id):
return
@abc.abstractmethod
def list_notification(self, tenant_id, notification_id):
return
@abc.abstractmethod
def update_notification(self, id, tenant_id, name, notification_type,
address):
return

View File

@ -18,13 +18,32 @@ import falcon
from falcon import api_helpers
from monasca.openstack.common import log
from stevedore import driver
RESOURCE_METHOD_FLAG = 'fab05a04-b861-4651-bd0c-9cb3eb9a6088'
LOG = log.getLogger(__name__)
def init_driver(namespace, driver_name, drv_invoke_args=None):
"""Initialize the resource driver and returns it.
:param namespace: the resource namespace (in setup.cfg).
:param driver_name: the driver name (in monasca.conf)
:param invoke_args: args to pass to the driver (a tuple)
"""
invoke_args_tuple = ()
if drv_invoke_args:
invoke_args_tuple = drv_invoke_args
mgr = driver.DriverManager(
namespace = namespace,
name = driver_name,
invoke_on_load = True,
invoke_args = invoke_args_tuple
)
return mgr.driver
class Restify(object):
def __init__(self, path='', method='GET'):
if not path:
@ -41,7 +60,6 @@ class Restify(object):
class ResourceAPI(falcon.API):
def add_route(self, uri_template, resource):
"""Associates uri patterns with resource methods.
@ -114,4 +132,21 @@ class ResourceAPI(falcon.API):
path_maps[item][1]))
except Exception:
LOG.exception('Error occurred while adding the resource')
LOG.debug(self._routes)
LOG.debug(self._routes)
def add_resource(self, resource_name, namespace, driver_name,
invoke_args=None, uri=None):
"""Loads the resource driver, and adds it to the routes.
:param resource_name: the name of the resource.
:param namespace: the resource namespace (in setup.cfg).
:param driver_name: the driver name (in monasca.conf)
:param invoke_args: args to pass to the driver (a tuple)
:param uri: the uri to associate with the resource
"""
resource_driver = init_driver(namespace, driver_name, invoke_args)
LOG.debug('%s dispatcher driver %s is loaded.' %
(resource_name, driver_name))
self.add_route(uri, resource_driver)
LOG.debug('%s dispatcher driver has been added to the routes!' %
(resource_name))

View File

@ -0,0 +1,36 @@
# Copyright 2014 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 voluptuous import Schema
from voluptuous import Optional, Required, Any, All, Length
from monasca.openstack.common import log
from monasca.v2.common.schemas import exceptions
LOG = log.getLogger(__name__)
notification_schema = {
Required('name'): Schema(All(Any(str, unicode), Length(max=250))),
Required('type'): Schema(Any("EMAIL", "email")),
Required('address'): Schema(All(Any(str, unicode), Length(max=100)))
}
request_body_schema = Schema(Any(notification_schema))
def validate(msg):
try:
request_body_schema(msg)
except Exception as ex:
LOG.debug(ex)
raise exceptions.ValidationException(str(ex))

View File

@ -20,7 +20,7 @@ from monasca.openstack.common import log
from monasca.v2.common.schemas import exceptions as schemas_exceptions
from monasca.v2.common.schemas import metric_name_schema
from monasca.v2.common.schemas import dimensions_schema
import simplejson
LOG = log.getLogger(__name__)
@ -32,16 +32,16 @@ def validate_json_content_type(req):
def is_in_role(req, authorized_roles):
'''
Determines if one or more of the X-ROLES is in the supplied
"""Determines if one or more of the X-ROLES is in the supplied
authorized_roles.
:param req: HTTP request object. Must contain "X-ROLES" in the HTTP
request header.
:param authorized_roles: List of authorized roles to check against.
:return: Returns True if in the list of authorized roles, otherwise False.
'''
"""
str_roles = req.get_header('X-ROLES')
if str_roles == None:
if str_roles is None:
return False
roles = str_roles.lower().split(',')
for role in roles:
@ -51,15 +51,15 @@ def is_in_role(req, authorized_roles):
def validate_authorization(req, authorized_roles):
'''
Validates whether one or more X-ROLES in the HTTP header is authorized.
"""Validates whether one or more X-ROLES in the HTTP header is authorized.
:param req: HTTP request object. Must contain "X-ROLES" in the HTTP
request header.
:param authorized_roles: List of authorized roles to check against.
:raises falcon.HTTPUnauthorized:
'''
:raises falcon.HTTPUnauthorized
"""
str_roles = req.get_header('X-ROLES')
if str_roles == None:
if str_roles is None:
raise falcon.HTTPUnauthorized('Forbidden',
'Tenant does not have any roles', '')
roles = str_roles.lower().split(',')
@ -72,21 +72,21 @@ def validate_authorization(req, authorized_roles):
def get_tenant_id(req):
'''
Returns the tenant ID in the HTTP request header.
"""Returns the tenant ID in the HTTP request header.
:param req: HTTP request object.
'''
"""
return req.get_header('X-TENANT-ID')
def get_cross_tenant_or_tenant_id(req, delegate_authorized_roles):
'''
Evaluates whether the tenant ID or cross tenant ID should be returned.
"""Evaluates whether the tenant ID or cross tenant ID should be returned.
:param req: HTTP request object.
:param delegate_authorized_roles: List of authorized roles that have
delegate privileges.
:returns: Returns the cross tenant or tenant ID.
'''
"""
if is_in_role(req, delegate_authorized_roles):
params = parse_query_string(req.query_string)
if 'tenant_id' in params:
@ -96,10 +96,10 @@ def get_cross_tenant_or_tenant_id(req, delegate_authorized_roles):
def get_query_name(req):
'''
Returns the query param "name" if supplied.
"""Returns the query param "name" if supplied.
:param req: HTTP request object.
'''
"""
params = parse_query_string(req.query_string)
name = ''
if 'name' in params:
@ -108,12 +108,12 @@ def get_query_name(req):
def get_query_dimensions(req):
'''
Gets and parses the query param dimensions.
"""Gets and parses the query param dimensions.
:param req: HTTP request object.
:return: Returns the dimensions as a JSON object
:raises falcon.HTTPBadRequest: If dimensions are malformed.
'''
"""
try:
params = parse_query_string(req.query_string)
dimensions = {}
@ -193,11 +193,11 @@ def get_query_period(req):
def validate_query_name(name):
'''
Validates the query param name.
"""Validates the query param name.
:param name: Query param name.
:raises falcon.HTTPBadRequest: If name is not valid.
'''
"""
try:
metric_name_schema.validate(name)
except schemas_exceptions.ValidationException as ex:
@ -206,13 +206,77 @@ def validate_query_name(name):
def validate_query_dimensions(dimensions):
'''
Validates the query param dimensions.
"""Validates the query param dimensions.
:param dimensions: Query param dimensions.
:raises falcon.HTTPBadRequest: If dimensions are not valid.
'''
"""
try:
dimensions_schema.validate(dimensions)
except schemas_exceptions.ValidationException as ex:
LOG.debug(ex)
raise falcon.HTTPBadRequest('Bad request', ex.message)
raise falcon.HTTPBadRequest('Bad request', ex.message)
def get_link(uri, resource_id, rel='self'):
"""Returns a link dictionary containing href, and rel.
:param uri: the http request.uri.
:param resource_id: the id of the resource
"""
href = uri + '/' + resource_id
link_dict = dict(href=href, rel=rel)
return link_dict
def add_links_to_resource(resource, uri):
"""Adds links to the given resource dictionary.
:param resource: the resource dictionary you wish to add links.
:param uri: the http request.uri.
"""
resource['links'] = [get_link(uri, resource['id'])]
return resource
def add_links_to_resource_list(resourcelist, uri):
"""Adds links to the given resource dictionary list.
:param resourcelist: the list of resources you wish to add links.
:param uri: the http request.uri.
"""
for resource in resourcelist:
add_links_to_resource(resource, uri)
return resourcelist
def read_http_resource(req):
"""Read from http request and return json.
:param req: the http request.
"""
try:
msg = req.stream.read()
json_msg = simplejson.loads(msg)
return json_msg
except ValueError as ex:
LOG.debug(ex)
raise falcon.HTTPBadRequest(
'Bad request',
'Request body is not valid JSON')
def raise_not_found_exception(resource_name, resource_id, tenant_id):
"""Provides exception for not found requests (update, delete, list).
:param resource_name: the name of the resource.
:param resource_id: id of the resource.
:param tenant_id: id of the tenant
"""
msg = 'No %s method exists for tenant_id = %s id = %s' % (
resource_name, tenant_id, resource_id)
raise falcon.HTTPError(
status='404 Not Found',
title='Not Found',
description=msg,
code=404)

View File

@ -0,0 +1,223 @@
# Copyright 2014 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.
# TODO: Used simplejson to read the yaml as simplejson transforms to "str"
# not "unicode"
import json
import falcon
from oslo.config import cfg
from monasca.openstack.common import log
from monasca.openstack.common import uuidutils
from monasca.api import monasca_notifications_api_v2
from monasca.common import resource_api
from monasca.common.repositories import exceptions as repository_exceptions
from monasca.v2.common.schemas import exceptions as schemas_exceptions
from monasca.v2.common.schemas import notifications_request_body_schema as schemas_notifications
from monasca.v2.reference import helpers
LOG = log.getLogger(__name__)
class Notifications(monasca_notifications_api_v2.NotificationsV2API):
def __init__(self, global_conf):
super(Notifications, self).__init__(global_conf)
self._region = cfg.CONF.region
self._default_authorized_roles = cfg.CONF.security.default_authorized_roles
self._notifications_repo = resource_api.init_driver('monasca.repositories',
cfg.CONF.repositories.notifications_driver)
def _validate_notification(self, notification):
"""Validates the notification
:param notification: An event object.
:raises falcon.HTTPBadRequest
"""
try:
schemas_notifications.validate(notification)
except schemas_exceptions.ValidationException as ex:
LOG.debug(ex)
raise falcon.HTTPBadRequest('Bad request', ex.message)
def _create_notification(self, id, tenant_id, notification):
"""Store the notification using the repository.
:param notification: A notification object.
:raises: falcon.HTTPServiceUnavailable,falcon.HTTPConflict
"""
try:
name = notification['name']
notification_type = notification['type'].upper()
address = notification['address']
if self._notifications_repo.exists(tenant_id, name):
raise falcon.HTTPConflict(
'Conflict', ('Notification Method already exists: tenant_id=%s name=%s' %
(tenant_id, name)), code=409)
self._notifications_repo.create_notification(
id,
tenant_id,
name,
notification_type,
address)
except repository_exceptions.RepositoryException as ex:
LOG.error(ex)
raise falcon.HTTPInternalServerError(
'Service unavailable',
ex.message)
def _update_notification(self, id, tenant_id, notification):
"""Update the notification using the repository.
:param notification: A notification object.
:raises: falcon.HTTPServiceUnavailable,falcon.HTTPError (404)
"""
try:
name = notification['name']
notification_type = notification['type'].upper()
address = notification['address']
self._notifications_repo.update_notification(
id,
tenant_id,
name,
notification_type,
address)
except repository_exceptions.DoesNotExistException:
helpers.raise_not_found_exception('notification', id, tenant_id)
except repository_exceptions.RepositoryException as ex:
LOG.error(ex)
raise falcon.HTTPInternalServerError(
'Service unavailable',
ex.message)
def _create_notification_response(self, id, notification, uri):
name = notification['name']
notification_type = notification['type'].upper()
address = notification['address']
response = {
'id': id,
'name': name,
'type': notification_type,
'address': address
}
return json.dumps(helpers.add_links_to_resource(response, uri))
def _list_notifications(self, tenant_id, uri):
"""Lists all notifications for this tenant id.
:param tenant_id: The tenant id.
:raises: falcon.HTTPServiceUnavailable
"""
try:
notifications = self._notifications_repo.list_notifications(
tenant_id)
return json.dumps(
helpers.add_links_to_resource_list(notifications, uri))
except repository_exceptions.RepositoryException as ex:
LOG.error(ex)
raise falcon.HTTPInternalServerError(
'Service unavailable',
ex.message)
def _list_notification(self, tenant_id, notification_id, uri):
"""Lists the notification by id.
:param tenant_id: The tenant id.
:param notification_id: The notification id
:raises: falcon.HTTPServiceUnavailable,falcon.HTTPError (404):
"""
try:
notifications = self._notifications_repo.list_notification(
tenant_id,
notification_id)
return json.dumps(
helpers.add_links_to_resource(notifications, uri))
except repository_exceptions.DoesNotExistException:
helpers.raise_not_found_exception('notification', notification_id, tenant_id)
except repository_exceptions.RepositoryException as ex:
LOG.error(ex)
raise falcon.HTTPInternalServerError(
'Service unavailable',
ex.message)
def _delete_notification(self, tenant_id, notification_id):
"""Deletes the notification using the repository.
:param tenant_id: The tenant id.
:param notification_id: The notification id
:raises: falcon.HTTPServiceUnavailable,falcon.HTTPError (404)
"""
try:
self._notifications_repo.delete_notification(
tenant_id,
notification_id)
except repository_exceptions.DoesNotExistException:
helpers.raise_not_found_exception('notification', notification_id, tenant_id)
except repository_exceptions.RepositoryException as ex:
LOG.error(ex)
raise falcon.HTTPInternalServerError(
'Service unavailable',
ex.message)
@resource_api.Restify('/v2.0/notification-methods', method='post')
def do_post_notification_methods(self, req, res):
helpers.validate_json_content_type(req)
helpers.validate_authorization(req, self._default_authorized_roles)
notification = helpers.read_http_resource(req)
self._validate_notification(notification)
id = uuidutils.generate_uuid()
tenant_id = helpers.get_tenant_id(req)
self._create_notification(id, tenant_id, notification)
res.body = self._create_notification_response(
id,
notification,
req.uri)
res.status = falcon.HTTP_200
@resource_api.Restify('/v2.0/notification-methods', method='get')
def do_get_notification_methods(self, req, res):
helpers.validate_authorization(req, self._default_authorized_roles)
tenant_id = helpers.get_tenant_id(req)
res.body = self._list_notifications(tenant_id, req.uri)
res.status = falcon.HTTP_200
@resource_api.Restify('/v2.0/notification-methods/{id}', method='delete')
def do_delete_notification_methods(self, req, res, id):
helpers.validate_authorization(req, self._default_authorized_roles)
tenant_id = helpers.get_tenant_id(req)
self._delete_notification(tenant_id, id)
res.status = falcon.HTTP_204
@resource_api.Restify('/v2.0/notification-methods/{id}', method='get')
def do_get_notification_method(self, req, res, id):
helpers.validate_authorization(req, self._default_authorized_roles)
tenant_id = helpers.get_tenant_id(req)
res.body = self._list_notification(tenant_id, id, req.uri)
res.status = falcon.HTTP_200
@resource_api.Restify('/v2.0/notification-methods/{id}', method='put')
def do_put_notification_methods(self, req, res, id):
helpers.validate_json_content_type(req)
helpers.validate_authorization(req, self._default_authorized_roles)
notification = helpers.read_http_resource(req)
self._validate_notification(notification)
tenant_id = helpers.get_tenant_id(req)
self._update_notification(id, tenant_id, notification)
res.body = self._create_notification_response(
id,
notification,
req.uri)
res.status = falcon.HTTP_200

View File

@ -43,6 +43,9 @@ monasca.events_dispatcher =
monasca.transforms_dispatcher =
v2_reference = monasca.v2.reference.transforms:Transforms
monasca.notifications_dispatcher =
v2_reference = monasca.v2.reference.notifications:Notifications
paste.filter_factory =
login = monasca.middleware.login:filter_factory
inspector = monasca.middleware.inspector:filter_factory
@ -59,6 +62,7 @@ monasca.repositories =
influxdb_metrics_repo = monasca.common.repositories.influxdb.metrics_repository:MetricsRepository
fake_events_repo = monasca.common.repositories.fake.events_repository:EventsRepository
mysql_transforms_repo = monasca.common.repositories.mysql.transforms_repository:TransformsRepository
mysql_notifications_repo = monasca.common.repositories.mysql.notifications_repository:NotificationsRepository
[pbr]
warnerrors = True