Browse Source

HUE-8758 [connector] Wire-in the test connection API to the UI

Some rough UI but the initial logic is there.
Romain 5 years ago
parent
commit
5bc65013ef

+ 2 - 1
desktop/core/src/desktop/lib/connectors/api.py

@@ -120,8 +120,9 @@ def test_connector(request):
 
 
   # Currently only Editor connectors are supported.
   # Currently only Editor connectors are supported.
   interpreter = _connector_to_iterpreter(
   interpreter = _connector_to_iterpreter(
-    _augment_connector_properties(connector)
+      _augment_connector_properties(connector)
   )
   )
+  interpreter['type'] = 'hello'  # This is the id of the common health check query
 
 
   warnings = ''.join([
   warnings = ''.join([
     ''.join(warning)
     ''.join(warning)

+ 9 - 3
desktop/core/src/desktop/lib/connectors/tests.py

@@ -81,7 +81,11 @@ class TestConnectors(object):
 
 
 
 
   def test_test_connector(self):
   def test_test_connector(self):
-    connector = {'connector': json.dumps({'name': 'hive', 'dialect': 'hive', 'is_sql': True, 'type': 'id-1'})}
+    connector = {
+      'connector': json.dumps({
+        'name': 'hive', 'dialect': 'hive', 'id': 'id-1', 'nice_name': 'Sales DB', 'settings': {}, 'interface': 'hiveserver2'
+      })
+    }
 
 
     response = self.client.post("/desktop/connectors/api/instance/test/", connector)
     response = self.client.post("/desktop/connectors/api/instance/test/", connector)
     assert_equal(401, response.status_code)
     assert_equal(401, response.status_code)
@@ -133,6 +137,8 @@ class TestConnectorListing(unittest.TestCase):
 
 
   @classmethod
   @classmethod
   def tearDownClass(cls):
   def tearDownClass(cls):
+    HuePermission.objects.all().delete()
+
     for reset in cls._class_resets:
     for reset in cls._class_resets:
       reset()
       reset()
 
 
@@ -160,10 +166,10 @@ class TestConnectorListing(unittest.TestCase):
 
 
     # Could leverate update_app_permissions() instead of adding manually the permission but this is more lightweight for now
     # Could leverate update_app_permissions() instead of adding manually the permission but this is more lightweight for now
     conn_perm = HuePermission.objects.create(app=connector.name, action='access', description='', connector=connector)
     conn_perm = HuePermission.objects.create(app=connector.name, action='access', description='', connector=connector)
-    default_group = get_default_user_group()
-    GroupPermission.objects.create(group=default_group, hue_permission=conn_perm)
+    GroupPermission.objects.create(group=self.user.groups.first(), hue_permission=conn_perm)
 
 
     try:
     try:
+      assert_true(self.user.get_permissions())
       connectors = _get_installed_connectors(user=self.user)
       connectors = _get_installed_connectors(user=self.user)
       assert_true(connectors, connectors)
       assert_true(connectors, connectors)
 
 

+ 9 - 7
desktop/libs/notebook/src/notebook/conf.py

@@ -331,14 +331,14 @@ def config_validator(user, interpreters=None):
     res.append(('Editor', _('Could not authenticate with user %s to validate interpreters') % user))
     res.append(('Editor', _('Could not authenticate with user %s to validate interpreters') % user))
 
 
   if interpreters is None:
   if interpreters is None:
-    connectors = get_ordered_interpreters(user=user)
+    interpreters = get_ordered_interpreters(user=user)
 
 
   for interpreter in interpreters:
   for interpreter in interpreters:
     if interpreter.get('is_sql'):
     if interpreter.get('is_sql'):
       connector_id = interpreter['type']
       connector_id = interpreter['type']
 
 
       try:
       try:
-        response = _excute_test_query(client, connector_id)
+        response = _excute_test_query(client, connector_id, interpreter=interpreter)
         data = json.loads(response.content)
         data = json.loads(response.content)
 
 
         if data['status'] != 0:
         if data['status'] != 0:
@@ -360,7 +360,7 @@ def config_validator(user, interpreters=None):
   return res
   return res
 
 
 
 
-def _excute_test_query(client, connector_id):
+def _excute_test_query(client, connector_id, interpreter=None):
   '''
   '''
   Helper utils until the API gets simplified.
   Helper utils until the API gets simplified.
   '''
   '''
@@ -368,8 +368,8 @@ def _excute_test_query(client, connector_id):
     {
     {
       "selectedSnippet": "hive",
       "selectedSnippet": "hive",
       "showHistory": false,
       "showHistory": false,
-      "description": "Test Hive Query",
-      "name": "Test Hive Query",
+      "description": "Test Query",
+      "name": "Test Query",
       "sessions": [
       "sessions": [
           {
           {
               "type": "hive",
               "type": "hive",
@@ -383,13 +383,15 @@ def _excute_test_query(client, connector_id):
       "uuid": "d9efdee1-ef25-4d43-b8f9-1a170f69a05a"
       "uuid": "d9efdee1-ef25-4d43-b8f9-1a170f69a05a"
   }
   }
   """ % {
   """ % {
-    'connector_id': connector_id
+    'connector_id': connector_id,
   }
   }
+  snippet = json.loads(notebook_json)['snippets'][0]
+  snippet['interpreter'] = interpreter
 
 
   return client.post(
   return client.post(
     reverse('notebook:api_sample_data', kwargs={'database': 'default', 'table': 'default'}), {
     reverse('notebook:api_sample_data', kwargs={'database': 'default', 'table': 'default'}), {
       'notebook': notebook_json,
       'notebook': notebook_json,
-      'snippet': json.dumps(json.loads(notebook_json)['snippets'][0]),
+      'snippet': json.dumps(snippet),
       'is_async': json.dumps(True),
       'is_async': json.dumps(True),
       'operation': json.dumps('hello')
       'operation': json.dumps('hello')
   })
   })

+ 2 - 4
desktop/libs/notebook/src/notebook/conf_tests.py

@@ -68,10 +68,9 @@ class TestInterpreterConfig(unittest.TestCase):
           'name': 'hive-1',
           'name': 'hive-1',
           'dialect': 'hive',
           'dialect': 'hive',
           'category': 'editor',
           'category': 'editor',
-          'is_sql': True,
           'interface': 'hiveserver2',
           'interface': 'hiveserver2',
           'settings': {},
           'settings': {},
-          'dialect_properties': {'sql_identifier_quote': '`',},
+          'dialect_properties': {'sql_identifier_quote': '`', 'is_sql': True},
         }
         }
       ]
       ]
 
 
@@ -118,10 +117,9 @@ class TestCheckConfig():
             'name': 'hive-1',
             'name': 'hive-1',
             'dialect': 'hive',
             'dialect': 'hive',
             'category': 'editor',
             'category': 'editor',
-            'is_sql': True,
             'interface': 'hiveserver2',
             'interface': 'hiveserver2',
             'settings': {},
             'settings': {},
-            'dialect_properties': {'sql_identifier_quote': '`',},
+            'dialect_properties': {'sql_identifier_quote': '`', 'is_sql': True},
           }
           }
         ]
         ]
         _excute_test_query.return_value = Mock(content=json.dumps({'status': 0}))
         _excute_test_query.return_value = Mock(content=json.dumps({'status': 0}))

+ 17 - 5
desktop/libs/notebook/src/notebook/connectors/base.py

@@ -24,6 +24,7 @@ import uuid
 
 
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
+from desktop.auth.backend import is_admin
 from desktop.conf import TASK_SERVER, has_connectors
 from desktop.conf import TASK_SERVER, has_connectors
 from desktop.lib import export_csvxls
 from desktop.lib import export_csvxls
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.exceptions_renderable import PopupException
@@ -136,7 +137,14 @@ class Notebook(object):
         value = str(variable['value'])
         value = str(variable['value'])
         return p1 + (value if value is not None else variable['meta'].get('placeholder',''))
         return p1 + (value if value is not None else variable['meta'].get('placeholder',''))
 
 
-      return re.sub("([^\\\\])\\$" + ("{(" if hasCurlyBracketParameters else "(") + variablesString + ")(=[^}]*)?" + ("}" if hasCurlyBracketParameters else ""), replace, statement_raw)
+      return re.sub(
+          "([^\\\\])\\$" + (
+            "{(" if hasCurlyBracketParameters else "(") + variablesString + ")(=[^}]*)?" + ("}"
+            if hasCurlyBracketParameters else ""
+          ),
+          replace,
+          statement_raw
+      )
 
 
     return statement_raw
     return statement_raw
 
 
@@ -327,19 +335,23 @@ def get_api(request, snippet):
     snippet['type'] = 'impala'
     snippet['type'] = 'impala'
 
 
   if snippet.get('connector'):
   if snippet.get('connector'):
-    connector_name = snippet['connector']['type'] # Ideally unify with name and nice_name
+    connector_name = snippet['connector']['type']  # Ideally unify with name and nice_name
     snippet['type'] = connector_name
     snippet['type'] = connector_name
   else:
   else:
     connector_name = snippet['type']
     connector_name = snippet['type']
 
 
-  interpreter = get_interpreter(connector_type=connector_name, user=request.user)
+  if has_connectors() and snippet.get('type') == 'hello' and is_admin(request.user):
+    interpreter = snippet.get('interpreter')
+  else:
+    interpreter = get_interpreter(connector_type=connector_name, user=request.user)
+
   interface = interpreter['interface']
   interface = interpreter['interface']
 
 
   if get_cluster_config(request.user)['has_computes']:
   if get_cluster_config(request.user)['has_computes']:
-    compute = json.loads(request.POST.get('cluster', '""')) # Via Catalog autocomplete API or Notebook create sessions.
+    compute = json.loads(request.POST.get('cluster', '""'))  # Via Catalog autocomplete API or Notebook create sessions.
     if compute == '""' or compute == 'undefined':
     if compute == '""' or compute == 'undefined':
       compute = None
       compute = None
-    if not compute and snippet.get('compute'): # Via notebook.ko.js
+    if not compute and snippet.get('compute'):  # Via notebook.ko.js
       interpreter['compute'] = snippet['compute']
       interpreter['compute'] = snippet['compute']
 
 
   LOG.debug('Selected interpreter %s interface=%s compute=%s' % (
   LOG.debug('Selected interpreter %s interface=%s compute=%s' % (