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 <bod.de...@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 <k...@rxd.hu>, Daniel Dai <dai...@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); + } +}