[Kimchi-devel] [PATCH] [Wok] Implement Asynchronous Notifications backend
Lucio Correia
luciojhc at linux.vnet.ibm.com
Mon Mar 28 17:35:47 UTC 2016
On 28-03-2016 13:23, Paulo Ricardo Paz Vital wrote:
>
>
> On 03/28/2016 11:33 AM, Lucio Correia wrote:
>> * There is no POST method: a notification is
>> added through add_notification() method.
>> * Notifications are always stored in Wok object store under
>> 'notification' type, even if added by a plugin.
>> * Every time Wok is started, all notifications are erased,
>> since this is a UI feature, intended to be showed to the
>> user asynchronously, independent of which tab is opened.
>>
>> Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
>> ---
>> docs/API/notifications.md | 33 ++++++++++++++++++++++++++++
>> src/wok/control/notifications.py | 39 +++++++++++++++++++++++++++++++++
>> src/wok/i18n.py | 2 ++
>> src/wok/model/notifications.py | 47 ++++++++++++++++++++++++++++++++++++++++
>> src/wok/objectstore.py | 20 +++++++++++++++++
>> src/wok/server.py | 4 ++++
>> 6 files changed, 145 insertions(+)
>> create mode 100644 docs/API/notifications.md
>> create mode 100644 src/wok/control/notifications.py
>> create mode 100644 src/wok/model/notifications.py
>>
>> IMPORTANT: This patch depends on WokMessage patch.
>>
>>
>> diff --git a/docs/API/notifications.md b/docs/API/notifications.md
>> new file mode 100644
>> index 0000000..fb0e691
>> --- /dev/null
>> +++ b/docs/API/notifications.md
>> @@ -0,0 +1,33 @@
>> +## REST API Specification for Notifications
>> +
>> +### Collection: Notifications
>> +
>> +**URI:** /notifications
>> +
>> +**Methods:**
>> +
>> +* **GET**: Retrieve a summarized list of current Notifications
>> +
>> +#### Examples
>> +GET /notifications
>> +[{Notification1}, {Notification2}, ...]
>> +
>> +### Resource: Notification
>> +
>> +**URI:** /notifications/*:id*
>> +
>> +A task represents an asynchronous operation that is being performed by the
>> +server.
>> +
>> +**Methods:**
>> +
>> +* **GET**: Retrieve the full description of the Notification
>> + * code: message ID
>> + * message: message text already translated
>> +
>> +#### Examples
>> +GET /notifications/KCHLIBVIRT0001W
>> +{
>> + id: "KCHLIBVIRT0001W",
>> + message: "KCHLIBVIRT0001W: Lack of storage space in guest vm-1",
>> +}
>> diff --git a/src/wok/control/notifications.py b/src/wok/control/notifications.py
>> new file mode 100644
>> index 0000000..4e6d8d9
>> --- /dev/null
>> +++ b/src/wok/control/notifications.py
>> @@ -0,0 +1,39 @@
>> +#
>> +# Project Wok
>> +#
>> +# Copyright IBM Corp, 2016
>> +#
>> +# Code derived from Project Kimchi
>
> Was it???? ^^
Yes, most of this code was part of WokException class. The problem here
is that Copyright year should be 2015-2016, but the script will change
it back to 2016 since it's a new file.
>
>> +#
>> +# This library is free software; you can redistribute it and/or
>> +# modify it under the terms of the GNU Lesser General Public
>> +# License as published by the Free Software Foundation; either
>> +# version 2.1 of the License, or (at your option) any later version.
>> +#
>> +# This library is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> +# Lesser General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU Lesser General Public
>> +# License along with this library; if not, write to the Free Software
>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> +
>> +from wok.control.base import Collection, Resource
>> +from wok.control.utils import UrlSubNode
>> +
>> +
>> + at UrlSubNode('notifications', True)
>> +class Notifications(Collection):
>> + def __init__(self, model):
>> + super(Notifications, self).__init__(model)
>> + self.resource = Notification
>> +
>> +
>> +class Notification(Resource):
>> + def __init__(self, model, id):
>> + super(Notification, self).__init__(model, id)
>> +
>> + @property
>> + def data(self):
>> + return self.info
>> diff --git a/src/wok/i18n.py b/src/wok/i18n.py
>> index e6087f4..1bc92e3 100644
>> --- a/src/wok/i18n.py
>> +++ b/src/wok/i18n.py
>> @@ -45,6 +45,8 @@ messages = {
>> "WOKLOG0001E": _("Invalid filter parameter. Filter parameters allowed: %(filters)s"),
>> "WOKLOG0002E": _("Creation of log file failed: %(err)s"),
>>
>> + "WOKNOT0001E": _("Unable to find notification %(id)s"),
>> +
>> "WOKOBJST0001E": _("Unable to find %(item)s in datastore"),
>>
>> "WOKUTILS0001E": _("Unable to reach %(url)s. Make sure it is accessible and try again."),
>> diff --git a/src/wok/model/notifications.py b/src/wok/model/notifications.py
>> new file mode 100644
>> index 0000000..7158571
>> --- /dev/null
>> +++ b/src/wok/model/notifications.py
>> @@ -0,0 +1,47 @@
>> +#
>> +# Project Wok
>> +#
>> +# Copyright IBM Corp, 2016
>> +#
>> +# This library is free software; you can redistribute it and/or
>> +# modify it under the terms of the GNU Lesser General Public
>> +# License as published by the Free Software Foundation; either
>> +# version 2.1 of the License, or (at your option) any later version.
>> +#
>> +# This library is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> +# Lesser General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU Lesser General Public
>> +# License along with this library; if not, write to the Free Software
>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> +
>> +from wok.exception import NotFoundError
>> +from wok.message import WokMessage
>> +
>> +
>> +class NotificationsModel(object):
>> + def __init__(self, **kargs):
>> + self.objstore = kargs['objstore']
>> +
>> + def get_list(self):
>> + with self.objstore as session:
>> + return session.get_list('notification')
>> +
>> +
>> +class NotificationModel(object):
>> + def __init__(self, **kargs):
>> + self.objstore = kargs['objstore']
>> +
>> + def lookup(self, id):
>> + with self.objstore as session:
>> + notification = session.get('notification', str(id))
>> +
>> + # use WokMessage to translate the notification
>> + if notification:
>> + plugin = notification.pop('_plugin_name', None)
>> + message = WokMessage(id, notification, plugin).get_text()
>> + return {"code": id, "message": message}
>> +
>> + raise NotFoundError("WOKNOT0001E", {'id': str(id)})
>> diff --git a/src/wok/objectstore.py b/src/wok/objectstore.py
>> index 59354f3..2bae30b 100644
>> --- a/src/wok/objectstore.py
>> +++ b/src/wok/objectstore.py
>> @@ -144,3 +144,23 @@ class ObjectStore(object):
>> # exception again
>> wok_log.error(traceback.format_exc())
>> return False
>> +
>> +
>> +def add_notification(code="", args={}, plugin_name=None):
>> + try:
>> + args.update({"_plugin_name": plugin_name})
>> +
>> + with ObjectStore() as session:
>> + session.store('notification', code, args)
>
> Question. If I call in my code add_notification(), exactly like I wrote
> without arguments, I'll get and "empty" entry on my objectstore file
> (only with notification and _plugin_name=None) ?
Yes, I believe we should make 'code' a required parameter, this way no
empty message is added as notification. Good catch, I will send it in V2.
>
>> + except Exception as e:
>> + wok_log.error("Unable to generate notification: %s" % e.message)
>> +
>> +
>> +def clean_notifications():
>> + try:
>> + with ObjectStore() as session:
>> + notifications = session.get_list('notification')
>> + for item in notifications:
>> + session.delete('notification', item)
>> + except Exception as e:
>> + wok_log.error("Unable to clean notifications: %s" % e.message)
>> diff --git a/src/wok/server.py b/src/wok/server.py
>> index 902d4bf..a329ed4 100644
>> --- a/src/wok/server.py
>> +++ b/src/wok/server.py
>> @@ -33,6 +33,7 @@ from wok.config import config as configParser
>> from wok.config import paths, PluginConfig, WokConfig
>> from wok.control import sub_nodes
>> from wok.model import model
>> +from wok.objectstore import clean_notifications
>> from wok.proxy import start_proxy, terminate_proxy
>> from wok.reqlogger import RequestLogger
>> from wok.root import WokRoot
>> @@ -106,6 +107,9 @@ class Server(object):
>> if dev_env:
>> cherrypy.log.screen = True
>>
>> + # clean object store notifications
>> + clean_notifications()
>> +
>> # close standard file handlers because we are going to use a
>> # watchedfiled handler, otherwise we will have two file handlers
>> # pointing to the same file, duplicating log enries
>>
>
> _______________________________________________
> Kimchi-devel mailing list
> Kimchi-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>
--
Lucio Correia
Software Engineer
IBM LTC Brazil
More information about the Kimchi-devel
mailing list