From 259fdbf0369dc8e736b8f096b7c484a78da3fb63 Mon Sep 17 00:00:00 2001 From: Na Yang Date: Sun, 21 Dec 2014 22:18:23 -0800 Subject: [PATCH] HIVE-9119 --- .../java/org/apache/hadoop/hive/conf/HiveConf.java | 5 + ql/pom.xml | 17 +++ .../zookeeper/CuratorFrameworkSingleton.java | 64 ++++++++++ .../zookeeper/ZooKeeperHiveLockManager.java | 140 +++++++-------------- .../zookeeper/TestZookeeperLockManager.java | 95 ++++++++------ 5 files changed, 182 insertions(+), 139 deletions(-) create mode 100644 ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/CuratorFrameworkSingleton.java diff --git common/src/java/org/apache/hadoop/hive/conf/HiveConf.java common/src/java/org/apache/hadoop/hive/conf/HiveConf.java index 10ad3ea..015b8c9 100644 --- common/src/java/org/apache/hadoop/hive/conf/HiveConf.java +++ common/src/java/org/apache/hadoop/hive/conf/HiveConf.java @@ -1309,6 +1309,11 @@ "The parent node under which all ZooKeeper nodes are created."), HIVE_ZOOKEEPER_CLEAN_EXTRA_NODES("hive.zookeeper.clean.extra.nodes", false, "Clean extra nodes at the end of the session."), + HIVE_ZOOKEEPER_CONNECTION_MAX_RETRIES("hive.zookeeper.connection.max.retries", 3, + "Max number of times to retry when connecting to the zookeeper server."), + HIVE_ZOOKEEPR_CONNECTION_BASESLEEPTIME("hive.zookeeper.connection.basesleeptime", 1000, + "Initial amount of time to wait between retries when connecting to the zookeeper server."), + // Transactions HIVE_TXN_MANAGER("hive.txn.manager", diff --git ql/pom.xml ql/pom.xml index 84e912e..a1fd46f 100644 --- ql/pom.xml +++ ql/pom.xml @@ -162,6 +162,23 @@ ${zookeeper.version} + org.apache.curator + curator-framework + ${curator.version} + + + org.apache.curator + apache-curator + ${curator.version} + pom + + + org.apache.curator + curator-test + ${curator.version} + test + + org.codehaus.groovy groovy-all ${groovy.version} diff --git ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/CuratorFrameworkSingleton.java ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/CuratorFrameworkSingleton.java new file mode 100644 index 0000000..56cd86d --- /dev/null +++ ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/CuratorFrameworkSingleton.java @@ -0,0 +1,64 @@ +/** + * 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.lockmgr.zookeeper; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.ql.util.ZooKeeperHiveHelper; + +public class CuratorFrameworkSingleton { + private static CuratorFramework sharedClient = null; + static final Log LOG = LogFactory.getLog("CuratorFrameworkSingleton"); + static { + // Add shutdown hook. + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + if (sharedClient != null) { + sharedClient.close(); + } + String shutdownMsg = "Closing ZooKeeper client."; + LOG.info(shutdownMsg); + } + }); + } + public static CuratorFramework getInstance() { + if (sharedClient == null) { + synchronized (CuratorFrameworkSingleton.class) { + // create a client instance + HiveConf hiveConf = new HiveConf(); + int sessionTimeout = hiveConf.getIntVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_SESSION_TIMEOUT); + int baseSleepTime = hiveConf.getIntVar(HiveConf.ConfVars.HIVE_ZOOKEEPR_CONNECTION_BASESLEEPTIME); + int maxRetries = hiveConf.getIntVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_CONNECTION_MAX_RETRIES); + String quorumServers = ZooKeeperHiveHelper.getQuorumServers(hiveConf); + + sharedClient = CuratorFrameworkFactory.builder().connectString(quorumServers) + .sessionTimeoutMs(sessionTimeout) + .retryPolicy(new ExponentialBackoffRetry(baseSleepTime, maxRetries)) + .build(); + sharedClient.start(); + } + } + return sharedClient; + } +} diff --git ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java index 1334a91..48b6a7d 100644 --- ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java +++ ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java @@ -27,15 +27,10 @@ import org.apache.hadoop.hive.ql.lockmgr.HiveLockObject.HiveLockObjectData; import org.apache.hadoop.hive.ql.metadata.*; import org.apache.hadoop.hive.ql.session.SessionState.LogHelper; -import org.apache.hadoop.hive.ql.util.ZooKeeperHiveHelper; import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.data.Stat; import org.apache.zookeeper.KeeperException; -import org.apache.zookeeper.Watcher; -import org.apache.zookeeper.ZooDefs.Ids; -import org.apache.zookeeper.ZooKeeper; +import org.apache.curator.framework.CuratorFramework; -import java.io.IOException; import java.net.InetAddress; import java.util.*; import java.util.concurrent.TimeUnit; @@ -47,14 +42,11 @@ public static final Log LOG = LogFactory.getLog("ZooKeeperHiveLockManager"); static final private LogHelper console = new LogHelper(LOG); - private ZooKeeper zooKeeper; + private static CuratorFramework curatorFramework = CuratorFrameworkSingleton.getInstance(); // All the locks are created under this parent private String parent; - private int sessionTimeout; - private String quorumServers; - private long sleepTime; private int numRetriesForLock; private int numRetriesForUnLock; @@ -80,8 +72,6 @@ public ZooKeeperHiveLockManager() { public void setContext(HiveLockManagerCtx ctx) throws LockException { this.ctx = ctx; HiveConf conf = ctx.getConf(); - sessionTimeout = conf.getIntVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_SESSION_TIMEOUT); - quorumServers = ZooKeeperHiveHelper.getQuorumServers(conf); sleepTime = conf.getTimeVar( HiveConf.ConfVars.HIVE_LOCK_SLEEP_BETWEEN_RETRIES, TimeUnit.MILLISECONDS); @@ -89,20 +79,17 @@ public void setContext(HiveLockManagerCtx ctx) throws LockException { numRetriesForUnLock = conf.getIntVar(HiveConf.ConfVars.HIVE_UNLOCK_NUMRETRIES); try { - renewZookeeperInstance(sessionTimeout, quorumServers); parent = conf.getVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_NAMESPACE); - - try { - zooKeeper.create("/" + parent, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); - } catch (KeeperException e) { + try{ + curatorFramework.create().withMode(CreateMode.PERSISTENT).forPath("/" + parent, new byte[0]); + } catch (Exception e) { // ignore if the parent already exists - if (e.code() != KeeperException.Code.NODEEXISTS) { + if (!(e instanceof KeeperException) || ((KeeperException)e).code() != KeeperException.Code.NODEEXISTS) { LOG.warn("Unexpected ZK exception when creating parent node /" + parent, e); } } - } catch (Exception e) { - LOG.error("Failed to create ZooKeeper object: ", e); + LOG.error("Failed to create curatorFramework object: ", e); throw new LockException(ErrorMsg.ZOOKEEPER_CLIENT_COULD_NOT_BE_INITIALIZED.getMsg()); } } @@ -116,15 +103,6 @@ public void refresh() { numRetriesForUnLock = conf.getIntVar(HiveConf.ConfVars.HIVE_UNLOCK_NUMRETRIES); } - private void renewZookeeperInstance(int sessionTimeout, String quorumServers) - throws InterruptedException, IOException { - if (zooKeeper != null) { - return; - } - - zooKeeper = new ZooKeeper(quorumServers, sessionTimeout, new ZooKeeperHiveHelper.DummyWatcher()); - } - /** * @param key object to be locked * Get the name of the last string. For eg. if you need to lock db/T/ds=1=/hr=1, @@ -266,8 +244,8 @@ public ZooKeeperHiveLock lock(HiveLockObject key, HiveLockMode mode, * @throws InterruptedException **/ private String createChild(String name, byte[] data, CreateMode mode) - throws KeeperException, InterruptedException { - return zooKeeper.create(name, data, Ids.OPEN_ACL_UNSAFE, mode); + throws Exception { + return curatorFramework.create().withMode(mode).forPath(name, data); } private String getLockName(String parent, HiveLockMode mode) { @@ -347,7 +325,7 @@ private void printConflictingLocks(HiveLockObject key, HiveLockMode mode, private ZooKeeperHiveLock lockPrimitive(HiveLockObject key, HiveLockMode mode, boolean keepAlive, boolean parentCreated, Set conflictingLocks) - throws KeeperException, InterruptedException { + throws Exception { String res; // If the parents have already been created, create the last child only @@ -369,8 +347,8 @@ private ZooKeeperHiveLock lockPrimitive(HiveLockObject key, for (String name : names) { try { res = createChild(name, new byte[0], CreateMode.PERSISTENT); - } catch (KeeperException e) { - if (e.code() != KeeperException.Code.NODEEXISTS) { + } catch (Exception e) { + if (!(e instanceof KeeperException) || ((KeeperException)e).code() != KeeperException.Code.NODEEXISTS) { //if the exception is not 'NODEEXISTS', re-throw it throw e; } @@ -383,11 +361,11 @@ private ZooKeeperHiveLock lockPrimitive(HiveLockObject key, int seqNo = getSequenceNumber(res, getLockName(lastName, mode)); if (seqNo == -1) { - zooKeeper.delete(res, -1); + curatorFramework.delete().forPath(res); return null; } - List children = zooKeeper.getChildren(lastName, false); + List children = curatorFramework.getChildren().forPath(lastName); String exLock = getLockName(lastName, HiveLockMode.EXCLUSIVE); String shLock = getLockName(lastName, HiveLockMode.SHARED); @@ -407,12 +385,11 @@ private ZooKeeperHiveLock lockPrimitive(HiveLockObject key, if ((childSeq >= 0) && (childSeq < seqNo)) { try { - zooKeeper.delete(res, -1); + curatorFramework.delete().forPath(res); } finally { if (LOG.isDebugEnabled()) { - Stat stat = new Stat(); try { - String data = new String(zooKeeper.getData(child, false, stat)); + String data = new String(curatorFramework.getData().forPath(child)); conflictingLocks.add(data); } catch (Exception e) { //ignored @@ -428,11 +405,10 @@ private ZooKeeperHiveLock lockPrimitive(HiveLockObject key, /* Remove the lock specified */ public void unlock(HiveLock hiveLock) throws LockException { - unlockWithRetry(ctx.getConf(), zooKeeper, hiveLock, parent); + unlockWithRetry(hiveLock, parent); } - private void unlockWithRetry(HiveConf conf, ZooKeeper zkpClient, - HiveLock hiveLock, String parent) throws LockException { + private void unlockWithRetry(HiveLock hiveLock, String parent) throws LockException { int tryNum = 0; do { @@ -440,14 +416,13 @@ private void unlockWithRetry(HiveConf conf, ZooKeeper zkpClient, tryNum++; if (tryNum > 1) { Thread.sleep(sleepTime); - prepareRetry(); } - unlockPrimitive(conf, zkpClient, hiveLock, parent); + unlockPrimitive(hiveLock, parent, curatorFramework); break; } catch (Exception e) { if (tryNum >= numRetriesForUnLock) { String name = ((ZooKeeperHiveLock)hiveLock).getPath(); - LOG.error("Node " + name + " can not be deleted after " + numRetriesForUnLock + " attempts."); + LOG.error("Node " + name + " can not be deleted after " + numRetriesForUnLock + " attempts."); throw new LockException(e); } } @@ -458,21 +433,20 @@ private void unlockWithRetry(HiveConf conf, ZooKeeper zkpClient, /* Remove the lock specified */ @VisibleForTesting - static void unlockPrimitive(HiveConf conf, ZooKeeper zkpClient, - HiveLock hiveLock, String parent) throws LockException { + static void unlockPrimitive(HiveLock hiveLock, String parent, CuratorFramework curatorFramework) throws LockException { ZooKeeperHiveLock zLock = (ZooKeeperHiveLock)hiveLock; HiveLockObject obj = zLock.getHiveLockObject(); String name = getLastObjectName(parent, obj); try { - zkpClient.delete(zLock.getPath(), -1); + curatorFramework.delete().forPath(zLock.getPath()); // Delete the parent node if all the children have been deleted - List children = zkpClient.getChildren(name, false); + List children = curatorFramework.getChildren().forPath(name); if (children == null || children.isEmpty()) { - zkpClient.delete(name, -1); + curatorFramework.delete().forPath(name); } } catch (KeeperException.NoNodeException nne) { - //can happen in retrying deleting the zLock after exceptions like InterruptedException + //can happen in retrying deleting the zLock after exceptions like InterruptedException //or in a race condition where parent has already been deleted by other process when it //is to be deleted. Both cases should not raise error LOG.debug("Node " + zLock.getPath() + " or its parent has already been deleted."); @@ -480,7 +454,7 @@ static void unlockPrimitive(HiveConf conf, ZooKeeper zkpClient, //can happen in a race condition where another process adds a zLock under this parent //just before it is about to be deleted. It should not be a problem since this parent //can eventually be deleted by the process which hold its last child zLock - LOG.debug("Node " + name + " to be deleted is not empty."); + LOG.debug("Node " + name + " to be deleted is not empty."); } catch (Exception e) { //exceptions including InterruptException and other KeeperException LOG.error("Failed to release ZooKeeper lock: ", e); @@ -490,19 +464,14 @@ static void unlockPrimitive(HiveConf conf, ZooKeeper zkpClient, /* Release all locks - including PERSISTENT locks */ public static void releaseAllLocks(HiveConf conf) throws Exception { - ZooKeeper zkpClient = null; try { - int sessionTimeout = conf.getIntVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_SESSION_TIMEOUT); - String quorumServers = ZooKeeperHiveHelper.getQuorumServers(conf); - Watcher dummyWatcher = new ZooKeeperHiveHelper.DummyWatcher(); - zkpClient = new ZooKeeper(quorumServers, sessionTimeout, dummyWatcher); String parent = conf.getVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_NAMESPACE); - List locks = getLocks(conf, zkpClient, null, parent, false, false); + List locks = getLocks(conf, null, parent, false, false); Exception lastExceptionGot = null; if (locks != null) { for (HiveLock lock : locks) { try { - unlockPrimitive(conf, zkpClient, lock, parent); + unlockPrimitive(lock, parent, curatorFramework); } catch (Exception e) { lastExceptionGot = e; } @@ -516,24 +485,19 @@ public static void releaseAllLocks(HiveConf conf) throws Exception { } catch (Exception e) { LOG.error("Failed to release all locks: ", e); throw new Exception(ErrorMsg.ZOOKEEPER_CLIENT_COULD_NOT_BE_INITIALIZED.getMsg()); - } finally { - if (zkpClient != null) { - zkpClient.close(); - zkpClient = null; - } } } /* Get all locks */ public List getLocks(boolean verifyTablePartition, boolean fetchData) throws LockException { - return getLocks(ctx.getConf(), zooKeeper, null, parent, verifyTablePartition, fetchData); + return getLocks(ctx.getConf(), null, parent, verifyTablePartition, fetchData); } /* Get all locks for a particular object */ public List getLocks(HiveLockObject key, boolean verifyTablePartitions, boolean fetchData) throws LockException { - return getLocks(ctx.getConf(), zooKeeper, key, parent, verifyTablePartitions, fetchData); + return getLocks(ctx.getConf(), key, parent, verifyTablePartitions, fetchData); } /** @@ -541,7 +505,7 @@ public static void releaseAllLocks(HiveConf conf) throws Exception { * @param zkpClient The ZooKeeper client * @param key The object to be compared against - if key is null, then get all locks **/ - private static List getLocks(HiveConf conf, ZooKeeper zkpClient, + private static List getLocks(HiveConf conf, HiveLockObject key, String parent, boolean verifyTablePartition, boolean fetchData) throws LockException { List locks = new ArrayList(); @@ -552,12 +516,12 @@ public static void releaseAllLocks(HiveConf conf) throws Exception { try { if (key != null) { commonParent = "/" + parent + "/" + key.getName(); - children = zkpClient.getChildren(commonParent, false); + children = curatorFramework.getChildren().forPath(commonParent); recurse = false; } else { commonParent = "/" + parent; - children = zkpClient.getChildren(commonParent, false); + children = curatorFramework.getChildren().forPath(commonParent); } } catch (Exception e) { // no locks present @@ -579,7 +543,7 @@ public static void releaseAllLocks(HiveConf conf) throws Exception { if (recurse) { try { - children = zkpClient.getChildren(curChild, false); + children = curatorFramework.getChildren().forPath(curChild); for (String child : children) { childn.add(curChild + "/" + child); } @@ -588,7 +552,7 @@ public static void releaseAllLocks(HiveConf conf) throws Exception { } } - HiveLockMode mode = getLockMode(conf, curChild); + HiveLockMode mode = getLockMode(curChild); if (mode == null) { continue; } @@ -605,8 +569,7 @@ public static void releaseAllLocks(HiveConf conf) throws Exception { if (fetchData) { try { - data = new HiveLockObjectData(new String(zkpClient.getData(curChild, - new ZooKeeperHiveHelper.DummyWatcher(), null))); + data = new HiveLockObjectData(new String(curatorFramework.getData().watched().forPath(curChild))); data.setClientIp(clientIp); } catch (Exception e) { LOG.error("Error in getting data for " + curChild, e); @@ -623,12 +586,7 @@ public static void releaseAllLocks(HiveConf conf) throws Exception { /** Remove all redundant nodes **/ private void removeAllRedundantNodes() { try { - renewZookeeperInstance(sessionTimeout, quorumServers); checkRedundantNode("/" + parent); - if (zooKeeper != null) { - zooKeeper.close(); - zooKeeper = null; - } } catch (Exception e) { LOG.warn("Exception while removing all redundant nodes", e); } @@ -637,19 +595,19 @@ private void removeAllRedundantNodes() { private void checkRedundantNode(String node) { try { // Nothing to do if it is a lock mode - if (getLockMode(ctx.getConf(), node) != null) { + if (getLockMode(node) != null) { return; } - List children = zooKeeper.getChildren(node, false); + List children = curatorFramework.getChildren().forPath(node); for (String child : children) { checkRedundantNode(node + "/" + child); } - children = zooKeeper.getChildren(node, false); + children = curatorFramework.getChildren().forPath(node); if ((children == null) || (children.isEmpty())) { - zooKeeper.delete(node, -1); + curatorFramework.delete().forPath(node); } } catch (Exception e) { LOG.warn("Error in checkRedundantNode for node " + node, e); @@ -658,12 +616,7 @@ private void checkRedundantNode(String node) { /* Release all transient locks, by simply closing the client */ public void close() throws LockException { - try { - - if (zooKeeper != null) { - zooKeeper.close(); - zooKeeper = null; - } + try { if (HiveConf.getBoolVar(ctx.getConf(), HiveConf.ConfVars.HIVE_ZOOKEEPER_CLEAN_EXTRA_NODES)) { removeAllRedundantNodes(); @@ -750,7 +703,7 @@ private static HiveLockObject getLockObject(HiveConf conf, String path, private static Pattern exMode = Pattern.compile("^.*-(EXCLUSIVE)-([0-9]+)$"); /* Get the mode of the lock encoded in the path */ - private static HiveLockMode getLockMode(HiveConf conf, String path) { + private static HiveLockMode getLockMode(String path) { Matcher shMatcher = shMode.matcher(path); Matcher exMatcher = exMode.matcher(path); @@ -768,15 +721,6 @@ private static HiveLockMode getLockMode(HiveConf conf, String path) { @Override public void prepareRetry() throws LockException { - try { - if (zooKeeper != null && zooKeeper.getState() == ZooKeeper.States.CLOSED) { - // Reconnect if the connection is closed. - zooKeeper = null; - } - renewZookeeperInstance(sessionTimeout, quorumServers); - } catch (Exception e) { - throw new LockException(e); - } } } diff --git ql/src/test/org/apache/hadoop/hive/ql/lockmgr/zookeeper/TestZookeeperLockManager.java ql/src/test/org/apache/hadoop/hive/ql/lockmgr/zookeeper/TestZookeeperLockManager.java index aacb73f..ebe728b 100644 --- ql/src/test/org/apache/hadoop/hive/ql/lockmgr/zookeeper/TestZookeeperLockManager.java +++ ql/src/test/org/apache/hadoop/hive/ql/lockmgr/zookeeper/TestZookeeperLockManager.java @@ -18,70 +18,82 @@ package org.apache.hadoop.hive.ql.lockmgr.zookeeper; -import static org.mockito.Mockito.*; - -import java.util.Collections; - import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.ql.lockmgr.HiveLockMode; import org.apache.hadoop.hive.ql.lockmgr.HiveLockObject; +import org.apache.hadoop.hive.ql.lockmgr.HiveLockObject.HiveLockObjectData; import org.apache.hadoop.hive.ql.util.ZooKeeperHiveHelper; import org.apache.zookeeper.KeeperException; -import org.apache.zookeeper.ZooKeeper; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.RetryOneTime; +import org.apache.curator.test.TestingServer; import org.junit.Assert; import org.junit.Before; +import org.junit.After; import org.junit.Test; -import com.google.common.base.Joiner; - public class TestZookeeperLockManager { - private static final Joiner SLASH = Joiner.on("/"); - private static final String PARENT = "hive"; - private static final String TABLE = "t1"; - private static final String PARENT_LOCK_PATH = SLASH.join("", PARENT, TABLE); - private static final String TABLE_LOCK_PATH = SLASH.join("", PARENT, TABLE, "00001"); private HiveConf conf; - private ZooKeeper zooKeeper; + protected TestingServer server; + CuratorFramework client; private HiveLockObject hiveLock; private ZooKeeperHiveLock zLock; + private HiveLockObjectData lockObjData; + private static final String PARENT = "hive"; + private static final String TABLE = "t1"; + private static final String PARENT_LOCK_PATH = "/hive/t1"; + private static final String TABLE_LOCK_PATH = "/hive/t1/00001"; @Before public void setup() { conf = new HiveConf(); - zooKeeper = mock(ZooKeeper.class); - hiveLock = mock(HiveLockObject.class); - when(hiveLock.getName()).thenReturn(TABLE); + lockObjData = new HiveLockObjectData("1", "10", "SHARED", "show tables"); + hiveLock = new HiveLockObject(TABLE, lockObjData); zLock = new ZooKeeperHiveLock(TABLE_LOCK_PATH, hiveLock, HiveLockMode.SHARED); - } - @Test - public void testDeleteNoChildren() throws Exception { - ZooKeeperHiveLockManager.unlockPrimitive(conf, zooKeeper, zLock, PARENT); - verify(zooKeeper).delete(TABLE_LOCK_PATH, -1); - verify(zooKeeper).getChildren(PARENT_LOCK_PATH, false); - verify(zooKeeper).delete(PARENT_LOCK_PATH, -1); - verifyNoMoreInteractions(zooKeeper); + while (server == null) + { + try { + server = new TestingServer(); + CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder(); + client = builder.connectString(server.getConnectString()).retryPolicy(new RetryOneTime(1)).build(); + client.start(); + } catch (Exception e) { + System.err.println("Getting bind exception - retrying to allocate server"); + server = null; + } + } } - /** - * Tests two threads racing to delete PARENT_LOCK_PATH - */ - @Test - public void testDeleteNoChildrenNodeDoesNotExist() throws Exception { - doThrow(new KeeperException.NoNodeException()).when(zooKeeper).delete(PARENT_LOCK_PATH, -1); - ZooKeeperHiveLockManager.unlockPrimitive(conf, zooKeeper, zLock, PARENT); - verify(zooKeeper).delete(TABLE_LOCK_PATH, -1); - verify(zooKeeper).getChildren(PARENT_LOCK_PATH, false); - verify(zooKeeper).delete(PARENT_LOCK_PATH, -1); - verifyNoMoreInteractions(zooKeeper); + + @After + public void teardown() throws Exception + { + client.close(); + server.close(); + server = null; } + @Test - public void testDeleteWithChildren() throws Exception { - when(zooKeeper.getChildren(PARENT_LOCK_PATH, false)).thenReturn(Collections.singletonList("somechild")); - ZooKeeperHiveLockManager.unlockPrimitive(conf, zooKeeper, zLock, PARENT); - verify(zooKeeper).delete(TABLE_LOCK_PATH, -1); - verify(zooKeeper).getChildren(PARENT_LOCK_PATH, false); - verifyNoMoreInteractions(zooKeeper); + public void testDeleteNoChildren() throws Exception + { + client.create().creatingParentsIfNeeded().forPath(TABLE_LOCK_PATH, lockObjData.toString().getBytes()); + byte[] data = client.getData().forPath(TABLE_LOCK_PATH); + Assert.assertArrayEquals(lockObjData.toString().getBytes(), data); + ZooKeeperHiveLockManager.unlockPrimitive(zLock, PARENT, client); + try { + data = client.getData().forPath(TABLE_LOCK_PATH); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals( e instanceof KeeperException.NoNodeException, true); + } + try { + data = client.getData().forPath(PARENT_LOCK_PATH); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals( e instanceof KeeperException.NoNodeException, true); + } } @Test @@ -99,3 +111,4 @@ public void testGetQuorumServers() { Assert.assertEquals("node1:5666,node2:9999,node3:9999", ZooKeeperHiveHelper.getQuorumServers(conf)); } } + -- 1.8.5.2 (Apple Git-48)