Przeglądaj źródła

HUE-8758 [connector] Adding a test connector API

Relying on Notebook connectors only currently.
Romain 5 lat temu
rodzic
commit
90f34cdb0a

+ 11 - 0
desktop/core/src/desktop/lib/connectors/api.py

@@ -21,6 +21,7 @@ import logging
 from django.utils.translation import ugettext as _
 
 from useradmin.models import update_app_permissions
+from notebook.conf import config_validator
 
 from desktop.auth.decorators import admin_required
 from desktop.decorators import api_error_handler
@@ -112,6 +113,16 @@ def delete_connector(request):
   return JsonResponse({})
 
 
+@admin_required
+def test_connector(request):
+  connector = json.loads(request.POST.get('connector', '{}'))
+
+  connectors = [connector]
+  warnings = config_validator(user=request.user, connectors=connectors)
+
+  return JsonResponse({'warnings': warnings})
+
+
 @admin_required
 @api_error_handler
 def install_connector_examples(request):

+ 43 - 2
desktop/core/src/desktop/lib/connectors/tests.py

@@ -24,7 +24,7 @@ from nose.plugins.skip import SkipTest
 from nose.tools import assert_equal, assert_true, assert_false
 
 from desktop.auth.backend import rewrite_user, is_admin
-from desktop.conf import ENABLE_CONNECTORS
+from desktop.conf import ENABLE_CONNECTORS, ENABLE_ORGANIZATIONS
 from desktop.lib.connectors.api import _get_installed_connectors
 from desktop.lib.django_test_util import make_logged_in_client
 
@@ -44,16 +44,34 @@ class TestConnectors(object):
     self.client = make_logged_in_client(username="test_connector", recreate=True, is_superuser=False)
     self.user = User.objects.get(username="test_connector")
 
+    self.admin_client = make_logged_in_client(username="admin_test_connector", recreate=True, is_superuser=True)
+    self.admin_user = User.objects.get(username="admin_test_connector")
+
+  @classmethod
+  def setUpClass(cls):
+    cls._class_resets = [
+      ENABLE_CONNECTORS.set_for_testing(True),
+      ENABLE_ORGANIZATIONS.set_for_testing(False),
+    ]
+
+  @classmethod
+  def tearDownClass(cls):
+    for reset in cls._class_resets:
+      reset()
+
+
   def test_page(self):
     response = self.client.get("/desktop/connectors/")
 
     assert_equal(200, response.status_code)
 
+
   def test_get_connector_types(self):
     response = self.client.post("/desktop/connectors/api/types/")
 
     assert_equal(200, response.status_code)
 
+
   def test_create_connector_perm(self):
     response = self.client.post("/desktop/connectors/api/instance/update/")
     assert_equal(401, response.status_code)
@@ -62,6 +80,27 @@ class TestConnectors(object):
     assert_equal(401, response.status_code)
 
 
+  def test_test_connector(self):
+    connector = {'connector': json.dumps({'name': 'hive', 'dialect': 'hive', 'is_sql': True, 'type': 'id-1'})}
+
+    response = self.client.post("/desktop/connectors/api/instance/test/", connector)
+    assert_equal(401, response.status_code)
+
+    with patch('desktop.lib.connectors.api.config_validator') as config_validator:
+      config_validator.return_value = []
+
+      response = self.admin_client.post("/desktop/connectors/api/instance/test/", connector)
+      assert_equal(200, response.status_code)
+      assert_false(json.loads(response.content)['warnings'])
+
+    with patch('notebook.conf._excute_test_query') as _excute_test_query:
+      _excute_test_query.side_effect = Exception('')  # Just in case as relying on connector id not existing
+
+      response = self.admin_client.post("/desktop/connectors/api/instance/test/", connector)
+      assert_equal(200, response.status_code)
+      assert_true(json.loads(response.content)['warnings'])
+
+
 class TestConnectorListing(unittest.TestCase):
 
   def setUp(self):
@@ -115,7 +154,9 @@ class TestConnectorListing(unittest.TestCase):
 
 
   def test_get_connectors_for_user(self):
-    connector = Connector.objects.create(name='MySql', dialect='mysql', settings=json.dumps([{"name": "url", "value": "mysql://hue:pwd@hue:3306/hue"}]))
+    connector = Connector.objects.create(
+        name='MySql', dialect='mysql', settings=json.dumps([{"name": "url", "value": "mysql://hue:pwd@hue:3306/hue"}])
+    )
 
     # 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)

+ 1 - 0
desktop/core/src/desktop/lib/connectors/urls.py

@@ -30,6 +30,7 @@ urlpatterns = [
   url(r'^api/instance/get/(?P<id>\d+)$', api.get_connector, name='connectors.api.get_connector'),
   url(r'^api/instance/delete/?$', api.delete_connector, name='connectors.api.delete_connector'),
   url(r'^api/instance/update/?$', api.update_connector, name='connectors.api.update_connector'),
+  url(r'^api/instance/test/?$', api.test_connector, name='connectors.api.test_connector'),
 
   url(r'^api/examples/install/?$', api.install_connector_examples, name='connectors.api.install_connector_examples'),
 ]

+ 1 - 3
desktop/core/src/desktop/views.py

@@ -628,9 +628,7 @@ def load_confs(configspecpath, conf_source=None):
   """Loads and merges all of the configurations passed in,
   returning a ConfigObj for the result.
 
-  @param conf_source if not specified, reads conf/ from
-                     desktop/conf/. Otherwise should be a generator
-                     of ConfigObjs
+  @param conf_source if not specified, reads conf/ from desktop/conf/. Otherwise should be a generator of ConfigObjs
   """
   if conf_source is None:
     conf_source = _configs_from_dir(get_desktop_root("conf"))

+ 5 - 2
desktop/libs/notebook/src/notebook/conf.py

@@ -312,7 +312,7 @@ def _default_interpreters(user):
   INTERPRETERS.set_for_testing(OrderedDict(interpreters))
 
 
-def config_validator(user):
+def config_validator(user, connectors=None):
   res = []
 
   if not has_connectors():
@@ -324,7 +324,10 @@ def config_validator(user):
   if not user.is_authenticated():
     res.append(('Editor', _('Could not authenticate with user %s to validate interpreters') % user))
 
-  for interpreter in get_ordered_interpreters(user=user):
+  if connectors is None:
+    connectors = get_ordered_interpreters(user=user)
+
+  for interpreter in connectors:
     if interpreter.get('is_sql'):
       connector_id = interpreter['type']