diff --git a/ql/src/test/org/apache/hadoop/hive/ql/security/SleepyMetastoreAuthorizationProvider.java b/ql/src/test/org/apache/hadoop/hive/ql/security/SleepyMetastoreAuthorizationProvider.java new file mode 100644 index 0000000..de38555 --- /dev/null +++ b/ql/src/test/org/apache/hadoop/hive/ql/security/SleepyMetastoreAuthorizationProvider.java @@ -0,0 +1,153 @@ +/** + * 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.hadoop.hive.ql.security; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hive.metastore.HiveMetaStore.HMSHandler; +import org.apache.hadoop.hive.metastore.api.Database; +import org.apache.hadoop.hive.ql.metadata.AuthorizationException; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.metadata.Partition; +import org.apache.hadoop.hive.ql.metadata.Table; +import org.apache.hadoop.hive.ql.security.authorization.HiveMetastoreAuthorizationProvider; +import org.apache.hadoop.hive.ql.security.authorization.Privilege; + +/** + * SleepyMetastoreAuthorizationProvider : This is not really an authorizer, but + * something that is used to test that AuthorizationProviders are being tested + * in a thread-safe manner. On any authorization call, it simply sleeps for + * SLEEPYTIME milliseconds, and then returns, throwing an error if the user + * has somehow magically changed in the meanwhile. This can happen if there is + * another parallel call being made to the metastore as some other user, and + * access to the authentication provider is not made in a threadsafe manner. + */ + +public class SleepyMetastoreAuthorizationProvider implements HiveMetastoreAuthorizationProvider { + private Configuration conf; + public static final Log LOG = LogFactory.getLog( + SleepyMetastoreAuthorizationProvider.class); + protected HiveAuthenticationProvider authenticator; + + public static long SLEEPYTIME = 15000; // 10k milliseconds = 10 seconds + public static long INITIALIZATION_PADDING = 5000; // 5 seconds + + private static final List failures = new ArrayList(); + + public static List getExceptions() { + return failures; + } + + @Override + public Configuration getConf() { + return this.conf; + } + + @Override + public void setConf(Configuration conf) { + this.conf = conf; + try { + init(conf); + } catch (HiveException e) { + throw new RuntimeException(e); + } + } + + @Override + public HiveAuthenticationProvider getAuthenticator() { + return authenticator; + } + + @Override + public void setAuthenticator(HiveAuthenticationProvider authenticator) { + this.authenticator = authenticator; + } + + @Override + public void authorize(Privilege[] readRequiredPriv, Privilege[] writeRequiredPriv) + throws HiveException, AuthorizationException { + doAuth(); + } + + @Override + public void authorize(Database db, Privilege[] readRequiredPriv, Privilege[] writeRequiredPriv) + throws HiveException, AuthorizationException { + doAuth(); + } + + @Override + public void authorize(Table table, Privilege[] readRequiredPriv, Privilege[] writeRequiredPriv) + throws HiveException, AuthorizationException { + doAuth(); + } + + @Override + public void authorize(Partition part, Privilege[] readRequiredPriv, Privilege[] writeRequiredPriv) + throws HiveException, AuthorizationException { + doAuth(); + } + + @Override + public void authorize(Table table, Partition part, List columns, + Privilege[] readRequiredPriv, Privilege[] writeRequiredPriv) throws HiveException, + AuthorizationException { + doAuth(); + } + + private void doAuth() throws HiveException, AuthorizationException { + String u1 = authenticator.getUserName(); + try { + Thread.sleep(SLEEPYTIME); + } catch (InterruptedException e) { + // we do not expect another thread interrupting us, so we wrap and throw this. + throw new HiveException(e); + } + String u2 = authenticator.getUserName(); + if (!u1.equalsIgnoreCase(u2)){ + String errorLog = + "User mismatch, user at beginning was [" + + u1 + +"], user at end was [" + + u2 + +"]"; + debugLog(errorLog); + AuthorizationException ae = new AuthorizationException(errorLog); + failures.add(ae); + throw ae; + } + } + + @Override + public void setMetaStoreHandler(HMSHandler handler) { + debugLog("SMAP.setMetaStoreHandler"); + } + + @Override + public void init(Configuration conf) throws HiveException { + debugLog("SMAP.init"); + } + + private void debugLog(String s) { + LOG.debug(s); + } + +}