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..6aee80c1451a01670a8c0dfb279dc7c43c5f99c0 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,15 @@ private volatile long lastAccessTime; private volatile long lastIdleTime; - public HiveSessionImpl(TProtocolVersion protocol, String username, String password, - HiveConf serverhiveConf, String ipAddress) { + + public HiveSessionImpl(SessionHandle sessionHandle, TProtocolVersion protocol, String username, String password, + HiveConf serverhiveConf, String ipAddress) { this.username = username; this.password = password; creationTime = System.currentTimeMillis(); - this.sessionHandle = new SessionHandle(protocol); + this.sessionHandle = sessionHandle != null ? sessionHandle : new SessionHandle(protocol); this.hiveConf = new HiveConf(serverhiveConf); this.ipAddress = ipAddress; - try { // In non-impersonation mode, map scheduler queue to current user // if fair scheduler is configured. @@ -132,13 +132,19 @@ public HiveSessionImpl(TProtocolVersion protocol, String username, String passwo } // Set an explicit session name to control the download directory name hiveConf.set(ConfVars.HIVESESSIONID.varname, - sessionHandle.getHandleIdentifier().toString()); + this.sessionHandle.getHandleIdentifier().toString()); // Use thrift transportable formatter hiveConf.set(ListSinkOperator.OUTPUT_FORMATTER, FetchFormatter.ThriftFormatter.class.getName()); hiveConf.setInt(ListSinkOperator.OUTPUT_PROTOCOL, protocol.getValue()); } + public HiveSessionImpl(TProtocolVersion protocol, String username, String password, + HiveConf serverhiveConf, String ipAddress) { + this(null, protocol, username, password, serverhiveConf, ipAddress); + } + + @Override /** * Opens a new HiveServer2 session for the client connection. diff --git a/service/src/java/org/apache/hive/service/cli/session/HiveSessionImplwithUGI.java b/service/src/java/org/apache/hive/service/cli/session/HiveSessionImplwithUGI.java index c56d97afc969ea57810e9b3222b20e086e847d67..ab4d12f594bdd53b746a100375a8e2dd0c34632b 100644 --- a/service/src/java/org/apache/hive/service/cli/session/HiveSessionImplwithUGI.java +++ b/service/src/java/org/apache/hive/service/cli/session/HiveSessionImplwithUGI.java @@ -30,6 +30,7 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hive.service.auth.HiveAuthFactory; import org.apache.hive.service.cli.HiveSQLException; +import org.apache.hive.service.cli.SessionHandle; import org.apache.hive.service.rpc.thrift.TProtocolVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,9 +50,13 @@ private HiveSession proxySession = null; - public HiveSessionImplwithUGI(TProtocolVersion protocol, String username, String password, - HiveConf hiveConf, String ipAddress, String delegationToken) throws HiveSQLException { - super(protocol, username, password, hiveConf, ipAddress); + public HiveSessionImplwithUGI(TProtocolVersion protocol, String username, + String password, HiveConf hiveConf, String ipAddress, String delegationToken) throws HiveSQLException { + this(null, protocol, username, password, hiveConf, ipAddress, delegationToken); + } + public HiveSessionImplwithUGI(SessionHandle sessionHandle, TProtocolVersion protocol, String username, + String password, HiveConf hiveConf, String ipAddress, String delegationToken) throws HiveSQLException { + super(sessionHandle, protocol, username, password, hiveConf, ipAddress); setSessionUGI(username); setDelegationToken(delegationToken); } 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..66e6d5ea59f67db73e1fb4252666f029c2a2ab65 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,20 +277,28 @@ 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 if (withImpersonation) { HiveSessionImplwithUGI hiveSessionUgi; if (sessionImplWithUGIclassName == null) { - hiveSessionUgi = new HiveSessionImplwithUGI(protocol, username, password, + hiveSessionUgi = new HiveSessionImplwithUGI(sessionHandle, 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}); + Constructor constructor = clazz.getConstructor(SessionHandle.class, TProtocolVersion.class, String.class, + String.class, HiveConf.class, String.class, String.class); + hiveSessionUgi = (HiveSessionImplwithUGI) constructor.newInstance(sessionHandle, + protocol, username, password, hiveConf, ipAddress, delegationToken); } catch (Exception e) { throw new HiveSQLException("Cannot initilize session class:" + sessionImplWithUGIclassName); } @@ -297,15 +307,17 @@ public SessionHandle openSession(TProtocolVersion protocol, String username, Str hiveSessionUgi.setProxySession(session); } else { if (sessionImplclassName == null) { - session = new HiveSessionImpl(protocol, username, password, hiveConf, ipAddress); + session = new HiveSessionImpl(sessionHandle, protocol, username, password, hiveConf, + TSetIpAddressProcessor.getUserIpAddress()); } 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}); + Class clazz = Class.forName(sessionImplclassName); + Constructor constructor = clazz.getConstructor(SessionHandle.class, TProtocolVersion.class, + String.class, String.class, HiveConf.class, String.class); + session = (HiveSession) constructor.newInstance(sessionHandle, protocol, username, password, + hiveConf, TSetIpAddressProcessor.getUserIpAddress()); } catch (Exception e) { - throw new HiveSQLException("Cannot initilize session class:" + sessionImplclassName); + throw new HiveSQLException("Cannot initilize session class:" + sessionImplclassName, e); } } } @@ -339,9 +351,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; + } +}