diff --git a/service/src/java/org/apache/hive/service/cli/CLIService.java b/service/src/java/org/apache/hive/service/cli/CLIService.java index 0d5ae1e491bdcf98a12f5eef7b35f23c7b9dfc00..49be13bd05db1307d21d33f3fafa8bcb44fcbe5a 100644 --- a/service/src/java/org/apache/hive/service/cli/CLIService.java +++ b/service/src/java/org/apache/hive/service/cli/CLIService.java @@ -201,6 +201,18 @@ public SessionHandle openSession(String username, String password, Map configuration) + throws HiveSQLException { + SessionHandle result = sessionManager.restoreSession(sessionHandle, SERVER_VERSION, username, password, + configuration, false, null); + LOG.debug(sessionHandle + ": restoreSession()"); + return result; + } + /* (non-Javadoc) * @see org.apache.hive.service.cli.ICLIService#openSession(java.lang.String, java.lang.String, java.util.Map) */ diff --git a/service/src/java/org/apache/hive/service/cli/SessionHandle.java b/service/src/java/org/apache/hive/service/cli/SessionHandle.java index 4e4f0211de09408168c8da669626fb49f3db364c..9fc30c6b49a4f01c906fead5a569035d6b79706e 100644 --- a/service/src/java/org/apache/hive/service/cli/SessionHandle.java +++ b/service/src/java/org/apache/hive/service/cli/SessionHandle.java @@ -45,7 +45,10 @@ public SessionHandle(TSessionHandle tSessionHandle, TProtocolVersion protocol) { super(tSessionHandle.getSessionId()); this.protocol = protocol; } - + public SessionHandle(HandleIdentifier handleId, TProtocolVersion protocol) { + super(handleId); + this.protocol = protocol; + } public UUID getSessionId() { return getHandleIdentifier().getPublicId(); } diff --git a/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java b/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java index 3c5700bd114f6b792df10df23e57dad9b9e689f6..c909df80162cab81299e443500c37a2aa28820f2 100644 --- a/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java +++ b/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java @@ -111,15 +111,25 @@ private volatile long lastAccessTime; private volatile long lastIdleTime; - public HiveSessionImpl(TProtocolVersion protocol, String username, String password, + public HiveSessionImpl(SessionHandle sessionHandle, TProtocolVersion protocol, String username, String password, HiveConf serverhiveConf, String ipAddress) { + this(sessionHandle, protocol, username, password, serverhiveConf, null, ipAddress); + } + + public HiveSessionImpl(SessionHandle sessionHandle, TProtocolVersion protocol, String username, String password, + HiveConf serverhiveConf, Map sessionConfMap, String ipAddress) { this.username = username; this.password = password; creationTime = System.currentTimeMillis(); - this.sessionHandle = new SessionHandle(protocol); + this.sessionHandle = sessionHandle; this.hiveConf = new HiveConf(serverhiveConf); this.ipAddress = ipAddress; - + //set conf properties specified by user from client side + if (sessionConfMap != null) { + for (Map.Entry entry : sessionConfMap.entrySet()) { + hiveConf.verifyAndSet(entry.getKey(), entry.getValue()); + } + } try { // In non-impersonation mode, map scheduler queue to current user // if fair scheduler is configured. @@ -139,6 +149,17 @@ public HiveSessionImpl(TProtocolVersion protocol, String username, String passwo hiveConf.setInt(ListSinkOperator.OUTPUT_PROTOCOL, protocol.getValue()); } + public HiveSessionImpl(TProtocolVersion protocol, String username, String password, + HiveConf serverhiveConf, String ipAddress) { + this(protocol, username, password, serverhiveConf, null, ipAddress); + } + + public HiveSessionImpl(TProtocolVersion protocol, String username, String password, + HiveConf serverhiveConf, Map sessionConf, String ipAddress) { + this(new SessionHandle(protocol), protocol, username, password, serverhiveConf, sessionConf, ipAddress); + } + + @Override /** * Opens a new HiveServer2 session for the client connection. 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 de18f1d93502704e7a8fbb8d31d93bd770c4d232..5580417ba171506eadb5cb2204245d21894fbcf4 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 @@ -43,10 +43,12 @@ import org.apache.hadoop.hive.conf.HiveConf.ConfVars; import org.apache.hadoop.hive.ql.hooks.HookUtils; import org.apache.hive.service.CompositeService; +import org.apache.hive.service.auth.TSetIpAddressProcessor; import org.apache.hive.service.cli.HiveSQLException; import org.apache.hive.service.cli.SessionHandle; import org.apache.hive.service.cli.operation.Operation; import org.apache.hive.service.cli.operation.OperationManager; +import org.apache.hive.service.rpc.thrift.TOpenSessionReq; import org.apache.hive.service.rpc.thrift.TProtocolVersion; import org.apache.hive.service.server.HiveServer2; import org.apache.hive.service.server.ThreadFactoryWithGarbageCleanup; @@ -260,7 +262,7 @@ public SessionHandle openSession(TProtocolVersion protocol, String username, Str * The username passed to this method is the effective username. * If withImpersonation is true (==doAs true) we wrap all the calls in HiveSession * within a UGI.doAs, where UGI corresponds to the effective user. - * @see org.apache.hive.service.cli.thrift.ThriftCLIService#getUserName() + * @see org.apache.hive.service.cli.thrift.ThriftCLIService#getUserName(TOpenSessionReq) * * @param protocol * @param username @@ -275,6 +277,13 @@ public SessionHandle openSession(TProtocolVersion protocol, String username, Str public SessionHandle openSession(TProtocolVersion protocol, String username, String password, String ipAddress, Map sessionConf, boolean withImpersonation, String delegationToken) throws HiveSQLException { + return createSession(null, protocol, username, password, ipAddress, sessionConf, + withImpersonation, delegationToken).getSessionHandle(); + } + public HiveSession createSession(SessionHandle sessionHandle, TProtocolVersion protocol, String username, String password, String ipAddress, + Map sessionConf, boolean withImpersonation, String delegationToken) + throws HiveSQLException { + HiveSession session; // 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 @@ -286,9 +295,10 @@ public SessionHandle openSession(TProtocolVersion protocol, String username, Str } 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}); + Constructor constructor = clazz.getConstructor(TProtocolVersion.class, String.class, String.class, + HiveConf.class, String.class, String.class); + hiveSessionUgi = (HiveSessionImplwithUGI) constructor.newInstance( + protocol, username, password, hiveConf, ipAddress, delegationToken); } catch (Exception e) { throw new HiveSQLException("Cannot initilize session class:" + sessionImplWithUGIclassName); } @@ -296,17 +306,24 @@ public SessionHandle openSession(TProtocolVersion protocol, String username, Str session = HiveSessionProxy.getProxy(hiveSessionUgi, hiveSessionUgi.getSessionUgi()); hiveSessionUgi.setProxySession(session); } else { - 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); + Class sessionImplClass = HiveSessionImpl.class; + try { + if (sessionImplclassName != null) { + sessionImplClass = Class.forName(sessionImplclassName); } + if (sessionHandle != null) { + Constructor constructor = sessionImplClass.getConstructor(SessionHandle.class, TProtocolVersion.class, + String.class, String.class, HiveConf.class, Map.class, String.class); + session = (HiveSession) constructor.newInstance(sessionHandle, protocol, username, password, + hiveConf, sessionConf, TSetIpAddressProcessor.getUserIpAddress()); + } else { + Constructor constructor = sessionImplClass.getConstructor(TProtocolVersion.class, + String.class, String.class, HiveConf.class, Map.class, String.class); + session = (HiveSession) constructor.newInstance(protocol, username, password, + hiveConf, sessionConf, TSetIpAddressProcessor.getUserIpAddress()); + } + } catch (Exception e) { + throw new HiveSQLException("Cannot initilize session class:" + sessionImplclassName, e); } } session.setSessionManager(this); @@ -339,9 +356,15 @@ public SessionHandle openSession(TProtocolVersion protocol, String username, Str throw new HiveSQLException("Failed to execute session hooks: " + e.getMessage(), e); } handleToSession.put(session.getSessionHandle(), session); + return session; + } + public SessionHandle restoreSession(SessionHandle sessionHandle, TProtocolVersion protocol, String username, String password, + Map sessionConf, boolean withImpersonation, String delegationToken) + throws HiveSQLException { + HiveSession session = createSession(sessionHandle, protocol, username, password, null, sessionConf, + withImpersonation, delegationToken); return session.getSessionHandle(); } - public void closeSession(SessionHandle sessionHandle) throws HiveSQLException { HiveSession session = handleToSession.remove(sessionHandle); if (session == null) { diff --git a/service/src/test/org/apache/hive/service/cli/CLIServiceRestoreTest.java b/service/src/test/org/apache/hive/service/cli/CLIServiceRestoreTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7d8151ab6aace2082aa404a15b968663edd60b44 --- /dev/null +++ b/service/src/test/org/apache/hive/service/cli/CLIServiceRestoreTest.java @@ -0,0 +1,45 @@ +/** + * 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.service.cli; + + +import org.apache.hadoop.hive.conf.HiveConf; + +import org.junit.Assert; +import org.junit.Test; + +public class CLIServiceRestoreTest { + + CLIService service = getService(); + + @Test + public void testRestore() throws HiveSQLException { + SessionHandle session = service.openSession("foo", "bar", null); + service.stop(); + service = getService(); + SessionHandle restoredSession = service.restoreSession(session, "foo", "bar", null); + Assert.assertEquals(session, restoredSession); + } + + public CLIService getService() { + CLIService service = new CLIService(null); + service.init(new HiveConf()); + service.start(); + return service; + } +}