HIVE-10435 : Make HiveSession implementation pluggable through configuration (Akshay Goyal, reviewed by Amareshwari)
Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/5b67f352 Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/5b67f352 Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/5b67f352 Branch: refs/heads/hbase-metastore Commit: 5b67f35232cf9f9323e999fbbaac0a8ddffc6954 Parents: 16546cc Author: Akshay Goyal <akshaygoyal2...@gmail.com> Authored: Thu Aug 13 16:12:14 2015 +0530 Committer: Amareshwari Sriramadasu <amareshw...@apache.org> Committed: Thu Aug 13 16:12:14 2015 +0530 ---------------------------------------------------------------------- .../org/apache/hadoop/hive/conf/HiveConf.java | 3 ++ .../service/cli/session/SessionManager.java | 42 +++++++++++++-- .../session/TestPluggableHiveSessionImpl.java | 55 ++++++++++++++++++++ 3 files changed, 95 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/5b67f352/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java ---------------------------------------------------------------------- diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java index 9cc7987..d1cb5fb 100644 --- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java +++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java @@ -1869,6 +1869,9 @@ public class HiveConf extends Configuration { new TimeValidator(TimeUnit.MILLISECONDS), "Time that HiveServer2 will wait before responding to asynchronous calls that use long polling"), + HIVE_SESSION_IMPL_CLASSNAME("hive.session.impl.classname", null, "Classname for custom implementation of hive session"), + HIVE_SESSION_IMPL_WITH_UGI_CLASSNAME("hive.session.impl.withugi.classname", null, "Classname for custom implementation of hive session with UGI"), + // HiveServer2 auth configuration HIVE_SERVER2_AUTHENTICATION("hive.server2.authentication", "NONE", new StringSet("NOSASL", "NONE", "LDAP", "KERBEROS", "PAM", "CUSTOM"), http://git-wip-us.apache.org/repos/asf/hive/blob/5b67f352/service/src/java/org/apache/hive/service/cli/session/SessionManager.java ---------------------------------------------------------------------- diff --git a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java index c46bbce..77c5e66 100644 --- a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java +++ b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java @@ -20,6 +20,7 @@ package org.apache.hive.service.cli.session; import java.io.File; import java.io.IOException; +import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -67,6 +68,8 @@ public class SessionManager extends CompositeService { private volatile boolean shutdown; // The HiveServer2 instance running this service private final HiveServer2 hiveServer2; + private String sessionImplWithUGIclassName; + private String sessionImplclassName; public SessionManager(HiveServer2 hiveServer2) { super(SessionManager.class.getSimpleName()); @@ -82,9 +85,15 @@ public class SessionManager extends CompositeService { } createBackgroundOperationPool(); addService(operationManager); + initSessionImplClassName(); super.init(hiveConf); } + private void initSessionImplClassName() { + this.sessionImplclassName = hiveConf.getVar(ConfVars.HIVE_SESSION_IMPL_CLASSNAME); + this.sessionImplWithUGIclassName = hiveConf.getVar(ConfVars.HIVE_SESSION_IMPL_WITH_UGI_CLASSNAME); + } + private void createBackgroundOperationPool() { int poolSize = hiveConf.getIntVar(ConfVars.HIVE_SERVER2_ASYNC_EXEC_THREADS); LOG.info("HiveServer2: Background operation thread pool size: " + poolSize); @@ -245,12 +254,35 @@ public class SessionManager extends CompositeService { // If doAs is set to true for HiveServer2, we will create a proxy object for the session impl. // Within the proxy object, we wrap the method call in a UserGroupInformation#doAs if (withImpersonation) { - HiveSessionImplwithUGI sessionWithUGI = new HiveSessionImplwithUGI(protocol, username, password, - hiveConf, ipAddress, delegationToken); - session = HiveSessionProxy.getProxy(sessionWithUGI, sessionWithUGI.getSessionUgi()); - sessionWithUGI.setProxySession(session); + HiveSessionImplwithUGI hiveSessionUgi; + if (sessionImplWithUGIclassName == null) { + hiveSessionUgi = new HiveSessionImplwithUGI(protocol, username, password, + hiveConf, ipAddress, delegationToken); + } else { + try { + Class<?> clazz = Class.forName(sessionImplWithUGIclassName); + Constructor<?> constructor = clazz.getConstructor(String.class, String.class, Map.class, String.class); + hiveSessionUgi = (HiveSessionImplwithUGI) constructor.newInstance(new Object[] + {protocol, username, password, hiveConf, ipAddress, delegationToken}); + } catch (Exception e) { + throw new HiveSQLException("Cannot initilize session class:" + sessionImplWithUGIclassName); + } + } + session = HiveSessionProxy.getProxy(hiveSessionUgi, hiveSessionUgi.getSessionUgi()); + hiveSessionUgi.setProxySession(session); } else { - session = new HiveSessionImpl(protocol, username, password, hiveConf, ipAddress); + if (sessionImplclassName == null) { + session = new HiveSessionImpl(protocol, username, password, hiveConf, ipAddress); + } else { + try { + Class<?> clazz = Class.forName(sessionImplclassName); + Constructor<?> constructor = clazz.getConstructor(String.class, String.class, Map.class); + session = (HiveSession) constructor.newInstance(new Object[] + {protocol, username, password, hiveConf, ipAddress}); + } catch (Exception e) { + throw new HiveSQLException("Cannot initilize session class:" + sessionImplclassName); + } + } } session.setSessionManager(this); session.setOperationManager(operationManager); http://git-wip-us.apache.org/repos/asf/hive/blob/5b67f352/service/src/test/org/apache/hive/service/cli/session/TestPluggableHiveSessionImpl.java ---------------------------------------------------------------------- diff --git a/service/src/test/org/apache/hive/service/cli/session/TestPluggableHiveSessionImpl.java b/service/src/test/org/apache/hive/service/cli/session/TestPluggableHiveSessionImpl.java new file mode 100644 index 0000000..8c7546c --- /dev/null +++ b/service/src/test/org/apache/hive/service/cli/session/TestPluggableHiveSessionImpl.java @@ -0,0 +1,55 @@ +package org.apache.hive.service.cli.session; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hive.service.cli.CLIService; +import org.apache.hive.service.cli.HiveSQLException; +import org.apache.hive.service.cli.SessionHandle; +import org.apache.hive.service.cli.thrift.TProtocolVersion; +import org.apache.hive.service.cli.thrift.ThriftBinaryCLIService; +import org.apache.hive.service.cli.thrift.ThriftCLIService; +import org.apache.hive.service.cli.thrift.ThriftCLIServiceClient; +import org.junit.Before; +import org.junit.Test; + +public class TestPluggableHiveSessionImpl extends TestCase { + + private HiveConf hiveConf; + private CLIService cliService; + private ThriftCLIServiceClient client; + private ThriftCLIService service; + + @Override + @Before + public void setUp() { + hiveConf = new HiveConf(); + hiveConf.setVar(HiveConf.ConfVars.HIVE_SESSION_IMPL_CLASSNAME, TestHiveSessionImpl.class.getName()); + cliService = new CLIService(null); + service = new ThriftBinaryCLIService(cliService); + service.init(hiveConf); + client = new ThriftCLIServiceClient(service); + } + + + @Test + public void testSessionImpl() { + SessionHandle sessionHandle = null; + try { + sessionHandle = client.openSession("tom", "password"); + Assert.assertEquals(TestHiveSessionImpl.class.getName(), + service.getHiveConf().getVar(HiveConf.ConfVars.HIVE_SESSION_IMPL_CLASSNAME)); + Assert.assertTrue(cliService.getSessionManager().getSession(sessionHandle) instanceof TestHiveSessionImpl); + client.closeSession(sessionHandle); + } catch (HiveSQLException e) { + e.printStackTrace(); + } + } + + class TestHiveSessionImpl extends HiveSessionImpl { + + public TestHiveSessionImpl(TProtocolVersion protocol, String username, String password, HiveConf serverhiveConf, String ipAddress) { + super(protocol, username, password, serverhiveConf, ipAddress); + } + } +}