You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by da...@apache.org on 2019/03/26 21:29:50 UTC

[hive] branch master updated: HIVE-21507: Hive swallows NPE if no delegation token found (Denes Bodo, reviewed by Zoltan Haindrich, Daniel Dai)

This is an automated email from the ASF dual-hosted git repository.

daijy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new afd7b5b  HIVE-21507: Hive swallows NPE if no delegation token found (Denes Bodo, reviewed by Zoltan Haindrich, Daniel Dai)
afd7b5b is described below

commit afd7b5b38556f638782606edbe6850ef70e1c8bb
Author: Denes Bodo <bo...@gmail.com>
AuthorDate: Tue Mar 26 14:25:45 2019 -0700

    HIVE-21507: Hive swallows NPE if no delegation token found (Denes Bodo, reviewed by Zoltan Haindrich, Daniel Dai)
    
    Signed-off-by: Zoltan Haindrich <ki...@rxd.hu>, Daniel Dai <da...@gmail.com>
---
 .../java/org/apache/hive/jdbc/HiveConnection.java  | 62 ++++++++++++++--------
 .../org/apache/hive/jdbc/TestHiveConnection.java   | 60 +++++++++++++++++++++
 2 files changed, 101 insertions(+), 21 deletions(-)

diff --git a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java
index 32a4761..4c7119f 100644
--- a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java
+++ b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java
@@ -760,29 +760,21 @@ public class HiveConnection implements java.sql.Connection {
   }
 
   // Lookup the delegation token. First in the connection URL, then Configuration
-  private String getClientDelegationToken(Map<String, String> jdbcConnConf)
-      throws SQLException {
+  private String getClientDelegationToken(Map<String, String> jdbcConnConf) throws SQLException {
     String tokenStr = null;
-    if (JdbcConnectionParams.AUTH_TOKEN.equalsIgnoreCase(jdbcConnConf.get(JdbcConnectionParams.AUTH_TYPE))) {
-      // check delegation token in job conf if any
+    if (!JdbcConnectionParams.AUTH_TOKEN.equalsIgnoreCase(jdbcConnConf.get(JdbcConnectionParams.AUTH_TYPE))) {
+      return null;
+    }
+    DelegationTokenFetcher fetcher = new DelegationTokenFetcher();
+    try {
+      tokenStr = fetcher.getTokenStringFromFile();
+    } catch (IOException e) {
+      LOG.warn("Cannot get token from environment variable $HADOOP_TOKEN_FILE_LOCATION=" +
+              System.getenv(UserGroupInformation.HADOOP_TOKEN_FILE_LOCATION));
+    }
+    if (tokenStr == null) {
       try {
-        if (System.getenv(UserGroupInformation.HADOOP_TOKEN_FILE_LOCATION) != null) {
-          try {
-            Credentials cred = new Credentials();
-            DataInputStream dis = new DataInputStream(new FileInputStream(System.getenv(UserGroupInformation
-                    .HADOOP_TOKEN_FILE_LOCATION)));
-            cred.readTokenStorageStream(dis);
-            dis.close();
-            Token<? extends TokenIdentifier> token = cred.getToken(new Text("hive"));
-            tokenStr = token.encodeToUrlString();
-          } catch (IOException e) {
-            LOG.warn("Cannot get token from environment variable $HADOOP_TOKEN_FILE_LOCATION=" +
-                    System.getenv(UserGroupInformation.HADOOP_TOKEN_FILE_LOCATION));
-          }
-        }
-        if (tokenStr == null) {
-          tokenStr = SessionUtils.getTokenStrForm(HiveAuthConstants.HS2_CLIENT_TOKEN);
-        }
+        return fetcher.getTokenFromSession();
       } catch (IOException e) {
         throw new SQLException("Error reading token ", e);
       }
@@ -790,6 +782,34 @@ public class HiveConnection implements java.sql.Connection {
     return tokenStr;
   }
 
+  static class DelegationTokenFetcher {
+    String getTokenStringFromFile() throws IOException {
+      if (System.getenv(UserGroupInformation.HADOOP_TOKEN_FILE_LOCATION) == null) {
+        return null;
+      }
+      Credentials cred = new Credentials();
+      try (DataInputStream dis = new DataInputStream(new FileInputStream(System.getenv(UserGroupInformation
+              .HADOOP_TOKEN_FILE_LOCATION)))) {
+        cred.readTokenStorageStream(dis);
+      }
+      return getTokenFromCredential(cred, "hive");
+    }
+
+    String getTokenFromCredential(Credentials cred, String key) throws IOException {
+      Token<? extends TokenIdentifier> token = cred.getToken(new Text(key));
+      if (token == null) {
+        LOG.warn("Delegation token with key: [hive] cannot be found.");
+        return null;
+      }
+      return token.encodeToUrlString();
+    }
+
+    String getTokenFromSession() throws IOException {
+      LOG.debug("Fetching delegation token from session.");
+      return SessionUtils.getTokenStrForm(HiveAuthConstants.HS2_CLIENT_TOKEN);
+    }
+  }
+
   private void openSession() throws SQLException {
     TOpenSessionReq openReq = new TOpenSessionReq();
 
diff --git a/jdbc/src/test/org/apache/hive/jdbc/TestHiveConnection.java b/jdbc/src/test/org/apache/hive/jdbc/TestHiveConnection.java
new file mode 100644
index 0000000..bcd2608
--- /dev/null
+++ b/jdbc/src/test/org/apache/hive/jdbc/TestHiveConnection.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.hive.jdbc;
+
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.security.token.Token;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestHiveConnection {
+
+  private static final String EXISTING_TOKEN = "ExistingToken";
+  public static final String EXPECTED_TOKEN_STRING_FORM = "AAAAAA";
+  private static HiveConnection.DelegationTokenFetcher fetcher;
+
+  @BeforeClass
+  public static void init() {
+    fetcher = new HiveConnection.DelegationTokenFetcher();
+  }
+
+  @Test
+  public void testIfNPEThrownWhileGettingDelegationToken() throws IOException {
+    try {
+      String tokenStr = fetcher.getTokenFromCredential(new Credentials(), "hive");
+      Assert.assertEquals("Token with id: hive shall not be found.", null, tokenStr);
+    } catch (NullPointerException e) {
+      Assert.fail("This NPE is not handled in the code elsewhere so user is not notified about it!");
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void testIfGettingDelegationTokenFromCredentialWorks() throws IOException {
+    Credentials creds = new Credentials();
+    creds.addToken(new Text(EXISTING_TOKEN), new Token<>());
+
+    String tokenStr = fetcher.getTokenFromCredential(creds, EXISTING_TOKEN);
+    Assert.assertEquals("Token string form is not as expected.", EXPECTED_TOKEN_STRING_FORM, tokenStr);
+  }
+}