http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0d746fa2/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java ---------------------------------------------------------------------- diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java index 228215f..93d2344 100644 --- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java +++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java @@ -5,12 +5,12 @@ * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * - * <p>http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * <p>Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. */ package org.apache.zeppelin.jdbc; @@ -19,6 +19,22 @@ import static org.apache.commons.lang.StringUtils.isEmpty; import static org.apache.commons.lang.StringUtils.isNotEmpty; import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.KERBEROS; +import org.apache.commons.dbcp2.ConnectionFactory; +import org.apache.commons.dbcp2.DriverManagerConnectionFactory; +import org.apache.commons.dbcp2.PoolableConnectionFactory; +import org.apache.commons.dbcp2.PoolingDriver; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.apache.commons.pool2.ObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.alias.CredentialProvider; +import org.apache.hadoop.security.alias.CredentialProviderFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.security.PrivilegedExceptionAction; import java.sql.Connection; @@ -38,19 +54,7 @@ import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import org.apache.commons.dbcp2.ConnectionFactory; -import org.apache.commons.dbcp2.DriverManagerConnectionFactory; -import org.apache.commons.dbcp2.PoolableConnectionFactory; -import org.apache.commons.dbcp2.PoolingDriver; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.exception.ExceptionUtils; -import org.apache.commons.lang.mutable.MutableBoolean; -import org.apache.commons.pool2.ObjectPool; -import org.apache.commons.pool2.impl.GenericObjectPool; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.security.UserGroupInformation; -import org.apache.hadoop.security.alias.CredentialProvider; -import org.apache.hadoop.security.alias.CredentialProviderFactory; + import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterException; import org.apache.zeppelin.interpreter.InterpreterResult; @@ -63,24 +67,28 @@ import org.apache.zeppelin.scheduler.Scheduler; import org.apache.zeppelin.scheduler.SchedulerFactory; import org.apache.zeppelin.user.UserCredentials; import org.apache.zeppelin.user.UsernamePassword; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * JDBC interpreter for Zeppelin. This interpreter can also be used for accessing HAWQ, GreenplumDB, - * MariaDB, MySQL, Postgres and Redshift. + * JDBC interpreter for Zeppelin. This interpreter can also be used for accessing HAWQ, + * GreenplumDB, MariaDB, MySQL, Postgres and Redshift. * * <ul> - * <li>{@code default.url} - JDBC URL to connect to. - * <li>{@code default.user} - JDBC user name.. - * <li>{@code default.password} - JDBC password.. - * <li>{@code default.driver.name} - JDBC driver name. - * <li>{@code common.max.result} - Max number of SQL result to display. + * <li>{@code default.url} - JDBC URL to connect to.</li> + * <li>{@code default.user} - JDBC user name..</li> + * <li>{@code default.password} - JDBC password..</li> + * <li>{@code default.driver.name} - JDBC driver name.</li> + * <li>{@code common.max.result} - Max number of SQL result to display.</li> * </ul> * - * <p>How to use: <br> - * {@code %jdbc.sql} <br> - * {@code SELECT store_id, count(*) FROM retail_demo.order_lineitems_pxf GROUP BY store_id; } + * <p> + * How to use: <br/> + * {@code %jdbc.sql} <br/> + * {@code + * SELECT store_id, count(*) + * FROM retail_demo.order_lineitems_pxf + * GROUP BY store_id; + * } + * </p> */ public class JDBCInterpreter extends KerberosInterpreter { private Logger logger = LoggerFactory.getLogger(JDBCInterpreter.class); @@ -126,7 +134,7 @@ public class JDBCInterpreter extends KerberosInterpreter { private static final String CONCURRENT_EXECUTION_KEY = "zeppelin.jdbc.concurrent.use"; private static final String CONCURRENT_EXECUTION_COUNT = - "zeppelin.jdbc.concurrent.max_connection"; + "zeppelin.jdbc.concurrent.max_connection"; private static final String DBCP_STRING = "jdbc:apache:commons:dbcp:"; private final HashMap<String, Properties> basePropretiesMap; @@ -188,13 +196,8 @@ public class JDBCInterpreter extends KerberosInterpreter { if (!COMMON_KEY.equals(key)) { Properties properties = basePropretiesMap.get(key); if (!properties.containsKey(DRIVER_KEY) || !properties.containsKey(URL_KEY)) { - logger.error( - "{} will be ignored. {}.{} and {}.{} is mandatory.", - key, - DRIVER_KEY, - key, - key, - URL_KEY); + logger.error("{} will be ignored. {}.{} and {}.{} is mandatory.", + key, DRIVER_KEY, key, key, URL_KEY); removeKeySet.add(key); } } @@ -219,24 +222,20 @@ public class JDBCInterpreter extends KerberosInterpreter { } private void setMaxLineResults() { - if (basePropretiesMap.containsKey(COMMON_KEY) - && basePropretiesMap.get(COMMON_KEY).containsKey(MAX_LINE_KEY)) { + if (basePropretiesMap.containsKey(COMMON_KEY) && + basePropretiesMap.get(COMMON_KEY).containsKey(MAX_LINE_KEY)) { maxLineResults = Integer.valueOf(basePropretiesMap.get(COMMON_KEY).getProperty(MAX_LINE_KEY)); } } - private SqlCompleter createOrUpdateSqlCompleter( - SqlCompleter sqlCompleter, - final Connection connection, - String propertyKey, - final String buf, - final int cursor) { + private SqlCompleter createOrUpdateSqlCompleter(SqlCompleter sqlCompleter, + final Connection connection, String propertyKey, final String buf, final int cursor) { String schemaFiltersKey = String.format("%s.%s", propertyKey, COMPLETER_SCHEMA_FILTERS_KEY); String sqlCompleterTtlKey = String.format("%s.%s", propertyKey, COMPLETER_TTL_KEY); final String schemaFiltersString = getProperty(schemaFiltersKey); - int ttlInSeconds = - Integer.valueOf( - StringUtils.defaultIfEmpty(getProperty(sqlCompleterTtlKey), DEFAULT_COMPLETER_TTL)); + int ttlInSeconds = Integer.valueOf( + StringUtils.defaultIfEmpty(getProperty(sqlCompleterTtlKey), DEFAULT_COMPLETER_TTL) + ); final SqlCompleter completer; if (sqlCompleter == null) { completer = new SqlCompleter(ttlInSeconds); @@ -244,13 +243,12 @@ public class JDBCInterpreter extends KerberosInterpreter { completer = sqlCompleter; } ExecutorService executorService = Executors.newFixedThreadPool(1); - executorService.execute( - new Runnable() { - @Override - public void run() { - completer.createOrUpdateFromConnection(connection, schemaFiltersString, buf, cursor); - } - }); + executorService.execute(new Runnable() { + @Override + public void run() { + completer.createOrUpdateFromConnection(connection, schemaFiltersString, buf, cursor); + } + }); executorService.shutdown(); @@ -324,13 +322,13 @@ public class JDBCInterpreter extends KerberosInterpreter { } private boolean existAccountInBaseProperty(String propertyKey) { - return basePropretiesMap.get(propertyKey).containsKey(USER_KEY) - && !isEmpty((String) basePropretiesMap.get(propertyKey).get(USER_KEY)) - && basePropretiesMap.get(propertyKey).containsKey(PASSWORD_KEY); + return basePropretiesMap.get(propertyKey).containsKey(USER_KEY) && + !isEmpty((String) basePropretiesMap.get(propertyKey).get(USER_KEY)) && + basePropretiesMap.get(propertyKey).containsKey(PASSWORD_KEY); } - private UsernamePassword getUsernamePassword( - InterpreterContext interpreterContext, String replName) { + private UsernamePassword getUsernamePassword(InterpreterContext interpreterContext, + String replName) { UserCredentials uc = interpreterContext.getAuthenticationInfo().getUserCredentials(); if (uc != null) { return uc.getUsernamePassword(replName); @@ -362,8 +360,8 @@ public class JDBCInterpreter extends KerberosInterpreter { String user = interpreterContext.getAuthenticationInfo().getUser(); JDBCUserConfigurations jdbcUserConfigurations = getJDBCConfiguration(user); - if (basePropretiesMap.get(propertyKey).containsKey(USER_KEY) - && !basePropretiesMap.get(propertyKey).getProperty(USER_KEY).isEmpty()) { + if (basePropretiesMap.get(propertyKey).containsKey(USER_KEY) && + !basePropretiesMap.get(propertyKey).getProperty(USER_KEY).isEmpty()) { String password = getPassword(basePropretiesMap.get(propertyKey)); if (!isEmpty(password)) { basePropretiesMap.get(propertyKey).setProperty(PASSWORD_KEY, password); @@ -375,8 +373,8 @@ public class JDBCInterpreter extends KerberosInterpreter { } jdbcUserConfigurations.cleanUserProperty(propertyKey); - UsernamePassword usernamePassword = - getUsernamePassword(interpreterContext, getEntityName(interpreterContext.getReplName())); + UsernamePassword usernamePassword = getUsernamePassword(interpreterContext, + getEntityName(interpreterContext.getReplName())); if (usernamePassword != null) { jdbcUserConfigurations.setUserProperty(propertyKey, usernamePassword); } else { @@ -384,13 +382,13 @@ public class JDBCInterpreter extends KerberosInterpreter { } } - private void createConnectionPool( - String url, String user, String propertyKey, Properties properties) - throws SQLException, ClassNotFoundException { - ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, properties); + private void createConnectionPool(String url, String user, String propertyKey, + Properties properties) throws SQLException, ClassNotFoundException { + ConnectionFactory connectionFactory = + new DriverManagerConnectionFactory(url, properties); - PoolableConnectionFactory poolableConnectionFactory = - new PoolableConnectionFactory(connectionFactory, null); + PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory( + connectionFactory, null); final String maxConnectionLifetime = StringUtils.defaultIfEmpty(getProperty("zeppelin.jdbc.maxConnLifetime"), "-1"); poolableConnectionFactory.setMaxConnLifetimeMillis(Long.parseLong(maxConnectionLifetime)); @@ -404,9 +402,8 @@ public class JDBCInterpreter extends KerberosInterpreter { getJDBCConfiguration(user).saveDBDriverPool(propertyKey, driver); } - private Connection getConnectionFromPool( - String url, String user, String propertyKey, Properties properties) - throws SQLException, ClassNotFoundException { + private Connection getConnectionFromPool(String url, String user, String propertyKey, + Properties properties) throws SQLException, ClassNotFoundException { String jdbcDriver = getJDBCDriverName(user, propertyKey); if (!getJDBCConfiguration(user).isConnectionInDBDriverPool(propertyKey)) { @@ -417,7 +414,7 @@ public class JDBCInterpreter extends KerberosInterpreter { public Connection getConnection(String propertyKey, InterpreterContext interpreterContext) throws ClassNotFoundException, SQLException, InterpreterException, IOException { - final String user = interpreterContext.getAuthenticationInfo().getUser(); + final String user = interpreterContext.getAuthenticationInfo().getUser(); Connection connection; if (propertyKey == null || basePropretiesMap.get(propertyKey) == null) { return null; @@ -440,9 +437,8 @@ public class JDBCInterpreter extends KerberosInterpreter { JDBCSecurityImpl.createSecureConfiguration(getProperties(), authType); switch (authType) { case KERBEROS: - if (user == null - || "false" - .equalsIgnoreCase(getProperty("zeppelin.jdbc.auth.kerberos.proxy.enable"))) { + if (user == null || "false".equalsIgnoreCase( + getProperty("zeppelin.jdbc.auth.kerberos.proxy.enable"))) { connection = getConnectionFromPool(connectionUrl, user, propertyKey, properties); } else { if (basePropretiesMap.get(propertyKey).containsKey("proxy.user.property")) { @@ -450,9 +446,8 @@ public class JDBCInterpreter extends KerberosInterpreter { } else { UserGroupInformation ugi = null; try { - ugi = - UserGroupInformation.createProxyUser( - user, UserGroupInformation.getCurrentUser()); + ugi = UserGroupInformation.createProxyUser( + user, UserGroupInformation.getCurrentUser()); } catch (Exception e) { logger.error("Error in getCurrentUser", e); throw new InterpreterException("Error in getCurrentUser", e); @@ -460,14 +455,12 @@ public class JDBCInterpreter extends KerberosInterpreter { final String poolKey = propertyKey; try { - connection = - ugi.doAs( - new PrivilegedExceptionAction<Connection>() { - @Override - public Connection run() throws Exception { - return getConnectionFromPool(connectionUrl, user, poolKey, properties); - } - }); + connection = ugi.doAs(new PrivilegedExceptionAction<Connection>() { + @Override + public Connection run() throws Exception { + return getConnectionFromPool(connectionUrl, user, poolKey, properties); + } + }); } catch (Exception e) { logger.error("Error in doAs", e); throw new InterpreterException("Error in doAs", e); @@ -487,29 +480,21 @@ public class JDBCInterpreter extends KerberosInterpreter { private String appendProxyUserToURL(String url, String user, String propertyKey) { StringBuilder connectionUrl = new StringBuilder(url); - if (user != null - && !user.equals("anonymous") - && basePropretiesMap.get(propertyKey).containsKey("proxy.user.property")) { + if (user != null && !user.equals("anonymous") && + basePropretiesMap.get(propertyKey).containsKey("proxy.user.property")) { Integer lastIndexOfUrl = connectionUrl.indexOf("?"); if (lastIndexOfUrl == -1) { lastIndexOfUrl = connectionUrl.length(); } logger.info("Using proxy user as :" + user); - logger.info( - "Using proxy property for user as :" - + basePropretiesMap.get(propertyKey).getProperty("proxy.user.property")); - connectionUrl.insert( - lastIndexOfUrl, - ";" - + basePropretiesMap.get(propertyKey).getProperty("proxy.user.property") - + "=" - + user - + ";"); + logger.info("Using proxy property for user as :" + + basePropretiesMap.get(propertyKey).getProperty("proxy.user.property")); + connectionUrl.insert(lastIndexOfUrl, ";" + + basePropretiesMap.get(propertyKey).getProperty("proxy.user.property") + "=" + user + ";"); } else if (user != null && !user.equals("anonymous") && url.contains("hive")) { - logger.warn( - "User impersonation for hive has changed please refer: http://zeppelin.apache" - + ".org/docs/latest/interpreter/jdbc.html#apache-hive"); + logger.warn("User impersonation for hive has changed please refer: http://zeppelin.apache" + + ".org/docs/latest/interpreter/jdbc.html#apache-hive"); } return connectionUrl.toString(); @@ -522,8 +507,7 @@ public class JDBCInterpreter extends KerberosInterpreter { && isNotEmpty(properties.getProperty(JDBC_JCEKS_CREDENTIAL_KEY))) { try { Configuration configuration = new Configuration(); - configuration.set( - CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, + configuration.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, properties.getProperty(JDBC_JCEKS_FILE)); CredentialProvider provider = CredentialProviderFactory.getProviders(configuration).get(0); CredentialProvider.CredentialEntry credEntry = @@ -531,18 +515,13 @@ public class JDBCInterpreter extends KerberosInterpreter { if (credEntry != null) { return new String(credEntry.getCredential()); } else { - throw new InterpreterException( - "Failed to retrieve password from JCEKS from key: " - + properties.getProperty(JDBC_JCEKS_CREDENTIAL_KEY)); + throw new InterpreterException("Failed to retrieve password from JCEKS from key: " + + properties.getProperty(JDBC_JCEKS_CREDENTIAL_KEY)); } } catch (Exception e) { - logger.error( - "Failed to retrieve password from JCEKS \n" - + "For file: " - + properties.getProperty(JDBC_JCEKS_FILE) - + "\nFor key: " - + properties.getProperty(JDBC_JCEKS_CREDENTIAL_KEY), - e); + logger.error("Failed to retrieve password from JCEKS \n" + + "For file: " + properties.getProperty(JDBC_JCEKS_FILE) + + "\nFor key: " + properties.getProperty(JDBC_JCEKS_CREDENTIAL_KEY), e); throw e; } } @@ -638,10 +617,7 @@ public class JDBCInterpreter extends KerberosInterpreter { } } - if (!quoteString - && !doubleQuoteString - && !multiLineComment - && !singleLineComment + if (!quoteString && !doubleQuoteString && !multiLineComment && !singleLineComment && sql.length() > item + 1) { if (character == '-' && sql.charAt(item + 1) == '-') { singleLineComment = true; @@ -650,10 +626,7 @@ public class JDBCInterpreter extends KerberosInterpreter { } } - if (character == ';' - && !quoteString - && !doubleQuoteString - && !multiLineComment + if (character == ';' && !quoteString && !doubleQuoteString && !multiLineComment && !singleLineComment) { queries.add(StringUtils.trim(query.toString())); query = new StringBuilder(); @@ -683,8 +656,8 @@ public class JDBCInterpreter extends KerberosInterpreter { return interpreterResult; } - private InterpreterResult executeSql( - String propertyKey, String sql, InterpreterContext interpreterContext) { + private InterpreterResult executeSql(String propertyKey, String sql, + InterpreterContext interpreterContext) { Connection connection = null; Statement statement; ResultSet resultSet = null; @@ -739,7 +712,7 @@ public class JDBCInterpreter extends KerberosInterpreter { String statementPrecode = getProperty(String.format(STATEMENT_PRECODE_KEY_TEMPLATE, propertyKey)); - + if (StringUtils.isNotBlank(statementPrecode)) { statement.execute(statementPrecode); } @@ -750,42 +723,37 @@ public class JDBCInterpreter extends KerberosInterpreter { resultSet = statement.getResultSet(); // Regards that the command is DDL. - if (isDDLCommand( - statement.getUpdateCount(), resultSet.getMetaData().getColumnCount())) { - interpreterResult.add(InterpreterResult.Type.TEXT, "Query executed successfully."); + if (isDDLCommand(statement.getUpdateCount(), + resultSet.getMetaData().getColumnCount())) { + interpreterResult.add(InterpreterResult.Type.TEXT, + "Query executed successfully."); } else { MutableBoolean isComplete = new MutableBoolean(true); - String results = - getResults( - resultSet, !containsIgnoreCase(sqlToExecute, EXPLAIN_PREDICATE), isComplete); + String results = getResults(resultSet, + !containsIgnoreCase(sqlToExecute, EXPLAIN_PREDICATE), isComplete); interpreterResult.add(results); if (!isComplete.booleanValue()) { - interpreterResult.add( - ResultMessages.getExceedsLimitRowsMessage( - getMaxResult(), String.format("%s.%s", COMMON_KEY, MAX_LINE_KEY))); + interpreterResult.add(ResultMessages.getExceedsLimitRowsMessage(getMaxResult(), + String.format("%s.%s", COMMON_KEY, MAX_LINE_KEY))); } } } else { // Response contains either an update count or there are no results. int updateCount = statement.getUpdateCount(); - interpreterResult.add( - InterpreterResult.Type.TEXT, - "Query executed successfully. Affected rows : " + updateCount); + interpreterResult.add(InterpreterResult.Type.TEXT, + "Query executed successfully. Affected rows : " + + updateCount); } } finally { if (resultSet != null) { try { resultSet.close(); - } catch (SQLException e) { - /*ignored*/ - } + } catch (SQLException e) { /*ignored*/ } } if (statement != null) { try { statement.close(); - } catch (SQLException e) { - /*ignored*/ - } + } catch (SQLException e) { /*ignored*/ } } } } @@ -795,23 +763,23 @@ public class JDBCInterpreter extends KerberosInterpreter { interpreterResult.add(errorMsg); return new InterpreterResult(Code.ERROR, interpreterResult.message()); } finally { - // In case user ran an insert/update/upsert statement + //In case user ran an insert/update/upsert statement if (connection != null) { try { if (!connection.getAutoCommit()) { connection.commit(); } connection.close(); - } catch (SQLException e) { - /*ignored*/ - } + } catch (SQLException e) { /*ignored*/ } } getJDBCConfiguration(user).removeStatement(paragraphId); } return interpreterResult; } - /** For %table response replace Tab and Newline characters from the content. */ + /** + * For %table response replace Tab and Newline characters from the content. + */ private String replaceReservedChars(String str) { if (str == null) { return EMPTY_COLUMN_VALUE; @@ -821,10 +789,8 @@ public class JDBCInterpreter extends KerberosInterpreter { @Override public InterpreterResult interpret(String originalCmd, InterpreterContext contextInterpreter) { - String cmd = - Boolean.parseBoolean(getProperty("zeppelin.jdbc.interpolation")) - ? interpolate(originalCmd, contextInterpreter.getResourcePool()) - : originalCmd; + String cmd = Boolean.parseBoolean(getProperty("zeppelin.jdbc.interpolation")) ? + interpolate(originalCmd, contextInterpreter.getResourcePool()) : originalCmd; logger.debug("Run SQL command '{}'", cmd); String propertyKey = getPropertyKey(contextInterpreter); cmd = cmd.trim(); @@ -837,7 +803,7 @@ public class JDBCInterpreter extends KerberosInterpreter { logger.info("Cancel current query statement."); String paragraphId = context.getParagraphId(); JDBCUserConfigurations jdbcUserConfigurations = - getJDBCConfiguration(context.getAuthenticationInfo().getUser()); + getJDBCConfiguration(context.getAuthenticationInfo().getUser()); try { jdbcUserConfigurations.cancelStatement(paragraphId); } catch (SQLException e) { @@ -873,15 +839,15 @@ public class JDBCInterpreter extends KerberosInterpreter { @Override public Scheduler getScheduler() { String schedulerName = JDBCInterpreter.class.getName() + this.hashCode(); - return isConcurrentExecution() - ? SchedulerFactory.singleton() - .createOrGetParallelScheduler(schedulerName, getMaxConcurrentConnection()) - : SchedulerFactory.singleton().createOrGetFIFOScheduler(schedulerName); + return isConcurrentExecution() ? + SchedulerFactory.singleton().createOrGetParallelScheduler(schedulerName, + getMaxConcurrentConnection()) + : SchedulerFactory.singleton().createOrGetFIFOScheduler(schedulerName); } @Override - public List<InterpreterCompletion> completion( - String buf, int cursor, InterpreterContext interpreterContext) throws InterpreterException { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) throws InterpreterException { List<InterpreterCompletion> candidates = new ArrayList<>(); String propertyKey = getPropertyKey(interpreterContext); String sqlCompleterKey =
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0d746fa2/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCUserConfigurations.java ---------------------------------------------------------------------- diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCUserConfigurations.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCUserConfigurations.java index e584c06..4eac9fc 100644 --- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCUserConfigurations.java +++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCUserConfigurations.java @@ -5,24 +5,28 @@ * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * - * <p>http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * <p>Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. */ package org.apache.zeppelin.jdbc; +import org.apache.commons.dbcp2.PoolingDriver; + import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; import java.util.Map; import java.util.Properties; -import org.apache.commons.dbcp2.PoolingDriver; + import org.apache.zeppelin.user.UsernamePassword; -/** UserConfigurations for JDBC impersonation. */ +/** + * UserConfigurations for JDBC impersonation. + */ public class JDBCUserConfigurations { private final Map<String, Statement> paragraphIdStatementMap; private final Map<String, PoolingDriver> poolingDriverMap; @@ -83,7 +87,6 @@ public class JDBCUserConfigurations { poolingDriverMap.put(key, driver); isSuccessful.put(key, false); } - public PoolingDriver removeDBDriverPool(String key) throws SQLException { isSuccessful.remove(key); return poolingDriverMap.remove(key); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0d746fa2/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java ---------------------------------------------------------------------- diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java index 0f7f01e..9f52ecb 100644 --- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java +++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java @@ -4,6 +4,11 @@ package org.apache.zeppelin.jdbc; * This source file is based on code taken from SQLLine 1.0.2 See SQLLine notice in LICENSE */ +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -21,47 +26,54 @@ import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.regex.Pattern; + import jline.console.completer.ArgumentCompleter.ArgumentList; import jline.console.completer.ArgumentCompleter.WhitespaceArgumentDelimiter; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; + import org.apache.zeppelin.completer.CachedCompleter; import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.completer.StringsCompleter; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -/** SQL auto complete functionality for the JdbcInterpreter. */ +/** + * SQL auto complete functionality for the JdbcInterpreter. + */ public class SqlCompleter { private static Logger logger = LoggerFactory.getLogger(SqlCompleter.class); - /** Delimiter that can split SQL statement in keyword list. */ - private WhitespaceArgumentDelimiter sqlDelimiter = - new WhitespaceArgumentDelimiter() { + /** + * Delimiter that can split SQL statement in keyword list. + */ + private WhitespaceArgumentDelimiter sqlDelimiter = new WhitespaceArgumentDelimiter() { - private Pattern pattern = Pattern.compile(","); + private Pattern pattern = Pattern.compile(","); - @Override - public boolean isDelimiterChar(CharSequence buffer, int pos) { - return pattern.matcher("" + buffer.charAt(pos)).matches() + @Override + public boolean isDelimiterChar(CharSequence buffer, int pos) { + return pattern.matcher("" + buffer.charAt(pos)).matches() || super.isDelimiterChar(buffer, pos); - } - }; + } + }; - /** Schema completer. */ + /** + * Schema completer. + */ private CachedCompleter schemasCompleter; - /** Contain different completer with table list for every schema name. */ + /** + * Contain different completer with table list for every schema name. + */ private Map<String, CachedCompleter> tablesCompleters = new HashMap<>(); /** - * Contains different completer with column list for every table name Table names store as - * schema_name.table_name. + * Contains different completer with column list for every table name + * Table names store as schema_name.table_name. */ private Map<String, CachedCompleter> columnsCompleters = new HashMap<>(); - /** Completer for sql keywords. */ + /** + * Completer for sql keywords. + */ private CachedCompleter keywordCompleter; private int ttlInSeconds; @@ -87,11 +99,7 @@ public class SqlCompleter { argumentPosition = argumentList.getArgumentPosition(); } - int complete = - completeName( - cursorArgument, - argumentPosition, - candidates, + int complete = completeName(cursorArgument, argumentPosition, candidates, findAliasesInSQL(argumentList.getArguments())); logger.debug("complete:" + complete + ", size:" + candidates.size()); @@ -102,9 +110,10 @@ public class SqlCompleter { * Return list of schema names within the database. * * @param meta metadata from connection to database - * @param schemaFilters a schema name patterns; must match the schema name as it is stored in the - * database; "" retrieves those without a schema; <code>null</code> means that the schema name - * should not be used to narrow the search; supports '%'; for example "prod_v_%" + * @param schemaFilters a schema name patterns; must match the schema name + * as it is stored in the database; "" retrieves those without a schema; + * <code>null</code> means that the schema name should not be used to narrow + * the search; supports '%'; for example "prod_v_%" * @return set of all schema names in the database */ private static Set<String> getSchemaNames(DatabaseMetaData meta, List<String> schemaFilters) { @@ -137,9 +146,10 @@ public class SqlCompleter { * Return list of catalog names within the database. * * @param meta metadata from connection to database - * @param schemaFilters a catalog name patterns; must match the catalog name as it is stored in - * the database; "" retrieves those without a catalog; <code>null</code> means that the schema - * name should not be used to narrow the search; supports '%'; for example "prod_v_%" + * @param schemaFilters a catalog name patterns; must match the catalog name + * as it is stored in the database; "" retrieves those without a catalog; + * <code>null</code> means that the schema name should not be used to narrow + * the search; supports '%'; for example "prod_v_%" * @return set of all catalog names in the database */ private static Set<String> getCatalogNames(DatabaseMetaData meta, List<String> schemaFilters) { @@ -165,14 +175,8 @@ public class SqlCompleter { } private static void fillTableNames(String schema, DatabaseMetaData meta, Set<String> tables) { - try (ResultSet tbls = - meta.getTables( - schema, - schema, - "%", - new String[] { - "TABLE", "VIEW", "ALIAS", "SYNONYM", "GLOBAL TEMPORARY", "LOCAL TEMPORARY" - })) { + try (ResultSet tbls = meta.getTables(schema, schema, "%", + new String[]{"TABLE", "VIEW", "ALIAS", "SYNONYM", "GLOBAL TEMPORARY", "LOCAL TEMPORARY"})) { while (tbls.next()) { String table = tbls.getString("TABLE_NAME"); tables.add(table); @@ -188,11 +192,11 @@ public class SqlCompleter { * @param schema name of a scheme * @param table name of a table * @param meta meta metadata from connection to database - * @param columns function fills this set, for every table name adds set of columns within the - * table; table name is in format schema_name.table_name + * @param columns function fills this set, for every table name adds set + * of columns within the table; table name is in format schema_name.table_name */ - private static void fillColumnNames( - String schema, String table, DatabaseMetaData meta, Set<String> columns) { + private static void fillColumnNames(String schema, String table, DatabaseMetaData meta, + Set<String> columns) { try (ResultSet cols = meta.getColumns(schema, schema, table, "%")) { while (cols.next()) { String column = cols.getString("COLUMN_NAME"); @@ -203,34 +207,31 @@ public class SqlCompleter { } } - public static Set<String> getSqlKeywordsCompletions(DatabaseMetaData meta) - throws IOException, SQLException { + public static Set<String> getSqlKeywordsCompletions(DatabaseMetaData meta) throws IOException, + SQLException { // Add the default SQL completions String keywords = - new BufferedReader( - new InputStreamReader(SqlCompleter.class.getResourceAsStream("/ansi.sql.keywords"))) - .readLine(); + new BufferedReader(new InputStreamReader( + SqlCompleter.class.getResourceAsStream("/ansi.sql.keywords"))).readLine(); Set<String> completions = new TreeSet<>(); if (null != meta) { // Add the driver specific SQL completions String driverSpecificKeywords = - "/" + meta.getDriverName().replace(" ", "-").toLowerCase() + "-sql.keywords"; + "/" + meta.getDriverName().replace(" ", "-").toLowerCase() + "-sql.keywords"; logger.info("JDBC DriverName:" + driverSpecificKeywords); try { if (SqlCompleter.class.getResource(driverSpecificKeywords) != null) { String driverKeywords = - new BufferedReader( - new InputStreamReader( + new BufferedReader(new InputStreamReader( SqlCompleter.class.getResourceAsStream(driverSpecificKeywords))) - .readLine(); + .readLine(); keywords += "," + driverKeywords.toUpperCase(); } } catch (Exception e) { - logger.debug( - "fail to get driver specific SQL completions for " + driverSpecificKeywords + " : " + e, - e); + logger.debug("fail to get driver specific SQL completions for " + + driverSpecificKeywords + " : " + e, e); } // Add the keywords from the current JDBC connection @@ -276,11 +277,11 @@ public class SqlCompleter { * Initializes all local completers from database connection. * * @param connection database connection - * @param schemaFiltersString a comma separated schema name patterns, supports '%' symbol; for - * example "prod_v_%,prod_t_%" + * @param schemaFiltersString a comma separated schema name patterns, supports '%' symbol; + * for example "prod_v_%,prod_t_%" */ - public void createOrUpdateFromConnection( - Connection connection, String schemaFiltersString, String buffer, int cursor) { + public void createOrUpdateFromConnection(Connection connection, String schemaFiltersString, + String buffer, int cursor) { try (Connection c = connection) { if (schemaFiltersString == null) { schemaFiltersString = StringUtils.EMPTY; @@ -296,16 +297,14 @@ public class SqlCompleter { if (c != null) { DatabaseMetaData databaseMetaData = c.getMetaData(); - if (keywordCompleter == null - || keywordCompleter.getCompleter() == null + if (keywordCompleter == null || keywordCompleter.getCompleter() == null || keywordCompleter.isExpired()) { keywords = getSqlKeywordsCompletions(databaseMetaData); initKeywords(keywords); } - if (cursorArgument.needLoadSchemas() - && (schemasCompleter == null - || schemasCompleter.getCompleter() == null - || schemasCompleter.isExpired())) { + if (cursorArgument.needLoadSchemas() && + (schemasCompleter == null || schemasCompleter.getCompleter() == null + || schemasCompleter.isExpired())) { schemas = getSchemaNames(databaseMetaData, schemaFilters); catalogs = getCatalogNames(databaseMetaData, schemaFilters); @@ -317,8 +316,8 @@ public class SqlCompleter { } CachedCompleter tablesCompleter = tablesCompleters.get(cursorArgument.getSchema()); - if (cursorArgument.needLoadTables() - && (tablesCompleter == null || tablesCompleter.isExpired())) { + if (cursorArgument.needLoadTables() && + (tablesCompleter == null || tablesCompleter.isExpired())) { fillTableNames(cursorArgument.getSchema(), databaseMetaData, tables); initTables(cursorArgument.getSchema(), tables); } @@ -327,21 +326,15 @@ public class SqlCompleter { String.format("%s.%s", cursorArgument.getSchema(), cursorArgument.getTable()); CachedCompleter columnsCompleter = columnsCompleters.get(schemaTable); - if (cursorArgument.needLoadColumns() - && (columnsCompleter == null || columnsCompleter.isExpired())) { - fillColumnNames( - cursorArgument.getSchema(), cursorArgument.getTable(), databaseMetaData, columns); + if (cursorArgument.needLoadColumns() && + (columnsCompleter == null || columnsCompleter.isExpired())) { + fillColumnNames(cursorArgument.getSchema(), cursorArgument.getTable(), databaseMetaData, + columns); initColumns(schemaTable, columns); } - logger.info( - "Completer initialized with " - + schemas.size() - + " schemas, " - + columns.size() - + " tables and " - + keywords.size() - + " keywords"); + logger.info("Completer initialized with " + schemas.size() + " schemas, " + + columns.size() + " tables and " + keywords.size() + " keywords"); } } catch (SQLException | IOException e) { @@ -357,22 +350,22 @@ public class SqlCompleter { public void initSchemas(Set<String> schemas) { if (schemas != null && !schemas.isEmpty()) { - schemasCompleter = - new CachedCompleter(new StringsCompleter(new TreeSet<>(schemas)), ttlInSeconds); + schemasCompleter = new CachedCompleter( + new StringsCompleter(new TreeSet<>(schemas)), ttlInSeconds); } } public void initTables(String schema, Set<String> tables) { if (tables != null && !tables.isEmpty()) { - tablesCompleters.put( - schema, new CachedCompleter(new StringsCompleter(new TreeSet<>(tables)), ttlInSeconds)); + tablesCompleters.put(schema, new CachedCompleter( + new StringsCompleter(new TreeSet<>(tables)), ttlInSeconds)); } } public void initColumns(String schemaTable, Set<String> columns) { if (columns != null && !columns.isEmpty()) { - columnsCompleters.put( - schemaTable, new CachedCompleter(new StringsCompleter(columns), ttlInSeconds)); + columnsCompleters.put(schemaTable, + new CachedCompleter(new StringsCompleter(columns), ttlInSeconds)); } } @@ -385,8 +378,8 @@ public class SqlCompleter { public Map<String, String> findAliasesInSQL(String[] sqlArguments) { Map<String, String> res = new HashMap<>(); for (int i = 0; i < sqlArguments.length - 1; i++) { - if (columnsCompleters.keySet().contains(sqlArguments[i]) - && sqlArguments[i + 1].matches("[a-zA-Z]+")) { + if (columnsCompleters.keySet().contains(sqlArguments[i]) && + sqlArguments[i + 1].matches("[a-zA-Z]+")) { res.put(sqlArguments[i + 1], sqlArguments[i]); } } @@ -416,8 +409,8 @@ public class SqlCompleter { * * @return -1 in case of no candidates found, 0 otherwise */ - private int completeTable( - String schema, String buffer, int cursor, List<CharSequence> candidates) { + private int completeTable(String schema, String buffer, int cursor, + List<CharSequence> candidates) { // Wrong schema if (schema == null || !tablesCompleters.containsKey(schema)) { return -1; @@ -431,31 +424,26 @@ public class SqlCompleter { * * @return -1 in case of no candidates found, 0 otherwise */ - private int completeColumn( - String schema, String table, String buffer, int cursor, List<CharSequence> candidates) { + private int completeColumn(String schema, String table, String buffer, int cursor, + List<CharSequence> candidates) { // Wrong schema or wrong table if (schema == null || table == null || !columnsCompleters.containsKey(schema + "." + table)) { return -1; } else { - return columnsCompleters - .get(schema + "." + table) - .getCompleter() + return columnsCompleters.get(schema + "." + table).getCompleter() .complete(buffer, cursor, candidates); } } /** - * Complete buffer with a single name. Function will decide what it is: a schema, a table of a - * column or a keyword + * Complete buffer with a single name. Function will decide what it is: + * a schema, a table of a column or a keyword * * @param aliases for every alias contains table name in format schema_name.table_name * @return -1 in case of no candidates found, 0 otherwise */ - public int completeName( - String buffer, - int cursor, - List<InterpreterCompletion> candidates, - Map<String, String> aliases) { + public int completeName(String buffer, int cursor, List<InterpreterCompletion> candidates, + Map<String, String> aliases) { CursorArgument cursorArgument = parseCursorArgument(buffer, cursor); // find schema and table name if they are @@ -463,42 +451,40 @@ public class SqlCompleter { String table; String column; - if (cursorArgument.getSchema() == null) { // process all + if (cursorArgument.getSchema() == null) { // process all List<CharSequence> keywordsCandidates = new ArrayList(); List<CharSequence> schemaCandidates = new ArrayList<>(); int keywordsRes = completeKeyword(buffer, cursor, keywordsCandidates); int schemaRes = completeSchema(buffer, cursor, schemaCandidates); addCompletions(candidates, keywordsCandidates, CompletionType.keyword.name()); addCompletions(candidates, schemaCandidates, CompletionType.schema.name()); - return NumberUtils.max(new int[] {keywordsRes, schemaRes}); + return NumberUtils.max(new int[]{keywordsRes, schemaRes}); } else { schema = cursorArgument.getSchema(); - if (aliases.containsKey(schema)) { // process alias case + if (aliases.containsKey(schema)) { // process alias case String alias = aliases.get(schema); int pointPos = alias.indexOf('.'); schema = alias.substring(0, pointPos); table = alias.substring(pointPos + 1); column = cursorArgument.getColumn(); List<CharSequence> columnCandidates = new ArrayList(); - int columnRes = - completeColumn( - schema, table, column, cursorArgument.getCursorPosition(), columnCandidates); + int columnRes = completeColumn(schema, table, column, cursorArgument.getCursorPosition(), + columnCandidates); addCompletions(candidates, columnCandidates, CompletionType.column.name()); // process schema.table case } else if (cursorArgument.getTable() != null && cursorArgument.getColumn() == null) { List<CharSequence> tableCandidates = new ArrayList(); table = cursorArgument.getTable(); - int tableRes = - completeTable(schema, table, cursorArgument.getCursorPosition(), tableCandidates); + int tableRes = completeTable(schema, table, cursorArgument.getCursorPosition(), + tableCandidates); addCompletions(candidates, tableCandidates, CompletionType.table.name()); return tableRes; } else { List<CharSequence> columnCandidates = new ArrayList(); table = cursorArgument.getTable(); column = cursorArgument.getColumn(); - int columnRes = - completeColumn( - schema, table, column, cursorArgument.getCursorPosition(), columnCandidates); + int columnRes = completeColumn(schema, table, column, cursorArgument.getCursorPosition(), + columnCandidates); addCompletions(candidates, columnCandidates, CompletionType.column.name()); } } @@ -511,13 +497,11 @@ public class SqlCompleter { return this.sqlDelimiter; } - private void addCompletions( - List<InterpreterCompletion> interpreterCompletions, - List<CharSequence> candidates, - String meta) { + private void addCompletions(List<InterpreterCompletion> interpreterCompletions, + List<CharSequence> candidates, String meta) { for (CharSequence candidate : candidates) { - interpreterCompletions.add( - new InterpreterCompletion(candidate.toString(), candidate.toString(), meta)); + interpreterCompletions.add(new InterpreterCompletion(candidate.toString(), + candidate.toString(), meta)); } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0d746fa2/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java ---------------------------------------------------------------------- diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java index 22f4703..b093ab2 100644 --- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java +++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/security/JDBCSecurityImpl.java @@ -19,29 +19,31 @@ package org.apache.zeppelin.jdbc.security; import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.KERBEROS; import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.SIMPLE; -import java.io.IOException; -import java.util.Properties; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** Created for org.apache.zeppelin.jdbc.security on 09/07/16. */ +import java.io.IOException; +import java.util.Properties; + +/** + * Created for org.apache.zeppelin.jdbc.security on 09/07/16. + */ public class JDBCSecurityImpl { private static final Logger LOGGER = LoggerFactory.getLogger(JDBCSecurityImpl.class); - /** - * * - * + /*** * @param properties */ - public static void createSecureConfiguration( - Properties properties, AuthenticationMethod authType) { + public static void createSecureConfiguration(Properties properties, + AuthenticationMethod authType) { switch (authType) { case KERBEROS: - Configuration conf = new org.apache.hadoop.conf.Configuration(); + Configuration conf = new + org.apache.hadoop.conf.Configuration(); conf.set("hadoop.security.authentication", KERBEROS.toString()); UserGroupInformation.setConfiguration(conf); try { @@ -55,13 +57,12 @@ public class JDBCSecurityImpl { properties.getProperty("zeppelin.jdbc.principal"), properties.getProperty("zeppelin.jdbc.keytab.location")); } else { - LOGGER.info( - "The user has already logged in using Keytab and principal, " - + "no action required"); + LOGGER.info("The user has already logged in using Keytab and principal, " + + "no action required"); } } catch (IOException e) { - LOGGER.error( - "Failed to get either keytab location or principal name in the " + "interpreter", e); + LOGGER.error("Failed to get either keytab location or principal name in the " + + "interpreter", e); } } } @@ -69,14 +70,11 @@ public class JDBCSecurityImpl { public static AuthenticationMethod getAuthtype(Properties properties) { AuthenticationMethod authType; try { - authType = - AuthenticationMethod.valueOf( - properties.getProperty("zeppelin.jdbc.auth.type").trim().toUpperCase()); + authType = AuthenticationMethod.valueOf(properties.getProperty("zeppelin.jdbc.auth.type") + .trim().toUpperCase()); } catch (Exception e) { - LOGGER.error( - String.format( - "Invalid auth.type detected with value %s, defaulting " + "auth.type to SIMPLE", - properties.getProperty("zeppelin.jdbc.auth.type"))); + LOGGER.error(String.format("Invalid auth.type detected with value %s, defaulting " + + "auth.type to SIMPLE", properties.getProperty("zeppelin.jdbc.auth.type"))); authType = SIMPLE; } return authType; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0d746fa2/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterInterpolationTest.java ---------------------------------------------------------------------- diff --git a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterInterpolationTest.java b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterInterpolationTest.java index d602f95..d55f9fe 100644 --- a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterInterpolationTest.java +++ b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterInterpolationTest.java @@ -5,26 +5,16 @@ * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * - * <p>http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * <p>Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. */ package org.apache.zeppelin.jdbc; -import static java.lang.String.format; -import static org.junit.Assert.assertEquals; - import com.mockrunner.jdbc.BasicJDBCTestCaseAdapter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.Statement; -import java.util.Properties; import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterResult; import org.apache.zeppelin.resource.LocalResourcePool; @@ -33,7 +23,20 @@ import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.Before; import org.junit.Test; -/** JDBC interpreter Z-variable interpolation unit tests. */ +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import java.util.Properties; + +import static java.lang.String.format; +import static org.junit.Assert.assertEquals; + +/** + * JDBC interpreter Z-variable interpolation unit tests. + */ public class JDBCInterpreterInterpolationTest extends BasicJDBCTestCaseAdapter { private static String jdbcConnection; @@ -55,24 +58,22 @@ public class JDBCInterpreterInterpolationTest extends BasicJDBCTestCaseAdapter { Connection connection = DriverManager.getConnection(getJdbcConnection()); Statement statement = connection.createStatement(); statement.execute( - "DROP TABLE IF EXISTS test_table; " - + "CREATE TABLE test_table(id varchar(255), name varchar(255));"); + "DROP TABLE IF EXISTS test_table; " + + "CREATE TABLE test_table(id varchar(255), name varchar(255));"); Statement insertStatement = connection.createStatement(); - insertStatement.execute( - "insert into test_table(id, name) values " - + "('pro', 'processor')," - + "('mem', 'memory')," - + "('key', 'keyboard')," - + "('mou', 'mouse');"); + insertStatement.execute("insert into test_table(id, name) values " + + "('pro', 'processor')," + + "('mem', 'memory')," + + "('key', 'keyboard')," + + "('mou', 'mouse');"); resourcePool = new LocalResourcePool("JdbcInterpolationTest"); - interpreterContext = - InterpreterContext.builder() - .setParagraphId("paragraph_1") - .setAuthenticationInfo(new AuthenticationInfo("testUser")) - .setResourcePool(resourcePool) - .build(); + interpreterContext = InterpreterContext.builder() + .setParagraphId("paragraph_1") + .setAuthenticationInfo(new AuthenticationInfo("testUser")) + .setResourcePool(resourcePool) + .build(); } @Test @@ -109,7 +110,8 @@ public class JDBCInterpreterInterpolationTest extends BasicJDBCTestCaseAdapter { assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code()); assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType()); assertEquals(1, interpreterResult.message().size()); - assertEquals("ID\tNAME\nmem\tmemory\n", interpreterResult.message().get(0).getData()); + assertEquals("ID\tNAME\nmem\tmemory\n", + interpreterResult.message().get(0).getData()); } @Test @@ -147,7 +149,8 @@ public class JDBCInterpreterInterpolationTest extends BasicJDBCTestCaseAdapter { assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code()); assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType()); assertEquals(1, interpreterResult.message().size()); - assertEquals("ID\tNAME\nkey\tkeyboard\n", interpreterResult.message().get(0).getData()); + assertEquals("ID\tNAME\nkey\tkeyboard\n", + interpreterResult.message().get(0).getData()); } @Test @@ -174,7 +177,8 @@ public class JDBCInterpreterInterpolationTest extends BasicJDBCTestCaseAdapter { assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code()); assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType()); assertEquals(1, interpreterResult.message().size()); - assertEquals( - "ID\tNAME\nkey\tkeyboard\nmou\tmouse\n", interpreterResult.message().get(0).getData()); + assertEquals("ID\tNAME\nkey\tkeyboard\nmou\tmouse\n", + interpreterResult.message().get(0).getData()); } + } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0d746fa2/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java ---------------------------------------------------------------------- diff --git a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java index f66e2dd..62f6550 100644 --- a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java +++ b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java @@ -5,31 +5,36 @@ * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * - * <p>http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * <p>Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. */ package org.apache.zeppelin.jdbc; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import static java.lang.String.format; + import static org.apache.zeppelin.jdbc.JDBCInterpreter.COMMON_MAX_LINE; import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_DRIVER; import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_PASSWORD; -import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_PRECODE; import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_STATEMENT_PRECODE; -import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_URL; import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_USER; +import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_URL; +import static org.apache.zeppelin.jdbc.JDBCInterpreter.DEFAULT_PRECODE; import static org.apache.zeppelin.jdbc.JDBCInterpreter.PRECODE_KEY_TEMPLATE; + +import org.junit.Before; +import org.junit.Test; import static org.apache.zeppelin.jdbc.JDBCInterpreter.STATEMENT_PRECODE_KEY_TEMPLATE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import com.mockrunner.jdbc.BasicJDBCTestCaseAdapter; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -42,6 +47,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; + +import com.mockrunner.jdbc.BasicJDBCTestCaseAdapter; + import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterException; @@ -53,10 +61,10 @@ import org.apache.zeppelin.scheduler.Scheduler; import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.user.UserCredentials; import org.apache.zeppelin.user.UsernamePassword; -import org.junit.Before; -import org.junit.Test; -/** JDBC interpreter unit tests. */ +/** + * JDBC interpreter unit tests. + */ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { static String jdbcConnection; InterpreterContext interpreterContext; @@ -87,36 +95,40 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { Connection connection = DriverManager.getConnection(getJdbcConnection()); Statement statement = connection.createStatement(); statement.execute( - "DROP TABLE IF EXISTS test_table; " - + "CREATE TABLE test_table(id varchar(255), name varchar(255));"); + "DROP TABLE IF EXISTS test_table; " + + "CREATE TABLE test_table(id varchar(255), name varchar(255));"); - PreparedStatement insertStatement = - connection.prepareStatement( + PreparedStatement insertStatement = connection.prepareStatement( "insert into test_table(id, name) values ('a', 'a_name'),('b', 'b_name'),('c', ?);"); insertStatement.setString(1, null); insertStatement.execute(); - interpreterContext = - InterpreterContext.builder() - .setAuthenticationInfo(new AuthenticationInfo("testUser")) - .build(); + interpreterContext = InterpreterContext.builder() + .setAuthenticationInfo(new AuthenticationInfo("testUser")) + .build(); } + @Test public void testForParsePropertyKey() { JDBCInterpreter t = new JDBCInterpreter(new Properties()); Map<String, String> localProperties = new HashMap<>(); - InterpreterContext interpreterContext = - InterpreterContext.builder().setLocalProperties(localProperties).build(); + InterpreterContext interpreterContext = InterpreterContext.builder() + .setLocalProperties(localProperties) + .build(); assertEquals(JDBCInterpreter.DEFAULT_KEY, t.getPropertyKey(interpreterContext)); localProperties = new HashMap<>(); localProperties.put("db", "mysql"); - interpreterContext = InterpreterContext.builder().setLocalProperties(localProperties).build(); + interpreterContext = InterpreterContext.builder() + .setLocalProperties(localProperties) + .build(); assertEquals("mysql", t.getPropertyKey(interpreterContext)); localProperties = new HashMap<>(); localProperties.put("hive", "hive"); - interpreterContext = InterpreterContext.builder().setLocalProperties(localProperties).build(); + interpreterContext = InterpreterContext.builder() + .setLocalProperties(localProperties) + .build(); assertEquals("hive", t.getPropertyKey(interpreterContext)); } @@ -135,11 +147,10 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { String sqlQuery = "select * from test_table"; Map<String, String> localProperties = new HashMap<>(); localProperties.put("db", "fake"); - InterpreterContext context = - InterpreterContext.builder() - .setAuthenticationInfo(new AuthenticationInfo("testUser")) - .setLocalProperties(localProperties) - .build(); + InterpreterContext context = InterpreterContext.builder() + .setAuthenticationInfo(new AuthenticationInfo("testUser")) + .setLocalProperties(localProperties) + .build(); InterpreterResult interpreterResult = t.interpret(sqlQuery, context); // if prefix not found return ERROR and Prefix not found. @@ -181,17 +192,17 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { @Test public void testSplitSqlQuery() throws SQLException, IOException { - String sqlQuery = - "insert into test_table(id, name) values ('a', ';\"');" - + "select * from test_table;" - + "select * from test_table WHERE ID = \";'\";" - + "select * from test_table WHERE ID = ';';" - + "select '\n', ';';" - + "select replace('A\\;B', '\\', 'text');" - + "select '\\', ';';" - + "select '''', ';';" - + "select /*+ scan */ * from test_table;" - + "--singleLineComment\nselect * from test_table"; + String sqlQuery = "insert into test_table(id, name) values ('a', ';\"');" + + "select * from test_table;" + + "select * from test_table WHERE ID = \";'\";" + + "select * from test_table WHERE ID = ';';" + + "select '\n', ';';" + + "select replace('A\\;B', '\\', 'text');" + + "select '\\', ';';" + + "select '''', ';';" + + "select /*+ scan */ * from test_table;" + + "--singleLineComment\nselect * from test_table"; + Properties properties = new Properties(); JDBCInterpreter t = new JDBCInterpreter(properties); @@ -212,11 +223,10 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { @Test public void testQueryWithEscapedCharacters() throws SQLException, IOException { - String sqlQuery = - "select '\\n', ';';" - + "select replace('A\\;B', '\\', 'text');" - + "select '\\', ';';" - + "select '''', ';'"; + String sqlQuery = "select '\\n', ';';" + + "select replace('A\\;B', '\\', 'text');" + + "select '\\', ';';" + + "select '''', ';'"; Properties properties = new Properties(); properties.setProperty("common.max_count", "1000"); @@ -255,14 +265,15 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { JDBCInterpreter t = new JDBCInterpreter(properties); t.open(); - String sqlQuery = "select * from test_table;" + "select * from test_table WHERE ID = ';';"; + String sqlQuery = "select * from test_table;" + + "select * from test_table WHERE ID = ';';"; InterpreterResult interpreterResult = t.interpret(sqlQuery, interpreterContext); assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code()); assertEquals(2, interpreterResult.message().size()); assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType()); - assertEquals( - "ID\tNAME\na\ta_name\nb\tb_name\nc\tnull\n", interpreterResult.message().get(0).getData()); + assertEquals("ID\tNAME\na\ta_name\nb\tb_name\nc\tnull\n", + interpreterResult.message().get(0).getData()); assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(1).getType()); assertEquals("ID\tNAME\n", interpreterResult.message().get(1).getData()); @@ -280,14 +291,15 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { JDBCInterpreter t = new JDBCInterpreter(properties); t.open(); - String sqlQuery = "select * from test_table;" + "select * from test_table WHERE ID = ';';"; + String sqlQuery = "select * from test_table;" + + "select * from test_table WHERE ID = ';';"; InterpreterResult interpreterResult = t.interpret(sqlQuery, interpreterContext); assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code()); assertEquals(1, interpreterResult.message().size()); assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType()); - assertEquals( - "ID\tNAME\na\ta_name\nb\tb_name\nc\tnull\n", interpreterResult.message().get(0).getData()); + assertEquals("ID\tNAME\na\ta_name\nb\tb_name\nc\tnull\n", + interpreterResult.message().get(0).getData()); } @Test @@ -311,6 +323,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { assertEquals("ID\tNAME\nc\tnull\n", interpreterResult.message().get(0).getData()); } + @Test public void testSelectQueryMaxResult() throws SQLException, IOException { Properties properties = new Properties(); @@ -371,11 +384,11 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { jdbcInterpreter.interpret("", interpreterContext); - List<InterpreterCompletion> completionList = - jdbcInterpreter.completion("sel", 3, interpreterContext); + List<InterpreterCompletion> completionList = jdbcInterpreter.completion("sel", 3, + interpreterContext); - InterpreterCompletion correctCompletionKeyword = - new InterpreterCompletion("select", "select", CompletionType.keyword.name()); + InterpreterCompletion correctCompletionKeyword = new InterpreterCompletion("select", "select", + CompletionType.keyword.name()); assertEquals(1, completionList.size()); assertEquals(true, completionList.contains(correctCompletionKeyword)); @@ -396,8 +409,8 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { return properties; } - private AuthenticationInfo getUserAuth( - String user, String entityName, String dbUser, String dbPassword) { + private AuthenticationInfo getUserAuth(String user, String entityName, String dbUser, + String dbPassword) { UserCredentials userCredentials = new UserCredentials(); if (entityName != null && dbUser != null && dbPassword != null) { UsernamePassword up = new UsernamePassword(dbUser, dbPassword); @@ -427,11 +440,10 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { // user1 runs jdbc1 jdbc1.open(); - InterpreterContext ctx1 = - InterpreterContext.builder() - .setAuthenticationInfo(user1Credential) - .setReplName("jdbc1") - .build(); + InterpreterContext ctx1 = InterpreterContext.builder() + .setAuthenticationInfo(user1Credential) + .setReplName("jdbc1") + .build(); jdbc1.interpret("", ctx1); JDBCUserConfigurations user1JDBC1Conf = jdbc1.getJDBCConfiguration("user1"); @@ -441,11 +453,10 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { // user1 runs jdbc2 jdbc2.open(); - InterpreterContext ctx2 = - InterpreterContext.builder() - .setAuthenticationInfo(user1Credential) - .setReplName("jdbc2") - .build(); + InterpreterContext ctx2 = InterpreterContext.builder() + .setAuthenticationInfo(user1Credential) + .setReplName("jdbc2") + .build(); jdbc2.interpret("", ctx2); JDBCUserConfigurations user1JDBC2Conf = jdbc2.getJDBCConfiguration("user1"); @@ -455,11 +466,10 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { // user2 runs jdbc1 jdbc1.open(); - InterpreterContext ctx3 = - InterpreterContext.builder() - .setAuthenticationInfo(user2Credential) - .setReplName("jdbc1") - .build(); + InterpreterContext ctx3 = InterpreterContext.builder() + .setAuthenticationInfo(user2Credential) + .setReplName("jdbc1") + .build(); jdbc1.interpret("", ctx3); JDBCUserConfigurations user2JDBC1Conf = jdbc1.getJDBCConfiguration("user2"); @@ -469,11 +479,10 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { // user2 runs jdbc2 jdbc2.open(); - InterpreterContext ctx4 = - InterpreterContext.builder() - .setAuthenticationInfo(user2Credential) - .setReplName("jdbc2") - .build(); + InterpreterContext ctx4 = InterpreterContext.builder() + .setAuthenticationInfo(user2Credential) + .setReplName("jdbc2") + .build(); jdbc2.interpret("", ctx4); JDBCUserConfigurations user2JDBC2Conf = jdbc2.getJDBCConfiguration("user2"); @@ -489,9 +498,8 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { properties.setProperty("default.url", getJdbcConnection()); properties.setProperty("default.user", ""); properties.setProperty("default.password", ""); - properties.setProperty( - DEFAULT_PRECODE, - "create table test_precode (id int); insert into test_precode values (1);"); + properties.setProperty(DEFAULT_PRECODE, + "create table test_precode (id int); insert into test_precode values (1);"); JDBCInterpreter jdbcInterpreter = new JDBCInterpreter(properties); jdbcInterpreter.open(); jdbcInterpreter.executePrecode(interpreterContext); @@ -533,19 +541,17 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { properties.setProperty("anotherPrefix.url", getJdbcConnection()); properties.setProperty("anotherPrefix.user", ""); properties.setProperty("anotherPrefix.password", ""); - properties.setProperty( - String.format(PRECODE_KEY_TEMPLATE, "anotherPrefix"), - "create table test_precode_2 (id int); insert into test_precode_2 values (2);"); + properties.setProperty(String.format(PRECODE_KEY_TEMPLATE, "anotherPrefix"), + "create table test_precode_2 (id int); insert into test_precode_2 values (2);"); JDBCInterpreter jdbcInterpreter = new JDBCInterpreter(properties); jdbcInterpreter.open(); Map<String, String> localProperties = new HashMap<>(); localProperties.put("db", "anotherPrefix"); - InterpreterContext context = - InterpreterContext.builder() - .setAuthenticationInfo(new AuthenticationInfo("testUser")) - .setLocalProperties(localProperties) - .build(); + InterpreterContext context = InterpreterContext.builder() + .setAuthenticationInfo(new AuthenticationInfo("testUser")) + .setLocalProperties(localProperties) + .build(); jdbcInterpreter.executePrecode(context); String sqlQuery = "select * from test_precode_2"; @@ -603,19 +609,17 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { properties.setProperty("anotherPrefix.url", getJdbcConnection()); properties.setProperty("anotherPrefix.user", ""); properties.setProperty("anotherPrefix.password", ""); - properties.setProperty( - String.format(STATEMENT_PRECODE_KEY_TEMPLATE, "anotherPrefix"), - "set @v='statementAnotherPrefix'"); + properties.setProperty(String.format(STATEMENT_PRECODE_KEY_TEMPLATE, "anotherPrefix"), + "set @v='statementAnotherPrefix'"); JDBCInterpreter jdbcInterpreter = new JDBCInterpreter(properties); jdbcInterpreter.open(); Map<String, String> localProperties = new HashMap<>(); localProperties.put("db", "anotherPrefix"); - InterpreterContext context = - InterpreterContext.builder() - .setAuthenticationInfo(new AuthenticationInfo("testUser")) - .setLocalProperties(localProperties) - .build(); + InterpreterContext context = InterpreterContext.builder() + .setAuthenticationInfo(new AuthenticationInfo("testUser")) + .setLocalProperties(localProperties) + .build(); String sqlQuery = "select @v"; @@ -639,17 +643,16 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { JDBCInterpreter t = new JDBCInterpreter(properties); t.open(); - String sqlQuery = - "/* ; */\n" - + "-- /* comment\n" - + "--select * from test_table\n" - + "select * from test_table; /* some comment ; */\n" - + "/*\n" - + "select * from test_table;\n" - + "*/\n" - + "-- a ; b\n" - + "select * from test_table WHERE ID = ';--';\n" - + "select * from test_table WHERE ID = '/*' -- test"; + String sqlQuery = "/* ; */\n" + + "-- /* comment\n" + + "--select * from test_table\n" + + "select * from test_table; /* some comment ; */\n" + + "/*\n" + + "select * from test_table;\n" + + "*/\n" + + "-- a ; b\n" + + "select * from test_table WHERE ID = ';--';\n" + + "select * from test_table WHERE ID = '/*' -- test"; InterpreterResult interpreterResult = t.interpret(sqlQuery, interpreterContext); assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code());
