HBASE-19795 Move the tests which only need zookeeper in TestZooKeeper to hbase-zookeeper module

This commit is contained in:
zhangduo 2018-01-15 10:57:51 +08:00
parent ffa28502c4
commit 8dd4bf8e54
9 changed files with 386 additions and 349 deletions

View File

@ -26,7 +26,6 @@ import static org.apache.hadoop.hbase.client.RegionInfo.DEFAULT_REPLICA_ID;
import java.util.Optional;
import java.util.stream.IntStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.yetus.audience.InterfaceAudience;
@ -184,11 +183,23 @@ public class ZNodePaths {
}
/**
* Join the prefix znode name with the suffix znode name to generate a proper
* full znode name.
*
* Returns whether the znode is supposed to be readable by the client and DOES NOT contain
* sensitive information (world readable).
*/
public boolean isClientReadable(String node) {
// Developer notice: These znodes are world readable. DO NOT add more znodes here UNLESS
// all clients need to access this data to work. Using zk for sharing data to clients (other
// than service lookup case is not a recommended design pattern.
return node.equals(baseZNode) || isAnyMetaReplicaZNode(node) ||
node.equals(masterAddressZNode) || node.equals(clusterIdZNode) || node.equals(rsZNode) ||
// /hbase/table and /hbase/table/foo is allowed, /hbase/table-lock is not
node.equals(tableZNode) || node.startsWith(tableZNode + "/");
}
/**
* Join the prefix znode name with the suffix znode name to generate a proper full znode name.
* <p>
* Assumes prefix does not end with slash and suffix does not begin with it.
*
* @param prefix beginning of znode name
* @param suffix ending of znode name
* @return result of properly joining prefix with suffix

View File

@ -0,0 +1,51 @@
/**
* 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.hbase.zookeeper;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.testclassification.ZKTests;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@Category({ ZKTests.class, SmallTests.class })
public class TestZNodePaths {
@Test
public void testIsClientReadable() {
ZNodePaths znodePaths = new ZNodePaths(HBaseConfiguration.create());
assertTrue(znodePaths.isClientReadable(znodePaths.baseZNode));
assertTrue(znodePaths.isClientReadable(znodePaths.getZNodeForReplica(0)));
assertTrue(znodePaths.isClientReadable(znodePaths.masterAddressZNode));
assertTrue(znodePaths.isClientReadable(znodePaths.clusterIdZNode));
assertTrue(znodePaths.isClientReadable(znodePaths.tableZNode));
assertTrue(znodePaths.isClientReadable(ZNodePaths.joinZNode(znodePaths.tableZNode, "foo")));
assertTrue(znodePaths.isClientReadable(znodePaths.rsZNode));
assertFalse(znodePaths.isClientReadable(znodePaths.tableLockZNode));
assertFalse(znodePaths.isClientReadable(znodePaths.balancerZNode));
assertFalse(znodePaths.isClientReadable(znodePaths.regionNormalizerZNode));
assertFalse(znodePaths.isClientReadable(znodePaths.clusterStateZNode));
assertFalse(znodePaths.isClientReadable(znodePaths.drainingZNode));
assertFalse(znodePaths.isClientReadable(znodePaths.splitLogZNode));
assertFalse(znodePaths.isClientReadable(znodePaths.backupMasterAddressesZNode));
}
}

View File

@ -159,7 +159,7 @@ public class IntegrationTestZKAndFSPermissions extends AbstractHBaseTool {
private void checkZnodePermsRecursive(ZKWatcher watcher,
RecoverableZooKeeper zk, String znode) throws KeeperException, InterruptedException {
boolean expectedWorldReadable = watcher.isClientReadable(znode);
boolean expectedWorldReadable = watcher.znodePaths.isClientReadable(znode);
assertZnodePerms(zk, znode, expectedWorldReadable);

View File

@ -20,23 +20,21 @@ package org.apache.hadoop.hbase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.coordination.ZkSplitLogWorkerCoordination;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.LoadBalancer;
@ -45,17 +43,9 @@ import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.testclassification.MiscTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.hbase.util.Threads;
import org.apache.hadoop.hbase.zookeeper.EmptyWatcher;
import org.apache.hadoop.hbase.zookeeper.ZKConfig;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@ -67,20 +57,15 @@ import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Category({MiscTests.class, LargeTests.class})
public class TestZooKeeper {
private static final Logger LOG = LoggerFactory.getLogger(TestZooKeeper.class);
private final static HBaseTestingUtility
TEST_UTIL = new HBaseTestingUtility();
private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@Rule
public TestName name = new TestName();
/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
// Test we can first start the ZK cluster by itself
@ -92,17 +77,11 @@ public class TestZooKeeper {
LoadBalancer.class);
}
/**
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
TEST_UTIL.shutdownMiniCluster();
}
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
TEST_UTIL.startMiniHBaseCluster(2, 2);
@ -155,13 +134,11 @@ public class TestZooKeeper {
/**
* Make sure we can use the cluster
* @throws Exception
*/
private void testSanity(final String testName) throws Exception{
private void testSanity(final String testName) throws Exception {
String tableName = testName + "_" + System.currentTimeMillis();
HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
HColumnDescriptor family = new HColumnDescriptor("fam");
desc.addFamily(family);
TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName))
.addColumnFamily(ColumnFamilyDescriptorBuilder.of("fam")).build();
LOG.info("Creating table " + tableName);
Admin admin = TEST_UTIL.getAdmin();
try {
@ -178,162 +155,6 @@ public class TestZooKeeper {
table.close();
}
/**
* Create a znode with data
* @throws Exception
*/
@Test
public void testCreateWithParents() throws Exception {
ZKWatcher zkw =
new ZKWatcher(new Configuration(TEST_UTIL.getConfiguration()),
TestZooKeeper.class.getName(), null);
byte[] expectedData = new byte[] { 1, 2, 3 };
ZKUtil.createWithParents(zkw, "/l1/l2/l3/l4/testCreateWithParents", expectedData);
byte[] data = ZKUtil.getData(zkw, "/l1/l2/l3/l4/testCreateWithParents");
assertTrue(Bytes.equals(expectedData, data));
ZKUtil.deleteNodeRecursively(zkw, "/l1");
ZKUtil.createWithParents(zkw, "/testCreateWithParents", expectedData);
data = ZKUtil.getData(zkw, "/testCreateWithParents");
assertTrue(Bytes.equals(expectedData, data));
ZKUtil.deleteNodeRecursively(zkw, "/testCreateWithParents");
}
/**
* Create a bunch of znodes in a hierarchy, try deleting one that has childs (it will fail), then
* delete it recursively, then delete the last znode
* @throws Exception
*/
@Test
public void testZNodeDeletes() throws Exception {
ZKWatcher zkw = new ZKWatcher(
new Configuration(TEST_UTIL.getConfiguration()),
TestZooKeeper.class.getName(), null);
ZKUtil.createWithParents(zkw, "/l1/l2/l3/l4");
try {
ZKUtil.deleteNode(zkw, "/l1/l2");
fail("We should not be able to delete if znode has childs");
} catch (KeeperException ex) {
assertNotNull(ZKUtil.getDataNoWatch(zkw, "/l1/l2/l3/l4", null));
}
ZKUtil.deleteNodeRecursively(zkw, "/l1/l2");
// make sure it really is deleted
assertNull(ZKUtil.getDataNoWatch(zkw, "/l1/l2/l3/l4", null));
// do the same delete again and make sure it doesn't crash
ZKUtil.deleteNodeRecursively(zkw, "/l1/l2");
ZKUtil.deleteNode(zkw, "/l1");
assertNull(ZKUtil.getDataNoWatch(zkw, "/l1/l2", null));
}
/**
* A test for HBASE-3238
* @throws IOException A connection attempt to zk failed
* @throws InterruptedException One of the non ZKUtil actions was interrupted
* @throws KeeperException Any of the zookeeper connections had a
* KeeperException
*/
@Test
public void testCreateSilentIsReallySilent() throws InterruptedException,
KeeperException, IOException {
Configuration c = TEST_UTIL.getConfiguration();
String aclZnode = "/aclRoot";
String quorumServers = ZKConfig.getZKQuorumServersString(c);
int sessionTimeout = 5 * 1000; // 5 seconds
ZooKeeper zk = new ZooKeeper(quorumServers, sessionTimeout, EmptyWatcher.instance);
zk.addAuthInfo("digest", "hbase:rox".getBytes());
// Assumes the root of the ZooKeeper space is writable as it creates a node
// wherever the cluster home is defined.
ZKWatcher zk2 = new ZKWatcher(TEST_UTIL.getConfiguration(),
"testCreateSilentIsReallySilent", null);
// Save the previous ACL
Stat s = null;
List<ACL> oldACL = null;
while (true) {
try {
s = new Stat();
oldACL = zk.getACL("/", s);
break;
} catch (KeeperException e) {
switch (e.code()) {
case CONNECTIONLOSS:
case SESSIONEXPIRED:
case OPERATIONTIMEOUT:
LOG.warn("Possibly transient ZooKeeper exception", e);
Threads.sleep(100);
break;
default:
throw e;
}
}
}
// I set this acl after the attempted creation of the cluster home node.
// Add retries in case of retryable zk exceptions.
while (true) {
try {
zk.setACL("/", ZooDefs.Ids.CREATOR_ALL_ACL, -1);
break;
} catch (KeeperException e) {
switch (e.code()) {
case CONNECTIONLOSS:
case SESSIONEXPIRED:
case OPERATIONTIMEOUT:
LOG.warn("Possibly transient ZooKeeper exception: " + e);
Threads.sleep(100);
break;
default:
throw e;
}
}
}
while (true) {
try {
zk.create(aclZnode, null, ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
break;
} catch (KeeperException e) {
switch (e.code()) {
case CONNECTIONLOSS:
case SESSIONEXPIRED:
case OPERATIONTIMEOUT:
LOG.warn("Possibly transient ZooKeeper exception: " + e);
Threads.sleep(100);
break;
default:
throw e;
}
}
}
zk.close();
ZKUtil.createAndFailSilent(zk2, aclZnode);
// Restore the ACL
ZooKeeper zk3 = new ZooKeeper(quorumServers, sessionTimeout, EmptyWatcher.instance);
zk3.addAuthInfo("digest", "hbase:rox".getBytes());
try {
zk3.setACL("/", oldACL, -1);
} finally {
zk3.close();
}
}
/**
* Test should not fail with NPE when getChildDataAndWatchForNewChildren
* invoked with wrongNode
*/
@Test
@SuppressWarnings("deprecation")
public void testGetChildDataAndWatchForNewChildrenShouldNotThrowNPE()
throws Exception {
ZKWatcher zkw = new ZKWatcher(TEST_UTIL.getConfiguration(), name.getMethodName(), null);
ZKUtil.getChildDataAndWatchForNewChildren(zkw, "/wrongNode");
}
/**
* Tests that the master does not call retainAssignment after recovery from expired zookeeper
* session. Without the HBASE-6046 fix master always tries to assign all the user regions by
@ -351,8 +172,9 @@ public class TestZooKeeper {
byte[][] SPLIT_KEYS = new byte[][] { Bytes.toBytes("a"), Bytes.toBytes("b"),
Bytes.toBytes("c"), Bytes.toBytes("d"), Bytes.toBytes("e"), Bytes.toBytes("f"),
Bytes.toBytes("g"), Bytes.toBytes("h"), Bytes.toBytes("i"), Bytes.toBytes("j") };
HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName()));
htd.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
TableDescriptor htd =
TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
.addColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
admin.createTable(htd, SPLIT_KEYS);
TEST_UTIL.waitUntilNoRegionsInTransition(60000);
m.getZooKeeper().close();
@ -414,11 +236,10 @@ public class TestZooKeeper {
Table table = null;
try {
byte[][] SPLIT_KEYS = new byte[][] { Bytes.toBytes("1"), Bytes.toBytes("2"),
Bytes.toBytes("3"), Bytes.toBytes("4"), Bytes.toBytes("5") };
HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName()));
HColumnDescriptor hcd = new HColumnDescriptor("col");
htd.addFamily(hcd);
Bytes.toBytes("3"), Bytes.toBytes("4"), Bytes.toBytes("5") };
TableDescriptor htd =
TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
.addColumnFamily(ColumnFamilyDescriptorBuilder.of("col")).build();
admin.createTable(htd, SPLIT_KEYS);
TEST_UTIL.waitUntilNoRegionsInTransition(60000);
table = TEST_UTIL.getConnection().getTable(htd.getTableName());

View File

@ -923,7 +923,7 @@ public final class ZKUtil {
}
// Certain znodes are accessed directly by the client,
// so they must be readable by non-authenticated clients
if (zkw.isClientReadable(node)) {
if (zkw.znodePaths.isClientReadable(node)) {
acls.addAll(Ids.CREATOR_ALL_ACL);
acls.addAll(Ids.READ_ACL_UNSAFE);
} else {

View File

@ -159,23 +159,6 @@ public class ZKWatcher implements Watcher, Abortable, Closeable {
}
}
/** Returns whether the znode is supposed to be readable by the client
* and DOES NOT contain sensitive information (world readable).*/
public boolean isClientReadable(String node) {
// Developer notice: These znodes are world readable. DO NOT add more znodes here UNLESS
// all clients need to access this data to work. Using zk for sharing data to clients (other
// than service lookup case is not a recommended design pattern.
return
node.equals(znodePaths.baseZNode) ||
znodePaths.isAnyMetaReplicaZNode(node) ||
node.equals(znodePaths.masterAddressZNode) ||
node.equals(znodePaths.clusterIdZNode)||
node.equals(znodePaths.rsZNode) ||
// /hbase/table and /hbase/table/foo is allowed, /hbase/table-lock is not
node.equals(znodePaths.tableZNode) ||
node.startsWith(znodePaths.tableZNode + "/");
}
/**
* On master start, we check the znode ACLs under the root directory and set the ACLs properly
* if needed. If the cluster goes from an unsecure setup to a secure setup, this step is needed

View File

@ -7,105 +7,221 @@
* "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
* 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.
* 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.hbase.zookeeper;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.security.Superusers;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.Abortable;
import org.apache.hadoop.hbase.HBaseZKTestingUtility;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.ZKTests;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Threads;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooDefs.Perms;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.junit.Assert;
import org.apache.zookeeper.data.Stat;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Category({ ZKTests.class, SmallTests.class })
import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
@Category({ ZKTests.class, MediumTests.class })
public class TestZKUtil {
@Test
public void testUnsecure() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user1");
String node = "/hbase/testUnsecure";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, false);
Assert.assertEquals(1, aclList.size());
Assert.assertTrue(aclList.contains(Ids.OPEN_ACL_UNSAFE.iterator().next()));
private static final Logger LOG = LoggerFactory.getLogger(TestZKUtil.class);
private static HBaseZKTestingUtility UTIL = new HBaseZKTestingUtility();
private static ZKWatcher ZKW;
@BeforeClass
public static void setUp() throws Exception {
UTIL.startMiniZKCluster().getClientPort();
ZKW = new ZKWatcher(new Configuration(UTIL.getConfiguration()), TestZKUtil.class.getName(),
new WarnOnlyAbortable());
}
@Test
public void testSecuritySingleSuperuser() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user1");
String node = "/hbase/testSecuritySingleSuperuser";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, true);
Assert.assertEquals(2, aclList.size()); // 1+1, since ACL will be set for the creator by default
Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user1"))));
Assert.assertTrue(aclList.contains(Ids.CREATOR_ALL_ACL.iterator().next()));
@AfterClass
public static void tearDown() throws IOException {
Closeables.close(ZKW, true);
UTIL.shutdownMiniZKCluster();
UTIL.cleanupTestDir();
}
/**
* Create a znode with data
*/
@Test
public void testCreateACL() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user1,@group1,user2,@group2,user3");
String node = "/hbase/testCreateACL";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, true);
Assert.assertEquals(4, aclList.size()); // 3+1, since ACL will be set for the creator by default
Assert.assertFalse(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "@group1"))));
Assert.assertFalse(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "@group2"))));
Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user1"))));
Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user2"))));
Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user3"))));
public void testCreateWithParents() throws KeeperException, InterruptedException {
byte[] expectedData = new byte[] { 1, 2, 3 };
ZKUtil.createWithParents(ZKW, "/l1/l2/l3/l4/testCreateWithParents", expectedData);
byte[] data = ZKUtil.getData(ZKW, "/l1/l2/l3/l4/testCreateWithParents");
assertTrue(Bytes.equals(expectedData, data));
ZKUtil.deleteNodeRecursively(ZKW, "/l1");
ZKUtil.createWithParents(ZKW, "/testCreateWithParents", expectedData);
data = ZKUtil.getData(ZKW, "/testCreateWithParents");
assertTrue(Bytes.equals(expectedData, data));
ZKUtil.deleteNodeRecursively(ZKW, "/testCreateWithParents");
}
/**
* Create a bunch of znodes in a hierarchy, try deleting one that has childs (it will fail), then
* delete it recursively, then delete the last znode
*/
@Test
public void testCreateACLWithSameUser() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user4,@group1,user5,user6");
UserGroupInformation.setLoginUser(UserGroupInformation.createRemoteUser("user4"));
String node = "/hbase/testCreateACL";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, true);
Assert.assertEquals(3, aclList.size()); // 3, since service user the same as one of superuser
Assert.assertFalse(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "@group1"))));
Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("auth", ""))));
Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user5"))));
Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user6"))));
public void testZNodeDeletes() throws Exception {
ZKUtil.createWithParents(ZKW, "/l1/l2/l3/l4");
try {
ZKUtil.deleteNode(ZKW, "/l1/l2");
fail("We should not be able to delete if znode has childs");
} catch (KeeperException ex) {
assertNotNull(ZKUtil.getDataNoWatch(ZKW, "/l1/l2/l3/l4", null));
}
ZKUtil.deleteNodeRecursively(ZKW, "/l1/l2");
// make sure it really is deleted
assertNull(ZKUtil.getDataNoWatch(ZKW, "/l1/l2/l3/l4", null));
// do the same delete again and make sure it doesn't crash
ZKUtil.deleteNodeRecursively(ZKW, "/l1/l2");
ZKUtil.deleteNode(ZKW, "/l1");
assertNull(ZKUtil.getDataNoWatch(ZKW, "/l1/l2", null));
}
@Test(expected = KeeperException.SystemErrorException.class)
public void testInterruptedDuringAction()
throws ZooKeeperConnectionException, IOException, KeeperException, InterruptedException {
final RecoverableZooKeeper recoverableZk = Mockito.mock(RecoverableZooKeeper.class);
ZKWatcher zkw = new ZKWatcher(HBaseConfiguration.create(), "unittest", null) {
@Override
public RecoverableZooKeeper getRecoverableZooKeeper() {
return recoverableZk;
/**
* A test for HBASE-3238
* @throws IOException A connection attempt to zk failed
* @throws InterruptedException One of the non ZKUtil actions was interrupted
* @throws KeeperException Any of the zookeeper connections had a KeeperException
*/
@Test
public void testCreateSilentIsReallySilent()
throws InterruptedException, KeeperException, IOException {
Configuration c = UTIL.getConfiguration();
String aclZnode = "/aclRoot";
String quorumServers = ZKConfig.getZKQuorumServersString(c);
int sessionTimeout = 5 * 1000; // 5 seconds
ZooKeeper zk = new ZooKeeper(quorumServers, sessionTimeout, EmptyWatcher.instance);
zk.addAuthInfo("digest", "hbase:rox".getBytes());
// Save the previous ACL
Stat s = null;
List<ACL> oldACL = null;
while (true) {
try {
s = new Stat();
oldACL = zk.getACL("/", s);
break;
} catch (KeeperException e) {
switch (e.code()) {
case CONNECTIONLOSS:
case SESSIONEXPIRED:
case OPERATIONTIMEOUT:
LOG.warn("Possibly transient ZooKeeper exception", e);
Threads.sleep(100);
break;
default:
throw e;
}
}
};
Mockito.doThrow(new InterruptedException()).when(recoverableZk)
.getChildren(zkw.znodePaths.baseZNode, null);
ZKUtil.listChildrenNoWatch(zkw, zkw.znodePaths.baseZNode);
}
// I set this acl after the attempted creation of the cluster home node.
// Add retries in case of retryable zk exceptions.
while (true) {
try {
zk.setACL("/", ZooDefs.Ids.CREATOR_ALL_ACL, -1);
break;
} catch (KeeperException e) {
switch (e.code()) {
case CONNECTIONLOSS:
case SESSIONEXPIRED:
case OPERATIONTIMEOUT:
LOG.warn("Possibly transient ZooKeeper exception: " + e);
Threads.sleep(100);
break;
default:
throw e;
}
}
}
while (true) {
try {
zk.create(aclZnode, null, ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
break;
} catch (KeeperException e) {
switch (e.code()) {
case CONNECTIONLOSS:
case SESSIONEXPIRED:
case OPERATIONTIMEOUT:
LOG.warn("Possibly transient ZooKeeper exception: " + e);
Threads.sleep(100);
break;
default:
throw e;
}
}
}
zk.close();
ZKUtil.createAndFailSilent(ZKW, aclZnode);
// Restore the ACL
ZooKeeper zk3 = new ZooKeeper(quorumServers, sessionTimeout, EmptyWatcher.instance);
zk3.addAuthInfo("digest", "hbase:rox".getBytes());
try {
zk3.setACL("/", oldACL, -1);
} finally {
zk3.close();
}
}
/**
* Test should not fail with NPE when getChildDataAndWatchForNewChildren invoked with wrongNode
*/
@Test
@SuppressWarnings("deprecation")
public void testGetChildDataAndWatchForNewChildrenShouldNotThrowNPE() throws Exception {
ZKUtil.getChildDataAndWatchForNewChildren(ZKW, "/wrongNode");
}
private static class WarnOnlyAbortable implements Abortable {
@Override
public void abort(String why, Throwable e) {
LOG.warn("ZKWatcher received abort, ignoring. Reason: " + why);
if (LOG.isDebugEnabled()) {
LOG.debug(e.toString(), e);
}
}
@Override
public boolean isAborted() {
return false;
}
}
}

View File

@ -0,0 +1,113 @@
/**
* 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.hbase.zookeeper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.security.Superusers;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.testclassification.ZKTests;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooDefs.Perms;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.Mockito;
@Category({ ZKTests.class, SmallTests.class })
public class TestZKUtilNoServer {
@Test
public void testUnsecure() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user1");
String node = "/hbase/testUnsecure";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, false);
assertEquals(1, aclList.size());
assertTrue(aclList.contains(Ids.OPEN_ACL_UNSAFE.iterator().next()));
}
@Test
public void testSecuritySingleSuperuser() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user1");
String node = "/hbase/testSecuritySingleSuperuser";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, true);
assertEquals(2, aclList.size()); // 1+1, since ACL will be set for the creator by default
assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user1"))));
assertTrue(aclList.contains(Ids.CREATOR_ALL_ACL.iterator().next()));
}
@Test
public void testCreateACL() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user1,@group1,user2,@group2,user3");
String node = "/hbase/testCreateACL";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, true);
assertEquals(4, aclList.size()); // 3+1, since ACL will be set for the creator by default
assertFalse(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "@group1"))));
assertFalse(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "@group2"))));
assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user1"))));
assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user2"))));
assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user3"))));
}
@Test
public void testCreateACLWithSameUser() throws ZooKeeperConnectionException, IOException {
Configuration conf = HBaseConfiguration.create();
conf.set(Superusers.SUPERUSER_CONF_KEY, "user4,@group1,user5,user6");
UserGroupInformation.setLoginUser(UserGroupInformation.createRemoteUser("user4"));
String node = "/hbase/testCreateACL";
ZKWatcher watcher = new ZKWatcher(conf, node, null, false);
List<ACL> aclList = ZKUtil.createACL(watcher, node, true);
assertEquals(3, aclList.size()); // 3, since service user the same as one of superuser
assertFalse(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "@group1"))));
assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("auth", ""))));
assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user5"))));
assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("sasl", "user6"))));
}
@Test(expected = KeeperException.SystemErrorException.class)
public void testInterruptedDuringAction()
throws ZooKeeperConnectionException, IOException, KeeperException, InterruptedException {
final RecoverableZooKeeper recoverableZk = Mockito.mock(RecoverableZooKeeper.class);
ZKWatcher zkw = new ZKWatcher(HBaseConfiguration.create(), "unittest", null) {
@Override
public RecoverableZooKeeper getRecoverableZooKeeper() {
return recoverableZk;
}
};
Mockito.doThrow(new InterruptedException()).when(recoverableZk)
.getChildren(zkw.znodePaths.baseZNode, null);
ZKUtil.listChildrenNoWatch(zkw, zkw.znodePaths.baseZNode);
}
}

View File

@ -1,58 +0,0 @@
/**
* 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.hbase.zookeeper;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.testclassification.ZKTests;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@Category({ ZKTests.class, SmallTests.class })
public class TestZKWatcher {
@Test
public void testIsClientReadable() throws IOException {
ZKWatcher watcher =
new ZKWatcher(HBaseConfiguration.create(), "testIsClientReadable", null, false);
assertTrue(watcher.isClientReadable(watcher.znodePaths.baseZNode));
assertTrue(watcher.isClientReadable(watcher.znodePaths.getZNodeForReplica(0)));
assertTrue(watcher.isClientReadable(watcher.znodePaths.masterAddressZNode));
assertTrue(watcher.isClientReadable(watcher.znodePaths.clusterIdZNode));
assertTrue(watcher.isClientReadable(watcher.znodePaths.tableZNode));
assertTrue(
watcher.isClientReadable(ZNodePaths.joinZNode(watcher.znodePaths.tableZNode, "foo")));
assertTrue(watcher.isClientReadable(watcher.znodePaths.rsZNode));
assertFalse(watcher.isClientReadable(watcher.znodePaths.tableLockZNode));
assertFalse(watcher.isClientReadable(watcher.znodePaths.balancerZNode));
assertFalse(watcher.isClientReadable(watcher.znodePaths.regionNormalizerZNode));
assertFalse(watcher.isClientReadable(watcher.znodePaths.clusterStateZNode));
assertFalse(watcher.isClientReadable(watcher.znodePaths.drainingZNode));
assertFalse(watcher.isClientReadable(watcher.znodePaths.splitLogZNode));
assertFalse(watcher.isClientReadable(watcher.znodePaths.backupMasterAddressesZNode));
watcher.close();
}
}