Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions docs/interpreter/jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ There are more JDBC interpreter properties you can specify like below.
</tr>
<tr>
<td>zeppelin.jdbc.auth.kerberos.proxy.enable</td>
     <td>When auth type is Kerberos, enable/disable Kerberos proxy with the login user to get the connection. Default value is true.</td>
<td>When auth type is Kerberos, enable/disable Kerberos proxy with the login user to get the connection. Default value is true.</td>
</tr>
<tr>
<td>default.jceks.file</td>
Expand Down Expand Up @@ -202,7 +202,7 @@ To bind the interpreters created in the interpreter setting page, click the gear

<img src="../assets/themes/zeppelin/img/docs-img/click_interpreter_binding_button.png" width="600px" />

Select(blue) or deselect(white) the interpreter buttons depending on your use cases.
Select(blue) or deselect(white) the interpreter buttons depending on your use cases.
If you need to use more than one interpreter in the notebook, activate several buttons.
Don't forget to click `Save` button, or you will face `Interpreter *** is not found` error.

Expand Down Expand Up @@ -285,7 +285,7 @@ An example settings of interpreter for the two data sources, each of which has i
</table>

##### Usage
Test of execution *precode* for each data source.
Test of execution *precode* for each data source.

```sql
%jdbc
Expand Down Expand Up @@ -480,7 +480,7 @@ Here are some examples you can refer to. Including the below connectors, you can

[Maven Repository: com.amazonaws:aws-java-sdk-redshift](https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-redshift)

### Apache Hive
### Apache Hive

<img src="../assets/themes/zeppelin/img/docs-img/hive_setting.png" width="600px" />

Expand All @@ -507,12 +507,11 @@ Here are some examples you can refer to. Including the below connectors, you can
<td>hive_password</td>
</tr>
<tr>
<td>hive.proxy.user</td>
<td>true or false</td>
<td>default.proxy.user.property</td>
<td>Example value: hive.server2.proxy.user</td>
</tr>
</table>

Connection to Hive JDBC with a proxy user can be disabled with `hive.proxy.user` property (set to true by default)

[Apache Hive 1 JDBC Driver Docs](https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-JDBC)
[Apache Hive 2 JDBC Driver Docs](https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-JDBC)

Expand All @@ -534,6 +533,26 @@ Connection to Hive JDBC with a proxy user can be disabled with `hive.proxy.user`

[Maven Repository : org.apache.hive:hive-jdbc](https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc)

##### Impersonation
When Zeppelin server is running with authentication enabled, then the interpreter can utilize Hive's user proxy feature i.e. send extra parameter for creating and running a session ("hive.server2.proxy.user=": "${loggedInUser}"). This is particularly useful when multiple users are sharing a notebooks.

To enable this set following:
- `zeppelin.jdbc.auth.type` as `SIMPLE` or `KERBEROS` (if required) in the interpreter setting.
- `${prefix}.proxy.user.property` as `hive.server2.proxy.user`
Example configuration

*Properties*

| name | value |
|:------------------------- |:--------------------------------------------------------------------------------------------------|
| hive.driver | org.apache.hive.jdbc.HiveDriver |
| hive.password | |
| hive.url | jdbc:hive2://hive-server-host:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2 |
| hive.proxy.user.property | hive.proxy.user.property |
| zeppelin.jdbc.auth.type | SIMPLE |



### Apache Phoenix

Phoenix supports `thick` and `thin` connection types:
Expand Down
66 changes: 35 additions & 31 deletions jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

Expand Down Expand Up @@ -179,10 +178,6 @@ public void open() {
}
logger.debug("JDBC PropretiesMap: {}", basePropretiesMap);

if (!isEmpty(property.getProperty("zeppelin.jdbc.auth.type"))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also removed? zeppelin.jdbc.auth.type?

Copy link
Contributor Author

@prabhjyotsingh prabhjyotsingh Apr 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JDBCSecurityImpl.createSecureConfiguration call is moved to line#358 (https://github.com/apache/zeppelin/pull/2229/files/9fee9d2a9e476769b5d28a50d17f3a7ad38fc453#diff-ecdae8ee9594a5c4b21a3c217a3f130cR358). Instead of making this object JDBCSecurityImpl.getAuthtype(property) every time on open() do it only if required.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ok, doc change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's just a removal of extra call, so no doc change required.

JDBCSecurityImpl.createSecureConfiguration(property);
}

setMaxLineResults();
}

Expand Down Expand Up @@ -358,65 +353,74 @@ public Connection getConnection(String propertyKey, InterpreterContext interpret
} else {
UserGroupInformation.AuthenticationMethod authType = JDBCSecurityImpl.getAuthtype(property);

final String connectionUrl = appendProxyUserToURL(url, user, propertyKey);

JDBCSecurityImpl.createSecureConfiguration(property, authType);
switch (authType) {
case KERBEROS:
if (user == null || "false".equalsIgnoreCase(
property.getProperty("zeppelin.jdbc.auth.kerberos.proxy.enable"))) {
connection = getConnectionFromPool(url, user, propertyKey, properties);
property.getProperty("zeppelin.jdbc.auth.kerberos.proxy.enable"))) {
connection = getConnectionFromPool(connectionUrl, user, propertyKey, properties);
} else {
if (url.trim().startsWith("jdbc:hive")) {
StringBuilder connectionUrl = new StringBuilder(url);
Integer lastIndexOfUrl = connectionUrl.indexOf("?");
if (lastIndexOfUrl == -1) {
lastIndexOfUrl = connectionUrl.length();
}
boolean hasProxyUser = property.containsKey("hive.proxy.user");
if (!hasProxyUser || !property.getProperty("hive.proxy.user").equals("false")){
logger.debug("Using hive proxy user");
connectionUrl.insert(lastIndexOfUrl, ";hive.server2.proxy.user=" + user + ";");
}
connection = getConnectionFromPool(connectionUrl.toString(),
user, propertyKey, properties);
if (basePropretiesMap.get(propertyKey).containsKey("proxy.user.property")) {
connection = getConnectionFromPool(connectionUrl, user, propertyKey, properties);
} else {
UserGroupInformation ugi = null;
try {
ugi = UserGroupInformation.createProxyUser(
user, UserGroupInformation.getCurrentUser());
user, UserGroupInformation.getCurrentUser());
} catch (Exception e) {
logger.error("Error in getCurrentUser", e);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(e.getMessage()).append("\n");
stringBuilder.append(e.getCause());
throw new InterpreterException(stringBuilder.toString());
throw new InterpreterException("Error in getCurrentUser", e);
}

final String poolKey = propertyKey;
try {
connection = ugi.doAs(new PrivilegedExceptionAction<Connection>() {
@Override
public Connection run() throws Exception {
return getConnectionFromPool(url, user, poolKey, properties);
return getConnectionFromPool(connectionUrl, user, poolKey, properties);
}
});
} catch (Exception e) {
logger.error("Error in doAs", e);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(e.getMessage()).append("\n");
stringBuilder.append(e.getCause());
throw new InterpreterException(stringBuilder.toString());
throw new InterpreterException("Error in doAs", e);
}
}
}
break;

default:
connection = getConnectionFromPool(url, user, propertyKey, properties);
connection = getConnectionFromPool(connectionUrl, user, propertyKey, properties);
}
}

return connection;
}

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")) {

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 + ";");
} 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");
}

return connectionUrl.toString();
}

private String getPassword(Properties properties) throws IOException {
if (isNotEmpty(properties.getProperty(PASSWORD_KEY))) {
return properties.getProperty(PASSWORD_KEY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ public class JDBCSecurityImpl {
/***
* @param properties
*/
public static void createSecureConfiguration(Properties properties) {
AuthenticationMethod authType = getAuthtype(properties);

public static void createSecureConfiguration(Properties properties,
AuthenticationMethod authType) {
switch (authType) {
case KERBEROS:
Configuration conf = new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ public InterpreterException(String m) {
super(m);
}

public InterpreterException(String msg, Throwable t) {
super(msg, t);
}

}