This is an automated email from the ASF dual-hosted git repository.
nihaljain pushed a commit to branch branch-2.4
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2.4 by this push:
new 0391eb11ff1 HBASE-28110 Align TestShadeSaslAuthenticationProvider
between different branches (#5478) (#5434)
0391eb11ff1 is described below
commit 0391eb11ff11db9cb01d432e462a3c0f556eff10
Author: Nihal Jain <[email protected]>
AuthorDate: Wed Oct 25 18:06:13 2023 +0530
HBASE-28110 Align TestShadeSaslAuthenticationProvider between different
branches (#5478) (#5434)
Signed-off-by: Duo Zhang <[email protected]>
---
.../TestShadeSaslAuthenticationProvider.java | 102 +++++++++++++++++----
1 file changed, 84 insertions(+), 18 deletions(-)
diff --git
a/hbase-examples/src/test/java/org/apache/hadoop/hbase/security/provider/example/TestShadeSaslAuthenticationProvider.java
b/hbase-examples/src/test/java/org/apache/hadoop/hbase/security/provider/example/TestShadeSaslAuthenticationProvider.java
index 1fcea26d0d4..75894d69b0a 100644
---
a/hbase-examples/src/test/java/org/apache/hadoop/hbase/security/provider/example/TestShadeSaslAuthenticationProvider.java
+++
b/hbase-examples/src/test/java/org/apache/hadoop/hbase/security/provider/example/TestShadeSaslAuthenticationProvider.java
@@ -17,17 +17,23 @@
*/
package org.apache.hadoop.hbase.security.provider.example;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.hadoop.conf.Configuration;
@@ -60,8 +66,11 @@ import
org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.SecurityTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.CommonFSUtils;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.ipc.RemoteException;
import org.apache.hadoop.minikdc.MiniKdc;
import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.SecretManager.InvalidToken;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -70,9 +79,15 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TestName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.hbase.thirdparty.com.google.common.base.Throwables;
@Category({ MediumTests.class, SecurityTests.class })
public class TestShadeSaslAuthenticationProvider {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(TestShadeSaslAuthenticationProvider.class);
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
@@ -112,8 +127,8 @@ public class TestShadeSaslAuthenticationProvider {
if (fs.exists(p)) {
fs.delete(p, true);
}
- try (FSDataOutputStream out = fs.create(p);
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)))
{
+ try (FSDataOutputStream out = fs.create(p); BufferedWriter writer =
+ new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
{
for (Entry<String, char[]> e : userDatabase.entrySet()) {
writer.write(e.getKey());
writer.write(ShadeSaslServerAuthenticationProvider.SEPARATOR);
@@ -218,28 +233,79 @@ public class TestShadeSaslAuthenticationProvider {
@Test
public void testNegativeAuthentication() throws Exception {
- // Validate that we can read that record back out as the user with our
custom auth'n
- final Configuration clientConf = new Configuration(CONF);
- clientConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3);
- try (Connection conn = ConnectionFactory.createConnection(clientConf)) {
- UserGroupInformation user1 =
- UserGroupInformation.createUserForTesting("user1", new String[0]);
- user1.addToken(
- ShadeClientTokenUtil.obtainToken(conn, "user1", "not a real
password".toCharArray()));
- // Server will close the connection directly once auth failed, so at
client side, we do not
- // know what is the real problem so we will keep retrying, until reached
the max retry times
- // limitation
- assertThrows("Should not successfully authenticate with HBase",
- RetriesExhaustedException.class, () -> user1.doAs(new
PrivilegedExceptionAction<Void>() {
+ List<Pair<String, Class<? extends Exception>>> params = new ArrayList<>();
+ // ZK based connection will fail on the master RPC
+ params.add(new Pair<String, Class<? extends Exception>>(
+ // ZKConnectionRegistry is package-private
+ HConstants.ZK_CONNECTION_REGISTRY_CLASS,
RetriesExhaustedException.class));
+
+ params.forEach((pair) -> {
+ LOG.info("Running negative authentication test for client registry {},
expecting {}",
+ pair.getFirst(), pair.getSecond().getName());
+ // Validate that we can read that record back out as the user with our
custom auth'n
+ final Configuration clientConf = new Configuration(CONF);
+ clientConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3);
+ clientConf.set(HConstants.CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY,
pair.getFirst());
+ try (Connection conn = ConnectionFactory.createConnection(clientConf)) {
+ UserGroupInformation user1 =
+ UserGroupInformation.createUserForTesting("user1", new String[0]);
+ user1.addToken(
+ ShadeClientTokenUtil.obtainToken(conn, "user1", "not a real
password".toCharArray()));
+
+ LOG.info("Executing request to HBase Master which should fail");
+ user1.doAs(new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection conn =
ConnectionFactory.createConnection(clientConf);) {
+ conn.getAdmin().listTableDescriptors();
+ fail("Should not successfully authenticate with HBase");
+ } catch (Exception e) {
+ LOG.info("Caught exception in negative Master connectivity
test", e);
+ assertEquals("Found unexpected exception", pair.getSecond(),
e.getClass());
+ validateRootCause(Throwables.getRootCause(e));
+ }
+ return null;
+ }
+ });
+
+ LOG.info("Executing request to HBase RegionServer which should fail");
+ user1.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
try (Connection conn =
ConnectionFactory.createConnection(clientConf);
Table t = conn.getTable(tableName)) {
t.get(new Get(Bytes.toBytes("r1")));
- return null;
+ fail("Should not successfully authenticate with HBase");
+ } catch (Exception e) {
+ LOG.info("Caught exception in negative RegionServer connectivity
test", e);
+ assertEquals("Found unexpected exception", pair.getSecond(),
e.getClass());
+ validateRootCause(Throwables.getRootCause(e));
}
+ return null;
}
- }));
+ });
+ } catch (InterruptedException e) {
+ LOG.error("Caught interrupted exception", e);
+ Thread.currentThread().interrupt();
+ return;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ void validateRootCause(Throwable rootCause) {
+ LOG.info("Root cause was", rootCause);
+ if (rootCause instanceof RemoteException) {
+ RemoteException re = (RemoteException) rootCause;
+ IOException actualException = re.unwrapRemoteException();
+ assertEquals(InvalidToken.class, actualException.getClass());
+ } else {
+ StringWriter writer = new StringWriter();
+ rootCause.printStackTrace(new PrintWriter(writer));
+ String text = writer.toString();
+ assertTrue("Message did not contain expected text",
+ text.contains("Connection reset by peer"));
}
}
}