diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/security/HadoopThriftAuthBridge.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/security/HadoopThriftAuthBridge.java index b21b072..814ae10 100644 --- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/security/HadoopThriftAuthBridge.java +++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/security/HadoopThriftAuthBridge.java @@ -40,6 +40,8 @@ import javax.security.sasl.SaslServer; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.pool.KeyedPoolableObjectFactory; +import org.apache.commons.pool.impl.GenericKeyedObjectPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.hadoop.conf.Configuration; @@ -568,6 +570,28 @@ public void handle(Callback[] callbacks) throws InvalidToken, } } + static class UgiFactory implements KeyedPoolableObjectFactory { + @Override + public Object makeObject(Object key) throws Exception { + return UserGroupInformation.createProxyUser((String)key, UserGroupInformation.getLoginUser()); + } + + @Override + public void destroyObject(Object key, Object obj) throws Exception { + FileSystem.closeAllForUGI((UserGroupInformation)obj); + } + @Override + public boolean validateObject(Object key, Object obj) { + return true; + } + @Override + public void activateObject(Object key, Object obj) throws Exception { + } + @Override + public void passivateObject(Object key, Object obj) throws Exception { + } + } + /** * Processor that pulls the SaslServer object out of the transport, and * assumes the remote user's UGI before calling through to the original @@ -579,6 +603,9 @@ public void handle(Callback[] callbacks) throws InvalidToken, final TProcessor wrapped; DelegationTokenSecretManager secretManager; boolean useProxy; + GenericKeyedObjectPool ugiCache = new GenericKeyedObjectPool(new UgiFactory(), + 1000, GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW, 0, 10, + false, false, 24*60*5, 0, 0, false); TUGIAssumingProcessor(TProcessor wrapped, DelegationTokenSecretManager secretManager, boolean useProxy) { this.wrapped = wrapped; @@ -623,46 +650,45 @@ public boolean process(final TProtocol inProt, final TProtocol outProt) throws T UserGroupInformation clientUgi = null; try { - if (useProxy) { - clientUgi = UserGroupInformation.createProxyUser( - endUser, UserGroupInformation.getLoginUser()); - remoteUser.set(clientUgi.getShortUserName()); - LOG.debug("Set remoteUser :" + remoteUser.get()); - return clientUgi.doAs(new PrivilegedExceptionAction() { - - @Override - public Boolean run() { - try { - return wrapped.process(inProt, outProt); - } catch (TException te) { - throw new RuntimeException(te); + try { + if (useProxy) { + clientUgi = (UserGroupInformation)ugiCache.borrowObject(endUser); + remoteUser.set(clientUgi.getShortUserName()); + LOG.debug("Set remoteUser :" + remoteUser.get()); + return clientUgi.doAs(new PrivilegedExceptionAction() { + + @Override + public Boolean run() { + try { + return wrapped.process(inProt, outProt); + } catch (TException te) { + throw new RuntimeException(te); + } } - } - }); - } else { - // use the short user name for the request - UserGroupInformation endUserUgi = UserGroupInformation.createRemoteUser(endUser); - remoteUser.set(endUserUgi.getShortUserName()); - LOG.debug("Set remoteUser :" + remoteUser.get() + ", from endUser :" + endUser); - return wrapped.process(inProt, outProt); - } - } catch (RuntimeException rte) { - if (rte.getCause() instanceof TException) { - throw (TException)rte.getCause(); + }); + } else { + // use the short user name for the request + UserGroupInformation endUserUgi = UserGroupInformation.createRemoteUser(endUser); + remoteUser.set(endUserUgi.getShortUserName()); + LOG.debug("Set remoteUser :" + remoteUser.get() + ", from endUser :" + endUser); + return wrapped.process(inProt, outProt); + } + } catch (RuntimeException rte) { + if (rte.getCause() instanceof TException) { + throw (TException)rte.getCause(); + } + throw rte; + } finally { + if (clientUgi != null) { + ugiCache.returnObject(endUser, clientUgi); + } } - throw rte; } catch (InterruptedException ie) { throw new RuntimeException(ie); // unexpected! } catch (IOException ioe) { throw new RuntimeException(ioe); // unexpected! - } - finally { - if (clientUgi != null) { - try { FileSystem.closeAllForUGI(clientUgi); } - catch(IOException exception) { - LOG.error("Could not clean up file-system handles for UGI: " + clientUgi, exception); - } - } + } catch (Exception e) { + throw new RuntimeException(e); // unexpected! } } }