获取 HiveServer2 委托令牌
要使用 HiveServer2 访问 Hive 元数据,您需要一个特殊的委托令牌。(请参阅自带您的委托令牌。)与授予 HDFS(数据)委托令牌的 REST API 不同,HiveServer2 不提供获取此令牌的简单方法。
以下实用程序代码显示了获取此令牌的方法。您需要为自己的群集修改此代码;特别是,更改 connectURL
静态的值。
import java.io.FileWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.security.PrivilegedExceptionAction;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.shims.Utils;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hive.jdbc.HiveConnection;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class JDBCTest {
public static final String driverName = "org.apache.hive.jdbc.HiveDriver";
public static String connectURL = "jdbc:hive2://node2.cluster0.example.com:2181,node1.cluster0.example.com:2181,node3.cluster0.example.com:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2";
public static String schemaName = "hcat";
public static String verticaUser = "condor";
public static String proxyUser = "condor-2";
public static String krb5conf = "/home/server/kerberos/krb5.conf";
public static String realm = "EXAMPLE.COM";
public static String keytab = "/home/server/kerberos/kt.keytab";
public static void main(String[] args) {
if (args.length < 7) {
System.out.println(
"Usage: JDBCTest <jdbc_url> <hive_schema> <kerberized_user> <proxy_user> <krb5_conf> <krb_realm> <krb_keytab>");
System.exit(1);
}
connectURL = args[0];
schemaName = args[1];
verticaUser = args[2];
proxyUser = args[3];
krb5conf = args[4];
realm = args[5];
keytab = args[6];
System.out.println("connectURL: " + connectURL);
System.out.println("schemaName: " + schemaName);
System.out.println("verticaUser: " + verticaUser);
System.out.println("proxyUser: " + proxyUser);
System.out.println("krb5conf: " + krb5conf);
System.out.println("realm: " + realm);
System.out.println("keytab: " + keytab);
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
System.out.println("Found HiveServer2 JDBC driver");
} catch (ClassNotFoundException e) {
System.out.println("Couldn't find HiveServer2 JDBC driver");
}
try {
Configuration conf = new Configuration();
System.setProperty("java.security.krb5.conf", krb5conf);
conf.set("hadoop.security.authentication", "kerberos");
UserGroupInformation.setConfiguration(conf);
dtTest();
} catch (Throwable e) {
Writer stackString = new StringWriter();
e.printStackTrace(new PrintWriter(stackString));
System.out.println(e);
System.out.printf("Error occurred when connecting to HiveServer2 with [%s]: %s\n%s\n",
new Object[] { connectURL, e.getMessage(), stackString.toString() });
}
}
private static void dtTest() throws Exception {
UserGroupInformation user = UserGroupInformation.loginUserFromKeytabAndReturnUGI(verticaUser + "@" + realm, keytab);
user.doAs(new PrivilegedExceptionAction() {
public Void run() throws Exception {
System.out.println("In doas: " + UserGroupInformation.getLoginUser());
Connection con = DriverManager.getConnection(JDBCTest.connectURL);
System.out.println("Connected to HiveServer2");
JDBCTest.showUser(con);
System.out.println("Getting delegation token for user");
String token = ((HiveConnection) con).getDelegationToken(JDBCTest.proxyUser, "hive/_HOST@" + JDBCTest.realm);
System.out.println("Got token: " + token);
System.out.println("Closing original connection");
con.close();
System.out.println("Setting delegation token in UGI");
Utils.setTokenStr(Utils.getUGI(), token, "hiveserver2ClientToken");
con = DriverManager.getConnection(JDBCTest.connectURL + ";auth=delegationToken");
System.out.println("Connected to HiveServer2 with delegation token");
JDBCTest.showUser(con);
con.close();
JDBCTest.writeDTJSON(token);
return null;
}
});
}
private static void showUser(Connection con) throws Exception {
String sql = "select current_user()";
Statement stmt = con.createStatement();
ResultSet res = stmt.executeQuery(sql);
StringBuilder result = new StringBuilder();
while (res.next()) {
result.append(res.getString(1));
}
System.out.println("\tcurrent_user: " + result.toString());
}
private static void writeDTJSON(String token) {
JSONArray arr = new JSONArray();
JSONObject obj = new JSONObject();
obj.put("schema", schemaName);
obj.put("token", token);
arr.add(obj);
try {
FileWriter fileWriter = new FileWriter("hcat_delegation.json");
fileWriter.write(arr.toJSONString());
fileWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
以下是一个调用及其输出的示例:
$ java -cp hs2token.jar JDBCTest 'jdbc:hive2://test.example.com:10000/default;principal=hive/_HOST@EXAMPLE.COM' "default" "testuser" "test" "/etc/krb5.conf" "EXAMPLE.COM" "/test/testuser.keytab"
connectURL: jdbc:hive2://test.example.com:10000/default;principal=hive/_HOST@EXAMPLE.COM
schemaName: default
verticaUser: testuser
proxyUser: test
krb5conf: /etc/krb5.conf
realm: EXAMPLE.COM
keytab: /test/testuser.keytab
Found HiveServer2 JDBC driver
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
In doas: testuser@EXAMPLE.COM (auth:KERBEROS)
Connected to HiveServer2
current_user: testuser
Getting delegation token for user
Got token: JQAEdGVzdARoaXZlB3JlbGVhc2WKAWgvBOwzigFoUxFwMwKOAgMUHfqJ5ma7_27LiePN8C7MxJ682bsVSElWRV9ERUxFR0FUSU9OX1RPS0VOFmhpdmVzZXJ2ZXIyQ2xpZW50VG9rZW4
Closing original connection
Setting delegation token in UGI
Connected to HiveServer2 with delegation token
current_user: testuser