Browse Source

HUE-9064 [core] V1 of Websockets infra

Romain 6 years ago
parent
commit
5bd494dd40

+ 1 - 0
desktop/core/src/desktop/conf.py

@@ -45,6 +45,7 @@ if sys.version_info[0] > 2:
 else:
 else:
   new_str = unicode
   new_str = unicode
 
 
+
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)
 
 
 
 

+ 12 - 0
desktop/core/src/desktop/routing.py

@@ -0,0 +1,12 @@
+from channels.auth import AuthMiddlewareStack
+from channels.routing import ProtocolTypeRouter, URLRouter
+import notebook.routing
+
+application = ProtocolTypeRouter({
+    # (http->django views is added by default)
+    'websocket': AuthMiddlewareStack(
+        URLRouter(
+            notebook.routing.websocket_urlpatterns
+        )
+    ),
+})

+ 13 - 0
desktop/core/src/desktop/settings.py

@@ -204,6 +204,8 @@ INSTALLED_APPS = [
     # Desktop injects all the other installed apps into here magically.
     # Desktop injects all the other installed apps into here magically.
     'desktop',
     'desktop',
 
 
+    'channels',
+
     # App that keeps track of failed logins.
     # App that keeps track of failed logins.
     'axes',
     'axes',
     'webpack_loader',
     'webpack_loader',
@@ -480,6 +482,17 @@ if EMAIL_BACKEND == 'sendgrid_backend.SendgridBackend':
   SENDGRID_SANDBOX_MODE_IN_DEBUG = DEBUG
   SENDGRID_SANDBOX_MODE_IN_DEBUG = DEBUG
 
 
 
 
+ASGI_APPLICATION = 'desktop.routing.application'
+
+CHANNEL_LAYERS = {
+    'default': {
+        'BACKEND': 'channels_redis.core.RedisChannelLayer',
+        'CONFIG': {
+            "hosts": [('127.0.0.1', 6379)],
+        },
+    },
+}
+
 # Used for securely creating sessions. Should be unique and not shared with anybody. Changing auth backends will invalidate all open sessions.
 # Used for securely creating sessions. Should be unique and not shared with anybody. Changing auth backends will invalidate all open sessions.
 SECRET_KEY = desktop.conf.get_secret_key()
 SECRET_KEY = desktop.conf.get_secret_key()
 if SECRET_KEY:
 if SECRET_KEY:

+ 12 - 0
desktop/core/src/desktop/templates/common_notebook_ko_components.mako

@@ -418,6 +418,18 @@ from notebook.conf import ENABLE_SQL_INDEXER
           $('.clipboard-content').empty();
           $('.clipboard-content').empty();
         });
         });
 
 
+        var chatSocket = new WebSocket('ws://' + window.location.host + '/ws/chat/' + self.snippet.id() + '/');
+
+        chatSocket.onmessage = function(e) {
+          var data = JSON.parse(e.data);
+          var message = data['message'];
+          console.log(message);
+        };
+
+        chatSocket.onclose = function(e) {
+          console.error('Chat socket closed unexpectedly');
+        };
+
         self.trySaveResults = function () {
         self.trySaveResults = function () {
           if (self.isValidDestination()) {
           if (self.isValidDestination()) {
             self.saveResults();
             self.saveResults();

+ 17 - 16
desktop/core/src/desktop/views.py

@@ -511,22 +511,23 @@ def get_banner_message(request):
   banner_message = None
   banner_message = None
   forwarded_host = request.get_host()
   forwarded_host = request.get_host()
 
 
-  message = None
-  path_info = request.environ.get("PATH_INFO")
-  if path_info.find("/hue") < 0 and path_info.find("accounts/login") < 0:
-    url = request.build_absolute_uri("/hue")
-    link = '<a href="%s" style="color: #FFF; font-weight: bold">%s</a>' % (url, url)
-    message = _('You are accessing an older version of Hue, please switch to the latest version: %s.') % link
-    LOG.warn('User %s is using Hue 3 UI' % request.user.username)
-
-  if HUE_LOAD_BALANCER.get() and HUE_LOAD_BALANCER.get() != [''] and \
-    (not forwarded_host or not any(forwarded_host in lb for lb in HUE_LOAD_BALANCER.get())):
-    message = _('You are accessing a non-optimized Hue, please switch to one of the available addresses: %s') % \
-      (", ".join(['<a href="%s" style="color: #FFF; font-weight: bold">%s</a>' % (host, host) for host in HUE_LOAD_BALANCER.get()]))
-    LOG.warn('User %s is bypassing the load balancer' % request.user.username)
-
-  if message:
-    banner_message = '<div style="padding: 4px; text-align: center; background-color: #003F6C; height: 24px; color: #DBE8F1">%s</div>' % message
+  if hasattr(request, 'environ'):
+    message = None
+    path_info = request.environ.get("PATH_INFO")
+    if path_info.find("/hue") < 0 and path_info.find("accounts/login") < 0:
+      url = request.build_absolute_uri("/hue")
+      link = '<a href="%s" style="color: #FFF; font-weight: bold">%s</a>' % (url, url)
+      message = _('You are accessing an older version of Hue, please switch to the latest version: %s.') % link
+      LOG.warn('User %s is using Hue 3 UI' % request.user.username)
+
+    if HUE_LOAD_BALANCER.get() and HUE_LOAD_BALANCER.get() != [''] and \
+      (not forwarded_host or not any(forwarded_host in lb for lb in HUE_LOAD_BALANCER.get())):
+      message = _('You are accessing a non-optimized Hue, please switch to one of the available addresses: %s') % \
+        (", ".join(['<a href="%s" style="color: #FFF; font-weight: bold">%s</a>' % (host, host) for host in HUE_LOAD_BALANCER.get()]))
+      LOG.warn('User %s is bypassing the load balancer' % request.user.username)
+
+    if message:
+      banner_message = '<div style="padding: 4px; text-align: center; background-color: #003F6C; height: 24px; color: #DBE8F1">%s</div>' % message
 
 
   return banner_message
   return banner_message
 
 

+ 28 - 0
desktop/libs/notebook/src/notebook/consumer.py

@@ -0,0 +1,28 @@
+from channels.generic.websocket import AsyncWebsocketConsumer
+import json
+
+class ChatConsumer(AsyncWebsocketConsumer):
+
+  async def connect(self):
+    await self.accept()
+
+    await self.send(text_data=json.dumps({
+      'type': 'channel_name',
+      'data': self.channel_name,
+      'accept': True
+    }))
+
+
+  async def task_progress(self, event):
+    await self.send(text_data=json.dumps({
+      'type': 'task_progress',
+      'data': event["data"]
+    }))
+
+
+def _send_to_channel(channel_name, message_type, message_data):
+  channel_layer = get_channel_layer()
+  async_to_sync(channel_layer.send)(channel_name, {
+      "type": message_type,
+      "data": message_data,
+  })

+ 9 - 0
desktop/libs/notebook/src/notebook/routing.py

@@ -0,0 +1,9 @@
+# from django.urls import re_path # Django 2
+from django.conf.urls import url
+
+
+from notebook import consumer
+
+websocket_urlpatterns = [
+    url(r'ws/chat/(?P<room_name>[\w\-]+)/$', consumer.ChatConsumer),
+]