From 802f264f4e52bec44d6ce432821bc3ba9e7b52a3 Mon Sep 17 00:00:00 2001 From: gchanan Date: Sat, 15 Sep 2012 00:33:45 +0000 Subject: [PATCH] HBASE-6759 Forward port ZKReadOnly change from HBASE-6710 git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1384987 13f79535-47bb-0310-9956-ffa450edef68 --- .../hbase/client/HConnectionManager.java | 6 +- .../apache/hadoop/hbase/util/HBaseFsck.java | 4 +- .../hadoop/hbase/zookeeper/ZKTable.java | 126 +------------- .../hbase/zookeeper/ZKTableReadOnly.java | 161 ++++++++++++++++++ .../apache/hadoop/hbase/client/TestAdmin.java | 4 +- 5 files changed, 172 insertions(+), 129 deletions(-) create mode 100644 hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java index f5a5d909982..3657afc59f3 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java @@ -92,7 +92,7 @@ import org.apache.hadoop.hbase.util.Triple; import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker; import org.apache.hadoop.hbase.zookeeper.RootRegionTracker; import org.apache.hadoop.hbase.zookeeper.ZKClusterId; -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; @@ -880,9 +880,9 @@ public class HConnectionManager { ZooKeeperKeepAliveConnection zkw = getKeepAliveZooKeeperWatcher(); 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); }finally { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java index 727f64cbd87..26873c7cce8 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java @@ -91,7 +91,7 @@ import org.apache.hadoop.hbase.util.hbck.HFileCorruptionChecker; 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; @@ -1150,7 +1150,7 @@ public class HBaseFsck { public Void connect(HConnection connection) throws IOException { ZooKeeperWatcher zkw = createZooKeeperWatcher(); try { - for (String tableName : ZKTable.getDisabledOrDisablingTables(zkw)) { + for (String tableName : ZKTableReadOnly.getDisabledOrDisablingTables(zkw)) { disabledTables.add(Bytes.toBytes(tableName)); } } catch (KeeperException ke) { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java index fa068e141b8..e7bc810dcbb 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java @@ -40,9 +40,8 @@ import com.google.protobuf.InvalidProtocolBufferException; * 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}. + * *

To save on trips to the zookeeper ensemble, internally we cache table * state. */ @@ -83,39 +82,12 @@ public class ZKTable { List children = ZKUtil.listChildrenNoWatch(this.watcher, this.watcher.tableZNode); if (children == null) return; for (String child: children) { - ZooKeeperProtos.Table.State state = getTableState(this.watcher, child); + ZooKeeperProtos.Table.State state = ZKTableReadOnly.getTableState(this.watcher, child); if (state != null) this.cache.put(child, state); } } } - /** - * @param zkw - * @param child - * @return Null or {@link TableState} found in znode. - * @throws KeeperException - */ - private static ZooKeeperProtos.Table.State 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) return ZooKeeperProtos.Table.State.ENABLED; - try { - ProtobufUtil.expectPBMagicPrefix(data); - ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder(); - int magicLen = ProtobufUtil.lengthOfPBMagic(); - ZooKeeperProtos.Table t = builder.mergeFrom(data, magicLen, data.length - magicLen).build(); - return t.getState(); - } catch (InvalidProtocolBufferException e) { - KeeperException ke = new KeeperException.DataInconsistencyException(); - ke.initCause(e); - throw ke; - } catch (DeserializationException e) { - throw ZKUtil.convert(e); - } - } - /** * Sets the specified table as DISABLED in zookeeper. Fails silently if the * table is already disabled in zookeeper. Sets no watches. @@ -240,22 +212,6 @@ public class ZKTable { return isTableState(tableName, ZooKeeperProtos.Table.State.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 { - ZooKeeperProtos.Table.State state = getTableState(zkw, tableName); - return isTableState(ZooKeeperProtos.Table.State.DISABLED, state); - } - public boolean isDisablingTable(final String tableName) { return isTableState(tableName, ZooKeeperProtos.Table.State.DISABLING); } @@ -268,45 +224,12 @@ public class ZKTable { return isTableState(tableName, ZooKeeperProtos.Table.State.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 { - return getTableState(zkw, tableName) == ZooKeeperProtos.Table.State.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 { - ZooKeeperProtos.Table.State state = getTableState(zkw, tableName); - return isTableState(ZooKeeperProtos.Table.State.DISABLING, state) || - isTableState(ZooKeeperProtos.Table.State.DISABLED, state); - } - public boolean isEnabledOrDisablingTable(final String tableName) { synchronized (this.cache) { return isEnabledTable(tableName) || isDisablingTable(tableName); @@ -322,15 +245,10 @@ public class ZKTable { private boolean isTableState(final String tableName, final ZooKeeperProtos.Table.State state) { synchronized (this.cache) { ZooKeeperProtos.Table.State currentState = this.cache.get(tableName); - return isTableState(currentState, state); + return ZKTableReadOnly.isTableState(currentState, state); } } - private static boolean isTableState(final ZooKeeperProtos.Table.State expectedState, - final ZooKeeperProtos.Table.State 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. @@ -387,40 +305,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 getDisabledTables(ZooKeeperWatcher zkw) - throws KeeperException { - Set disabledTables = new HashSet(); - List children = - ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode); - for (String child: children) { - ZooKeeperProtos.Table.State state = getTableState(zkw, child); - if (state == ZooKeeperProtos.Table.State.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 getDisabledOrDisablingTables(ZooKeeperWatcher zkw) - throws KeeperException { - Set disabledTables = new HashSet(); - List children = - ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode); - for (String child: children) { - ZooKeeperProtos.Table.State state = getTableState(zkw, child); - if (state == ZooKeeperProtos.Table.State.DISABLED || - state == ZooKeeperProtos.Table.State.DISABLING) - disabledTables.add(child); - } - return disabledTables; - } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java new file mode 100644 index 00000000000..16a84a0a613 --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTableReadOnly.java @@ -0,0 +1,161 @@ +/** + * 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.DeserializationException; +import org.apache.hadoop.hbase.master.AssignmentManager; +import org.apache.zookeeper.KeeperException; +import org.apache.hadoop.hbase.protobuf.ProtobufUtil; +import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos; + +import com.google.protobuf.InvalidProtocolBufferException; + +/** + * Non-instantiable class that provides helper functions for + * clients other than {@link AssignmentManager} for reading the + * state of a table in ZK. + * + *

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 { + ZooKeeperProtos.Table.State state = getTableState(zkw, tableName); + return isTableState(ZooKeeperProtos.Table.State.DISABLED, state); + } + + /** + * 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 { + return getTableState(zkw, tableName) == ZooKeeperProtos.Table.State.ENABLED; + } + + /** + * 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 { + ZooKeeperProtos.Table.State state = getTableState(zkw, tableName); + return isTableState(ZooKeeperProtos.Table.State.DISABLING, state) || + isTableState(ZooKeeperProtos.Table.State.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 getDisabledTables(ZooKeeperWatcher zkw) + throws KeeperException { + Set disabledTables = new HashSet(); + List children = + ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode); + for (String child: children) { + ZooKeeperProtos.Table.State state = getTableState(zkw, child); + if (state == ZooKeeperProtos.Table.State.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 getDisabledOrDisablingTables(ZooKeeperWatcher zkw) + throws KeeperException { + Set disabledTables = new HashSet(); + List children = + ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode); + for (String child: children) { + ZooKeeperProtos.Table.State state = getTableState(zkw, child); + if (state == ZooKeeperProtos.Table.State.DISABLED || + state == ZooKeeperProtos.Table.State.DISABLING) + disabledTables.add(child); + } + return disabledTables; + } + + static boolean isTableState(final ZooKeeperProtos.Table.State expectedState, + final ZooKeeperProtos.Table.State currentState) { + return currentState != null && currentState.equals(expectedState); + } + + /** + * @param zkw + * @param child + * @return Null or {@link TableState} found in znode. + * @throws KeeperException + */ + static ZooKeeperProtos.Table.State 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) return ZooKeeperProtos.Table.State.ENABLED; + try { + ProtobufUtil.expectPBMagicPrefix(data); + ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder(); + int magicLen = ProtobufUtil.lengthOfPBMagic(); + ZooKeeperProtos.Table t = builder.mergeFrom(data, magicLen, data.length - magicLen).build(); + return t.getState(); + } catch (InvalidProtocolBufferException e) { + KeeperException ke = new KeeperException.DataInconsistencyException(); + ke.initCause(e); + throw ke; + } catch (DeserializationException e) { + throw ZKUtil.convert(e); + } + } +} diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java index 76924871d3a..8eec74f8447 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java @@ -53,7 +53,7 @@ import org.apache.hadoop.hbase.regionserver.wal.HLogUtilsForTests; 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; @@ -1008,7 +1008,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);