rest_dbus: add new route for event subscription

Add a route, '/subscribe', to be able to receive notifications from the
REST server over a websocket.

A client is supposed to create a new websocket by pointing to this route
in the URL. In this commit, the implementation of the route is to just
write a "Connected" message on the websocket.

Change-Id: I38a40b2c17eac3ecdccb131d267baefe20b36572
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/module/obmc/wsgi/apps/rest_dbus.py b/module/obmc/wsgi/apps/rest_dbus.py
index c3c42ef..1ad359c 100644
--- a/module/obmc/wsgi/apps/rest_dbus.py
+++ b/module/obmc/wsgi/apps/rest_dbus.py
@@ -719,6 +719,30 @@
         pass
 
 
+class EventHandler(RouteHandler):
+    ''' Handles the /subscribe route, for clients to be able
+        to subscribe to BMC events. '''
+
+    verbs = ['GET']
+    rules = ['/subscribe']
+
+    def __init__(self, app, bus):
+        super(EventHandler, self).__init__(
+            app, bus, self.verbs, self.rules)
+
+    def find(self, **kw):
+        pass
+
+    def setup(self, **kw):
+        pass
+
+    def do_get(self):
+        wsock = request.environ.get('wsgi.websocket')
+        if not wsock:
+            abort(400, 'Expected WebSocket request.')
+        wsock.send("Connected")
+
+
 class ImagePutHandler(RouteHandler):
     ''' Handles the /upload/image/<filename> route. '''
 
@@ -1047,6 +1071,9 @@
 class App(Bottle):
     def __init__(self, **kw):
         super(App, self).__init__(autojson=False)
+
+        self.have_wsock = kw.get('have_wsock', False)
+
         self.bus = dbus.SystemBus()
         self.mapper = obmc.mapper.Mapper(self.bus)
         self.error_callbacks = []
@@ -1090,6 +1117,8 @@
         self.image_upload_post_handler = ImagePostHandler(self, self.bus)
         self.image_upload_put_handler = ImagePutHandler(self, self.bus)
         self.download_dump_get_handler = DownloadDumpHandler(self, self.bus)
+        if self.have_wsock:
+            self.event_handler = EventHandler(self, self.bus)
         self.instance_handler = InstanceHandler(self, self.bus)
 
     def install_handlers(self):
@@ -1103,6 +1132,8 @@
         self.image_upload_post_handler.install()
         self.image_upload_put_handler.install()
         self.download_dump_get_handler.install()
+        if self.have_wsock:
+            self.event_handler.install()
         # this has to come last, since it matches everything
         self.instance_handler.install()