瀏覽代碼

[notebook] Add connection configuration options for JDBC

No need to hardcode any JDBC property.

    [[[mysql]]]
    name=MySql JDBC
    interface=jdbc
    options='{"url": "jdbc:mysql://localhost:3306/hue2", "driver": "com.mysql.jdbc.Driver", "user": "root", "password": "root"}'
Romain Rigaux 10 年之前
父節點
當前提交
f842b96

+ 11 - 3
desktop/libs/notebook/src/notebook/conf.py

@@ -17,14 +17,16 @@
 
 from django.utils.translation import ugettext_lazy as _t
 
-from desktop.lib.conf import Config, UnspecifiedConfigSection, ConfigSection
+from desktop.lib.conf import Config, UnspecifiedConfigSection, ConfigSection,\
+  coerce_json_dict
 
 
 def get_interpreters():
   return [{
       "name": INTERPRETERS.get()[i].NAME.get(),
       "type": i,
-      "interface": INTERPRETERS.get()[i].INTERFACE.get()}
+      "interface": INTERPRETERS.get()[i].INTERFACE.get(),
+      "options": INTERPRETERS.get()[i].OPTIONS.get()}
       for i in INTERPRETERS.get()
   ]
 
@@ -33,7 +35,7 @@ INTERPRETERS = UnspecifiedConfigSection(
   "interpreters",
   help="One entry for each type of snippet",
   each=ConfigSection(
-    help=_t("Information about a single Zookeeper cluster"),
+    help=_t("Define the name and how to execute the language"),
     members=dict(
       NAME=Config(
           "name",
@@ -47,6 +49,12 @@ INTERPRETERS = UnspecifiedConfigSection(
           default="hiveserver2",
           type=str,
       ),
+      OPTIONS=Config(
+        key='options',
+        help=_t('Database options to specify the server for connecting.'),
+        type=coerce_json_dict,
+        default='{}'
+      )                 
     )
   )
 )

+ 9 - 7
desktop/libs/notebook/src/notebook/connectors/base.py

@@ -79,7 +79,7 @@ class Notebook():
 
 def get_api(user, snippet, fs, jt):
   from notebook.connectors.hiveserver2 import HS2Api
-  from notebook.connectors.jdbc import JDBCApi
+  from notebook.connectors.jdbc import JdbcApi
   from notebook.connectors.mysql import MySqlApi
   from notebook.connectors.pig_batch import PigApi
   from notebook.connectors.spark_shell import SparkApi
@@ -87,10 +87,11 @@ def get_api(user, snippet, fs, jt):
   from notebook.connectors.text import TextApi
 
 
-  interface = [interpreter for interpreter in get_interpreters() if interpreter['type'] == snippet['type']]
-  if not interface:
+  interpreter = [interpreter for interpreter in get_interpreters() if interpreter['type'] == snippet['type']]
+  if not interpreter:
     raise PopupException(_('Snippet type %(type)s is not configured in hue.ini') % snippet)
-  interface = interface[0]['interface']
+  interface = interpreter[0]['interface']
+  options = interpreter[0]['options']
 
   if interface == 'hiveserver2':
     return HS2Api(user)
@@ -103,9 +104,9 @@ def get_api(user, snippet, fs, jt):
   elif interface == 'mysql':
     return MySqlApi(user)
   elif interface == 'jdbc':
-    return JDBCApi(user)
+    return JdbcApi(user, options=options)
   elif interface == 'pig':
-    return PigApi(user, fs, jt)
+    return PigApi(user, fs=fs, jt=jt)
   else:
     raise PopupException(_('Notebook connector interface not recognized: %s') % interface)
 
@@ -118,10 +119,11 @@ def _get_snippet_session(notebook, snippet):
 
 class Api(object):
 
-  def __init__(self, user, fs=None, jt=None):
+  def __init__(self, user, fs=None, jt=None, options=None):
     self.user = user
     self.fs = fs
     self.jt = jt
+    self.options = options
 
   def create_session(self, lang, properties=None):
     return {

+ 6 - 32
desktop/libs/notebook/src/notebook/connectors/jdbc.py

@@ -16,13 +16,12 @@
 # limitations under the License.
 
 import logging
-import re
 
+from django.utils.translation import ugettext as _
 
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.i18n import force_unicode
 from librdbms.jdbc import Jdbc
-from django.utils.translation import ugettext as _
 
 from notebook.connectors.base import Api, QueryError
 
@@ -36,32 +35,19 @@ def query_error_handler(func):
       return func(*args, **kwargs)
     except Exception, e:
       message = force_unicode(str(e))
-      if 'Class com.mysql.jdbc.Driver not found' in message:
-        raise QueryError(_('%s: did you export CLASSPATH=$CLASSPATH:/usr/share/java/mysql.jar?') % message)
+      if 'error occurred while trying to connect to the Java server' in message:
+        raise QueryError(_('%s: is the DB Proxy server running?') % message)
       else:
         raise QueryError(message)
   return decorator
 
 
-class JDBCApi(Api):
+class JdbcApi(Api):
 
-  # TODO
-  # async with queuing system
-  # impersonation / prompting for username/password
   @query_error_handler
   def execute(self, notebook, snippet):
-    user = 'root'
-    password = 'root'
-
-    host = 'localhost'
-    port = 3306
-    database = 'test'
-
-
-    jclassname = "com.mysql.jdbc.Driver"
-    url = "jdbc:mysql://{host}:{port}/{database}".format(host=host, port=port, database=database)
 
-    db = Jdbc(jclassname, url, user, password)
+    db = Jdbc(self.options['driver'], self.options['url'], self.options['user'], self.options['password'])
     db.connect()
 
     curs = db.cursor()
@@ -110,19 +96,7 @@ class JDBCApi(Api):
     return []
 
   def _progress(self, snippet, logs):
-    if snippet['type'] == 'hive':
-      match = re.search('Total jobs = (\d+)', logs, re.MULTILINE)
-      total = (int(match.group(1)) if match else 1) * 2
-
-      started = logs.count('Starting Job')
-      ended = logs.count('Ended Job')
-
-      return int((started + ended) * 100 / total)
-    elif snippet['type'] == 'impala':
-      match = re.search('(\d+)% Complete', logs, re.MULTILINE)
-      return int(match.group(1)) if match else 0
-    else:
-      return 50
+    return 50
 
   @query_error_handler
   def close_statement(self, snippet):