[
https://issues.apache.org/jira/browse/PHOENIX-3189?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15439795#comment-15439795
]
ASF GitHub Bot commented on PHOENIX-3189:
-----------------------------------------
Github user joshelser commented on a diff in the pull request:
https://github.com/apache/phoenix/pull/191#discussion_r76484922
--- Diff:
phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java
---
@@ -333,6 +337,55 @@ public ConnectionInfo normalize(ReadOnlyProps props)
throws SQLException {
keytab =
props.get(QueryServices.HBASE_CLIENT_KEYTAB);
}
}
+ if (!isConnectionless()) {
+ boolean credsProvidedInUrl = null != principal && null !=
keytab;
+ boolean credsProvidedInProps =
info.containsKey(QueryServices.HBASE_CLIENT_PRINCIPAL) &&
info.containsKey(QueryServices.HBASE_CLIENT_KEYTAB);
+ if (credsProvidedInUrl || credsProvidedInProps) {
+ // PHOENIX-3189 Because ConnectionInfo is immutable,
we must make sure all parts of it are correct before
+ // construction; this also requires the Kerberos user
credentials object (since they are compared by reference
+ // and not by value. If the user provided a principal
and keytab via the JDBC url, we must make sure that the
+ // Kerberos login happens *before* we construct the
ConnectionInfo object. Otherwise, the use of ConnectionInfo
+ // to determine when ConnectionQueryServices impl's
should be reused will be broken.
+ Configuration config =
HBaseFactoryProvider.getConfigurationFactory().getConfiguration();
+ // Add QueryServices properties
+ for (Entry<String,String> entry : props) {
+ config.set(entry.getKey(), entry.getValue());
+ }
+ // Add any user-provided properties (via DriverManager)
+ if (info != null) {
+ for (Object key : info.keySet()) {
+ config.set((String) key,
info.getProperty((String) key));
+ }
+ }
+ // Set the principal and keytab if provided from the
URL (overriding those provided in Properties)
+ if (null != principal) {
+ config.set(QueryServices.HBASE_CLIENT_PRINCIPAL,
principal);
+ }
+ if (null != keytab) {
+ config.set(QueryServices.HBASE_CLIENT_KEYTAB,
keytab);
+ }
+ try {
+ // Check if we need to authenticate with kerberos
so that we cache the correct ConnectionInfo
+ UserGroupInformation currentUser =
UserGroupInformation.getCurrentUser();
+ if (!currentUser.hasKerberosCredentials() ||
!currentUser.getUserName().equals(principal)) {
--- End diff --
Yes, good catch. Can definitely do this only when necessary.
> HBase/ZooKeeper connection leaks when providing principal/keytab in JDBC url
> ----------------------------------------------------------------------------
>
> Key: PHOENIX-3189
> URL: https://issues.apache.org/jira/browse/PHOENIX-3189
> Project: Phoenix
> Issue Type: Bug
> Affects Versions: 4.8.0
> Reporter: Josh Elser
> Assignee: Josh Elser
> Priority: Blocker
> Fix For: 4.9.0, 4.8.1
>
>
> We've been doing some more testing after PHOENIX-3126 and, with the help of
> [~arpitgupta] and [~harsha_ch], we've found an issue in a test between Storm
> and Phoenix.
> Storm was configured to create a JDBC Bolt, specifying the principal and
> keytab in the JDBC URL, relying on PhoenixDriver to do the Kerberos login for
> them. After PHOENIX-3126, a ZK server blacklisted the host running the bolt,
> and we observed that there were over 140 active ZK threads in the JVM.
> This results in a subtle change where every time the client tries to get a
> new Connection, we end up getting a new UGI instance (because the
> {{ConnectionQueryServicesImpl#openConnection()}} always does a new login).
> If users are correctly caching Connections, there isn't an issue (best as I
> can presently tell). However, if users rely on the getting the same
> connection every time (the pre-PHOENIX-3126), they will saturate their local
> JVM with connections and crash.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)