You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gc...@apache.org on 2012/09/13 03:32:59 UTC
svn commit: r1384181 - in /hbase/branches/0.94/src:
main/java/org/apache/hadoop/hbase/client/
main/java/org/apache/hadoop/hbase/util/
main/java/org/apache/hadoop/hbase/zookeeper/
test/java/org/apache/hadoop/hbase/client/ test/java/org/apache/hadoop/hba...
Author: gchanan
Date: Thu Sep 13 01:32:58 2012
New Revision: 1384181
URL: http://svn.apache.org/viewvc?rev=1384181&view=rev
Log:
HBASE-6710 0.92/0.94 compatibility issues due to HBASE-5206
Added:
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java
hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTableReadOnly.java
Modified:
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTable.java
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=1384181&r1=1384180&r2=1384181&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java Thu Sep 13 01:32:58 2012
@@ -76,7 +76,7 @@ import org.apache.hadoop.hbase.util.Soft
import org.apache.hadoop.hbase.util.Writables;
import org.apache.hadoop.hbase.zookeeper.ClusterId;
import org.apache.hadoop.hbase.zookeeper.RootRegionTracker;
-import org.apache.hadoop.hbase.zookeeper.ZKTable;
+import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.apache.hadoop.ipc.RemoteException;
@@ -782,9 +782,9 @@ public class HConnectionManager {
String tableNameStr = Bytes.toString(tableName);
try {
if (online) {
- return ZKTable.isEnabledTable(zkw, tableNameStr);
+ return ZKTableReadOnly.isEnabledTable(zkw, tableNameStr);
}
- return ZKTable.isDisabledTable(zkw, tableNameStr);
+ return ZKTableReadOnly.isDisabledTable(zkw, tableNameStr);
} catch (KeeperException e) {
throw new IOException("Enable/Disable failed", e);
}
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java?rev=1384181&r1=1384180&r2=1384181&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java Thu Sep 13 01:32:58 2012
@@ -89,7 +89,7 @@ import org.apache.hadoop.hbase.util.hbck
import org.apache.hadoop.hbase.util.hbck.TableIntegrityErrorHandler;
import org.apache.hadoop.hbase.util.hbck.TableIntegrityErrorHandlerImpl;
import org.apache.hadoop.hbase.zookeeper.RootRegionTracker;
-import org.apache.hadoop.hbase.zookeeper.ZKTable;
+import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation;
@@ -1156,7 +1156,7 @@ public class HBaseFsck {
public Void connect(HConnection connection) throws IOException {
ZooKeeperWatcher zkw = connection.getZooKeeperWatcher();
try {
- for (String tableName : ZKTable.getDisabledOrDisablingTables(zkw)) {
+ for (String tableName : ZKTableReadOnly.getDisabledOrDisablingTables(zkw)) {
disabledTables.add(Bytes.toBytes(tableName));
}
} catch (KeeperException ke) {
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java?rev=1384181&r1=1384180&r2=1384181&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java Thu Sep 13 01:32:58 2012
@@ -36,9 +36,8 @@ import org.apache.zookeeper.KeeperExcept
* Reads, caches and sets state up in zookeeper. If multiple read/write
* clients, will make for confusion. Read-only clients other than
* AssignmentManager interested in learning table state can use the
- * read-only utility methods {@link #isEnabledTable(ZooKeeperWatcher, String)}
- * and {@link #isDisabledTable(ZooKeeperWatcher, String)}.
- *
+ * read-only utility methods in {@link ZKTableReadOnly}.
+ *
* <p>To save on trips to the zookeeper ensemble, internally we cache table
* state.
*/
@@ -63,8 +62,8 @@ public class ZKTable {
// Have watcher on table znode so all are notified of state or schema change.
/**
* States a Table can be in.
- * {@link TableState#ENABLED} is not used currently; its the absence of state
- * in zookeeper that indicates an enabled table currently.
+ * Compatibility note: ENABLED does not exist in 0.92 releases. In 0.92, the absence of
+ * the znode indicates the table is enabled.
*/
public static enum TableState {
ENABLED,
@@ -87,7 +86,7 @@ public class ZKTable {
throws KeeperException {
synchronized (this.cache) {
List<String> children =
- ZKUtil.listChildrenNoWatch(this.watcher, this.watcher.tableZNode);
+ ZKUtil.listChildrenNoWatch(this.watcher, this.watcher.masterTableZNode);
if (children == null) return;
for (String child: children) {
TableState state = getTableState(this.watcher, child);
@@ -105,18 +104,7 @@ public class ZKTable {
private static TableState getTableState(final ZooKeeperWatcher zkw,
final String child)
throws KeeperException {
- String znode = ZKUtil.joinZNode(zkw.tableZNode, child);
- byte [] data = ZKUtil.getData(zkw, znode);
- if (data == null || data.length <= 0) {
- // Null if table is enabled.
- return null;
- }
- String str = Bytes.toString(data);
- try {
- return TableState.valueOf(str);
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException(str);
- }
+ return ZKTableReadOnly.getTableState(zkw, zkw.masterTableZNode, child);
}
/**
@@ -226,11 +214,29 @@ public class ZKTable {
private void setTableState(final String tableName, final TableState state)
throws KeeperException {
- String znode = ZKUtil.joinZNode(this.watcher.tableZNode, tableName);
+ String znode = ZKUtil.joinZNode(this.watcher.masterTableZNode, tableName);
if (ZKUtil.checkExists(this.watcher, znode) == -1) {
ZKUtil.createAndFailSilent(this.watcher, znode);
}
+ String znode92 = ZKUtil.joinZNode(this.watcher.masterTableZNode92, tableName);
+ boolean settingToEnabled = (state == TableState.ENABLED);
+ // 0.92 format znode differs in that it is deleted to represent ENABLED,
+ // so only create if we are not setting to enabled.
+ if (!settingToEnabled) {
+ if (ZKUtil.checkExists(this.watcher, znode92) == -1) {
+ ZKUtil.createAndFailSilent(this.watcher, znode92);
+ }
+ }
synchronized (this.cache) {
+ if (settingToEnabled) {
+ ZKUtil.deleteNodeFailSilent(this.watcher, znode92);
+ }
+ else {
+ ZKUtil.setData(this.watcher, znode92, Bytes.toBytes(state.toString()));
+ }
+ // Set the current format znode after the 0.92 format znode.
+ // This is so in the case of failure, the AssignmentManager is guaranteed to
+ // see the state was not applied, since it uses the current format znode internally.
ZKUtil.setData(this.watcher, znode, Bytes.toBytes(state.toString()));
this.cache.put(tableName, state);
}
@@ -240,22 +246,6 @@ public class ZKTable {
return isTableState(tableName, TableState.DISABLED);
}
- /**
- * Go to zookeeper and see if state of table is {@link TableState#DISABLED}.
- * This method does not use cache as {@link #isDisabledTable(String)} does.
- * This method is for clients other than {@link AssignmentManager}
- * @param zkw
- * @param tableName
- * @return True if table is enabled.
- * @throws KeeperException
- */
- public static boolean isDisabledTable(final ZooKeeperWatcher zkw,
- final String tableName)
- throws KeeperException {
- TableState state = getTableState(zkw, tableName);
- return isTableState(TableState.DISABLED, state);
- }
-
public boolean isDisablingTable(final String tableName) {
return isTableState(tableName, TableState.DISABLING);
}
@@ -268,46 +258,12 @@ public class ZKTable {
return isTableState(tableName, TableState.ENABLED);
}
- /**
- * Go to zookeeper and see if state of table is {@link TableState#ENABLED}.
- * This method does not use cache as {@link #isEnabledTable(String)} does.
- * This method is for clients other than {@link AssignmentManager}
- * @param zkw
- * @param tableName
- * @return True if table is enabled.
- * @throws KeeperException
- */
- public static boolean isEnabledTable(final ZooKeeperWatcher zkw,
- final String tableName)
- throws KeeperException {
- TableState state = getTableState(zkw, tableName);
- return state == null || state == TableState.ENABLED;
- }
-
public boolean isDisablingOrDisabledTable(final String tableName) {
synchronized (this.cache) {
return isDisablingTable(tableName) || isDisabledTable(tableName);
}
}
- /**
- * Go to zookeeper and see if state of table is {@link TableState#DISABLING}
- * of {@link TableState#DISABLED}.
- * This method does not use cache as {@link #isEnabledTable(String)} does.
- * This method is for clients other than {@link AssignmentManager}.
- * @param zkw
- * @param tableName
- * @return True if table is enabled.
- * @throws KeeperException
- */
- public static boolean isDisablingOrDisabledTable(final ZooKeeperWatcher zkw,
- final String tableName)
- throws KeeperException {
- TableState state = getTableState(zkw, tableName);
- return isTableState(TableState.DISABLING, state) ||
- isTableState(TableState.DISABLED, state);
- }
-
public boolean isEnabledOrDisablingTable(final String tableName) {
synchronized (this.cache) {
return isEnabledTable(tableName) || isDisablingTable(tableName);
@@ -323,15 +279,10 @@ public class ZKTable {
private boolean isTableState(final String tableName, final TableState state) {
synchronized (this.cache) {
TableState currentState = this.cache.get(tableName);
- return isTableState(currentState, state);
+ return ZKTableReadOnly.isTableState(currentState, state);
}
}
- private static boolean isTableState(final TableState expectedState,
- final TableState currentState) {
- return currentState != null && currentState.equals(expectedState);
- }
-
/**
* Deletes the table in zookeeper. Fails silently if the
* table is not currently disabled in zookeeper. Sets no watches.
@@ -341,12 +292,17 @@ public class ZKTable {
public void setDeletedTable(final String tableName)
throws KeeperException {
synchronized (this.cache) {
+ ZKUtil.deleteNodeFailSilent(this.watcher,
+ ZKUtil.joinZNode(this.watcher.masterTableZNode92, tableName));
+ // Delete the current format znode after the 0.92 format znode.
+ // This is so in the case of failure, the AssignmentManager is guaranteed to
+ // see the table was not deleted, since it uses the current format znode internally.
+ ZKUtil.deleteNodeFailSilent(this.watcher,
+ ZKUtil.joinZNode(this.watcher.masterTableZNode, tableName));
if (this.cache.remove(tableName) == null) {
LOG.warn("Moving table " + tableName + " state to deleted but was " +
"already deleted");
}
- ZKUtil.deleteNodeFailSilent(this.watcher,
- ZKUtil.joinZNode(this.watcher.tableZNode, tableName));
}
}
@@ -389,38 +345,4 @@ public class ZKTable {
return disabledTables;
}
- /**
- * Gets a list of all the tables set as disabled in zookeeper.
- * @return Set of disabled tables, empty Set if none
- * @throws KeeperException
- */
- public static Set<String> getDisabledTables(ZooKeeperWatcher zkw)
- throws KeeperException {
- Set<String> disabledTables = new HashSet<String>();
- List<String> children =
- ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
- for (String child: children) {
- TableState state = getTableState(zkw, child);
- if (state == TableState.DISABLED) disabledTables.add(child);
- }
- return disabledTables;
- }
-
- /**
- * Gets a list of all the tables set as disabled in zookeeper.
- * @return Set of disabled tables, empty Set if none
- * @throws KeeperException
- */
- public static Set<String> getDisabledOrDisablingTables(ZooKeeperWatcher zkw)
- throws KeeperException {
- Set<String> disabledTables = new HashSet<String>();
- List<String> children =
- ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
- for (String child: children) {
- TableState state = getTableState(zkw, child);
- if (state == TableState.DISABLED || state == TableState.DISABLING)
- disabledTables.add(child);
- }
- return disabledTables;
- }
}
Added: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java?rev=1384181&view=auto
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java (added)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java Thu Sep 13 01:32:58 2012
@@ -0,0 +1,153 @@
+/**
+ * Copyright The Apache Software Foundation
+ *
+ * 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 java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.hadoop.hbase.master.AssignmentManager;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.zookeeper.ZKTable;
+import org.apache.hadoop.hbase.zookeeper.ZKTable.TableState;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Non-instantiable class that provides helper functions for
+ * clients other than {@link AssignmentManager} for reading the
+ * state of a table in ZK.
+ *
+ * <p>Does not cache state like {@link ZKTable}, actually reads from ZK each call.
+ */
+public class ZKTableReadOnly {
+
+ private ZKTableReadOnly() {}
+
+ /**
+ * Go to zookeeper and see if state of table is {@link TableState#DISABLED}.
+ * This method does not use cache as {@link #isDisabledTable(String)} does.
+ * This method is for clients other than {@link AssignmentManager}
+ * @param zkw
+ * @param tableName
+ * @return True if table is enabled.
+ * @throws KeeperException
+ */
+ public static boolean isDisabledTable(final ZooKeeperWatcher zkw,
+ final String tableName)
+ throws KeeperException {
+ TableState state = getTableState(zkw, tableName);
+ return isTableState(TableState.DISABLED, state);
+ }
+
+ /**
+ * Go to zookeeper and see if state of table is {@link TableState#ENABLED}.
+ * @param zkw
+ * @param tableName
+ * @return True if table is enabled.
+ * @throws KeeperException
+ */
+ public static boolean isEnabledTable(final ZooKeeperWatcher zkw,
+ final String tableName) throws KeeperException {
+ TableState state = getTableState(zkw, tableName);
+ return state == null || state == TableState.ENABLED;
+ }
+
+ /**
+ * Go to zookeeper and see if state of table is {@link TableState#DISABLING}
+ * of {@link TableState#DISABLED}.
+ * @param zkw
+ * @param tableName
+ * @return True if table is enabled.
+ * @throws KeeperException
+ */
+ public static boolean isDisablingOrDisabledTable(final ZooKeeperWatcher zkw,
+ final String tableName) throws KeeperException {
+ TableState state = getTableState(zkw, tableName);
+ return isTableState(TableState.DISABLING, state) ||
+ isTableState(TableState.DISABLED, state);
+ }
+
+ /**
+ * Gets a list of all the tables set as disabled in zookeeper.
+ * @return Set of disabled tables, empty Set if none
+ * @throws KeeperException
+ */
+ public static Set<String> getDisabledTables(ZooKeeperWatcher zkw)
+ throws KeeperException {
+ Set<String> disabledTables = new HashSet<String>();
+ List<String> children =
+ ZKUtil.listChildrenNoWatch(zkw, zkw.clientTableZNode);
+ for (String child: children) {
+ TableState state = getTableState(zkw, child);
+ if (state == TableState.DISABLED) disabledTables.add(child);
+ }
+ return disabledTables;
+ }
+
+ /**
+ * Gets a list of all the tables set as disabled in zookeeper.
+ * @return Set of disabled tables, empty Set if none
+ * @throws KeeperException
+ */
+ public static Set<String> getDisabledOrDisablingTables(ZooKeeperWatcher zkw)
+ throws KeeperException {
+ Set<String> disabledTables = new HashSet<String>();
+ List<String> children =
+ ZKUtil.listChildrenNoWatch(zkw, zkw.clientTableZNode);
+ for (String child: children) {
+ TableState state = getTableState(zkw, child);
+ if (state == TableState.DISABLED || state == TableState.DISABLING)
+ disabledTables.add(child);
+ }
+ return disabledTables;
+ }
+
+ static boolean isTableState(final TableState expectedState,
+ final TableState currentState) {
+ return currentState != null && currentState.equals(expectedState);
+ }
+
+ /**
+ * Read the TableState from ZooKeeper
+ * @throws KeeperException
+ */
+ static TableState getTableState(final ZooKeeperWatcher zkw,
+ final String child) throws KeeperException {
+ return getTableState(zkw, zkw.clientTableZNode, child);
+ }
+
+ /**
+ * @deprecated Only for 0.92/0.94 compatibility. Use getTableState(zkw, child) instead.
+ */
+ static TableState getTableState(final ZooKeeperWatcher zkw,
+ final String parent, final String child) throws KeeperException {
+ String znode = ZKUtil.joinZNode(parent, child);
+ byte [] data = ZKUtil.getData(zkw, znode);
+ if (data == null || data.length <= 0) {
+ return null;
+ }
+ String str = Bytes.toString(data);
+ try {
+ return TableState.valueOf(str);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(str);
+ }
+ }
+}
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java?rev=1384181&r1=1384180&r2=1384181&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java Thu Sep 13 01:32:58 2012
@@ -725,7 +725,8 @@ public class ZKUtil {
(node.equals(zkw.clusterIdZNode) == true) ||
(node.equals(zkw.rsZNode) == true) ||
(node.equals(zkw.backupMasterAddressesZNode) == true) ||
- (node.startsWith(zkw.tableZNode) == true)) {
+ (node.startsWith(zkw.masterTableZNode) == true) ||
+ (node.startsWith(zkw.masterTableZNode92) == true)) {
return ZooKeeperWatcher.CREATOR_ALL_AND_WORLD_READABLE;
}
return Ids.CREATOR_ALL_ACL;
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java?rev=1384181&r1=1384180&r2=1384181&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java Thu Sep 13 01:32:58 2012
@@ -96,8 +96,13 @@ public class ZooKeeperWatcher implements
public String clusterStateZNode;
// znode used for region transitioning and assignment
public String assignmentZNode;
- // znode used for table disabling/enabling
- public String tableZNode;
+ // znode that the master uses for reading/writing the table disabling/enabling states
+ public String masterTableZNode;
+ // znode where the client reads table enabling/disabling states.
+ public String clientTableZNode;
+ // znode where the master writes table disabling/enabling states in the format expected
+ // by 0.92.0/0.92.1 clients for backwards compatibility. See HBASE-6710 for details.
+ public String masterTableZNode92;
// znode containing the unique cluster ID
public String clusterIdZNode;
// znode used for log splitting work assignment
@@ -162,7 +167,8 @@ public class ZooKeeperWatcher implements
ZKUtil.createAndFailSilent(this, assignmentZNode);
ZKUtil.createAndFailSilent(this, rsZNode);
ZKUtil.createAndFailSilent(this, drainingZNode);
- ZKUtil.createAndFailSilent(this, tableZNode);
+ ZKUtil.createAndFailSilent(this, masterTableZNode);
+ ZKUtil.createAndFailSilent(this, masterTableZNode92);
ZKUtil.createAndFailSilent(this, splitLogZNode);
ZKUtil.createAndFailSilent(this, backupMasterAddressesZNode);
} catch (KeeperException e) {
@@ -210,8 +216,13 @@ public class ZooKeeperWatcher implements
conf.get("zookeeper.znode.state", "shutdown"));
assignmentZNode = ZKUtil.joinZNode(baseZNode,
conf.get("zookeeper.znode.unassigned", "unassigned"));
- tableZNode = ZKUtil.joinZNode(baseZNode,
- conf.get("zookeeper.znode.tableEnableDisable", "table"));
+ String tableZNodeDefault = "table";
+ masterTableZNode = ZKUtil.joinZNode(baseZNode,
+ conf.get("zookeeper.znode.masterTableEnableDisable", tableZNodeDefault));
+ clientTableZNode = ZKUtil.joinZNode(baseZNode,
+ conf.get("zookeeper.znode.clientTableEnableDisable", tableZNodeDefault));
+ masterTableZNode92 = ZKUtil.joinZNode(baseZNode,
+ conf.get("zookeeper.znode.masterTableEnableDisable92", "table92"));
clusterIdZNode = ZKUtil.joinZNode(baseZNode,
conf.get("zookeeper.znode.clusterId", "hbaseid"));
splitLogZNode = ZKUtil.joinZNode(baseZNode,
Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java?rev=1384181&r1=1384180&r2=1384181&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java Thu Sep 13 01:32:58 2012
@@ -51,7 +51,7 @@ import org.apache.hadoop.hbase.regionser
import org.apache.hadoop.hbase.InvalidFamilyOperationException;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
-import org.apache.hadoop.hbase.zookeeper.ZKTable;
+import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.junit.*;
import org.junit.experimental.categories.Category;
@@ -1005,7 +1005,7 @@ public class TestAdmin {
ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL);
byte [] tableName = Bytes.toBytes("testMasterAdmin");
TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
- while (!ZKTable.isEnabledTable(zkw, "testMasterAdmin")) {
+ while (!ZKTableReadOnly.isEnabledTable(zkw, "testMasterAdmin")) {
Thread.sleep(10);
}
this.admin.disableTable(tableName);
Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTable.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTable.java?rev=1384181&r1=1384180&r2=1384181&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTable.java (original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTable.java Thu Sep 13 01:32:58 2012
@@ -28,15 +28,18 @@ import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.*;
+import org.apache.hadoop.hbase.zookeeper.ZKTable.TableState;
import org.apache.zookeeper.KeeperException;
+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;
@Category(MediumTests.class)
public class TestZKTable {
- private static final Log LOG = LogFactory.getLog(TestZooKeeperNodeTracker.class);
+ private static final Log LOG = LogFactory.getLog(TestZKTable.class);
private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@BeforeClass
@@ -49,22 +52,23 @@ public class TestZKTable {
TEST_UTIL.shutdownMiniZKCluster();
}
+ Abortable abortable = new Abortable() {
+ @Override
+ public void abort(String why, Throwable e) {
+ LOG.info(why, e);
+ }
+
+ @Override
+ public boolean isAborted() {
+ return false;
+ }
+ };
+
@Test
public void testTableStates()
throws ZooKeeperConnectionException, IOException, KeeperException {
final String name = "testDisabled";
- Abortable abortable = new Abortable() {
- @Override
- public void abort(String why, Throwable e) {
- LOG.info(why, e);
- }
-
- @Override
- public boolean isAborted() {
- return false;
- }
-
- };
+
ZooKeeperWatcher zkw = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
name, abortable, true);
ZKTable zkt = new ZKTable(zkw);
@@ -106,8 +110,169 @@ public class TestZKTable {
assertFalse(zkt.isTablePresent(name));
}
+ /**
+ * Test that ZK table writes table state in formats expected by 0.92 and 0.94 clients
+ */
+ @Test
+ public void test9294Compatibility() throws Exception {
+ final String tableName = "test9294Compatibility";
+
+ ZooKeeperWatcher zkw = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
+ tableName, abortable, true);
+ ZKTable zkt = new ZKTable(zkw);
+ zkt.setEnabledTable(tableName);
+ // check that current/0.94 format table has proper ENABLED format
+ assertTrue(
+ ZKTableReadOnly.getTableState(zkw, zkw.masterTableZNode, tableName) == TableState.ENABLED);
+ // check that 0.92 format table is null, as expected by 0.92.0/0.92.1 clients
+ assertTrue(ZKTableReadOnly.getTableState(zkw, zkw.masterTableZNode92, tableName) == null);
+ }
+
+ /**
+ * RecoverableZookeeper that throws a KeeperException after throwExceptionInNumOperations
+ */
+ class ThrowingRecoverableZookeeper extends RecoverableZooKeeper {
+ private ZooKeeperWatcher zkw;
+ private int throwExceptionInNumOperations;
+
+ public ThrowingRecoverableZookeeper(ZooKeeperWatcher zkw) throws Exception {
+ super(ZKConfig.getZKQuorumServersString(TEST_UTIL.getConfiguration()),
+ HConstants.DEFAULT_ZK_SESSION_TIMEOUT, zkw, 3, 1000);
+ this.zkw = zkw;
+ this.throwExceptionInNumOperations = 0; // indicate not to throw an exception
+ }
+
+ public void setThrowExceptionInNumOperations(int throwExceptionInNumOperations) {
+ this.throwExceptionInNumOperations = throwExceptionInNumOperations;
+ }
+
+ private void checkThrowKeeperException() throws KeeperException {
+ if (throwExceptionInNumOperations == 1) {
+ throwExceptionInNumOperations = 0;
+ throw new KeeperException.DataInconsistencyException();
+ }
+ if(throwExceptionInNumOperations > 0) throwExceptionInNumOperations--;
+ }
+
+ public Stat setData(String path, byte[] data, int version)
+ throws KeeperException, InterruptedException {
+ checkThrowKeeperException();
+ return zkw.getRecoverableZooKeeper().setData(path, data, version);
+ }
+
+ public void delete(String path, int version)
+ throws InterruptedException, KeeperException {
+ checkThrowKeeperException();
+ zkw.getRecoverableZooKeeper().delete(path, version);
+ }
+ }
+ /**
+ * Because two ZooKeeper nodes are written for each table state transition
+ * {@link ZooKeeperWatcher#masterTableZNode} and {@link ZooKeeperWatcher#masterTableZNode92}
+ * it is possible that we fail in between the two operations and are left with
+ * inconsistent state. Check that we can get back to a consistent state by
+ * retrying the operation.
+ */
+ @Test
+ public void testDisableTableRetry() throws Exception {
+ final String tableName = "testDisableTableRetry";
+
+ ZooKeeperWatcher zkw = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
+ tableName, abortable, true);
+ ThrowingRecoverableZookeeper throwing = new ThrowingRecoverableZookeeper(zkw);
+ ZooKeeperWatcher spyZookeeperWatcher = Mockito.spy(zkw);
+ Mockito.doReturn(throwing).when(spyZookeeperWatcher).getRecoverableZooKeeper();
+
+ ZKTable zkt = new ZKTable(spyZookeeperWatcher);
+ zkt.setEnabledTable(tableName);
+ assertTrue(zkt.isEnabledOrDisablingTable(tableName));
+ boolean caughtExpectedException = false;
+ try {
+ // throw an exception on the second ZK operation, which means the first will succeed.
+ throwing.setThrowExceptionInNumOperations(2);
+ zkt.setDisabledTable(tableName);
+ } catch (KeeperException ke) {
+ caughtExpectedException = true;
+ }
+ assertTrue(caughtExpectedException);
+ assertFalse(zkt.isDisabledTable(tableName));
+ // try again, ensure table is disabled
+ zkt.setDisabledTable(tableName);
+ // ensure disabled from master perspective
+ assertTrue(zkt.isDisabledTable(tableName));
+ // ensure disabled from client perspective
+ assertTrue(ZKTableReadOnly.isDisabledTable(zkw, tableName));
+ }
+
+ /**
+ * Same as above, but with enableTable
+ */
+ @Test
+ public void testEnableTableRetry() throws Exception {
+ final String tableName = "testEnableTableRetry";
+
+ ZooKeeperWatcher zkw = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
+ tableName, abortable, true);
+ ThrowingRecoverableZookeeper throwing = new ThrowingRecoverableZookeeper(zkw);
+ ZooKeeperWatcher spyZookeeperWatcher = Mockito.spy(zkw);
+ Mockito.doReturn(throwing).when(spyZookeeperWatcher).getRecoverableZooKeeper();
+
+ ZKTable zkt = new ZKTable(spyZookeeperWatcher);
+ zkt.setDisabledTable(tableName);
+ assertTrue(zkt.isDisabledTable(tableName));
+ boolean caughtExpectedException = false;
+ try {
+ // throw an exception on the second ZK operation, which means the first will succeed.
+ throwing.throwExceptionInNumOperations = 2;
+ zkt.setEnabledTable(tableName);
+ } catch (KeeperException ke) {
+ caughtExpectedException = true;
+ }
+ assertTrue(caughtExpectedException);
+ assertFalse(zkt.isEnabledTable(tableName));
+ // try again, ensure table is enabled
+ zkt.setEnabledTable(tableName);
+ // ensure enabled from master perspective
+ assertTrue(zkt.isEnabledTable(tableName));
+ // ensure enabled from client perspective
+ assertTrue(ZKTableReadOnly.isEnabledTable(zkw, tableName));
+ }
+
+ /**
+ * Same as above, but with deleteTable
+ */
+ @Test
+ public void testDeleteTableRetry() throws Exception {
+ final String tableName = "testEnableTableRetry";
+
+ ZooKeeperWatcher zkw = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
+ tableName, abortable, true);
+ ThrowingRecoverableZookeeper throwing = new ThrowingRecoverableZookeeper(zkw);
+ ZooKeeperWatcher spyZookeeperWatcher = Mockito.spy(zkw);
+ Mockito.doReturn(throwing).when(spyZookeeperWatcher).getRecoverableZooKeeper();
+
+ ZKTable zkt = new ZKTable(spyZookeeperWatcher);
+ zkt.setDisabledTable(tableName);
+ assertTrue(zkt.isDisabledTable(tableName));
+ boolean caughtExpectedException = false;
+ try {
+ // throw an exception on the second ZK operation, which means the first will succeed.
+ throwing.setThrowExceptionInNumOperations(2);
+ zkt.setDeletedTable(tableName);
+ } catch (KeeperException ke) {
+ caughtExpectedException = true;
+ }
+ assertTrue(caughtExpectedException);
+ assertTrue(zkt.isTablePresent(tableName));
+ // try again, ensure table is deleted
+ zkt.setDeletedTable(tableName);
+ // ensure deleted from master perspective
+ assertFalse(zkt.isTablePresent(tableName));
+ // ensure deleted from client perspective
+ assertFalse(ZKTableReadOnly.getDisabledTables(zkw).contains(tableName));
+ }
+
@org.junit.Rule
public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
}
-
Added: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTableReadOnly.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTableReadOnly.java?rev=1384181&view=auto
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTableReadOnly.java (added)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/zookeeper/TestZKTableReadOnly.java Thu Sep 13 01:32:58 2012
@@ -0,0 +1,103 @@
+/**
+ * Copyright The Apache Software Foundation
+ *
+ * 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.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.*;
+import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(MediumTests.class)
+public class TestZKTableReadOnly {
+ private static final Log LOG = LogFactory.getLog(TestZooKeeperNodeTracker.class);
+ private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ TEST_UTIL.startMiniZKCluster();
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ TEST_UTIL.shutdownMiniZKCluster();
+ }
+
+ Abortable abortable = new Abortable() {
+ @Override
+ public void abort(String why, Throwable e) {
+ LOG.info(why, e);
+ }
+
+ @Override
+ public boolean isAborted() {
+ return false;
+ }
+ };
+
+ private boolean enableAndCheckEnabled(ZooKeeperWatcher zkw, String tableName) throws Exception {
+ // set the table to enabled, as that is the only state that differs
+ // between the two formats
+ ZKTable zkt = new ZKTable(zkw);
+ zkt.setEnabledTable(tableName);
+ return ZKTableReadOnly.isEnabledTable(zkw, tableName);
+ }
+
+ /**
+ * Test that client ZK reader can handle the 0.92 table znode format.
+ */
+ @Test
+ public void testClientCompatibilityWith92ZNode() throws Exception {
+ final String tableName = "testClientCompatibilityWith92ZNode";
+
+ // Set the client to read from the 0.92 table znode format
+ Configuration conf = HBaseConfiguration.create(TEST_UTIL.getConfiguration());
+ String znode92 = conf.get("zookeeper.znode.masterTableEnableDisable92", "table92");
+ conf.set("zookeeper.znode.clientTableEnableDisable", znode92);
+
+ ZooKeeperWatcher zkw = new ZooKeeperWatcher(conf,
+ tableName, abortable, true);
+ assertTrue(enableAndCheckEnabled(zkw, tableName));
+ }
+
+ /**
+ * Test that client ZK reader can handle the current (0.94) table format znode
+ */
+ @Test
+ public void testClientCompatibilityWith94ZNode() throws Exception {
+ final String tableName = "testClientCompatibilityWith94ZNode";
+
+ ZooKeeperWatcher zkw = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
+ tableName, abortable, true);
+ assertTrue(enableAndCheckEnabled(zkw, tableName));
+ }
+
+ @org.junit.Rule
+ public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
+ new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
+}