Repository: hbase Updated Branches: refs/heads/branch-1 22320eeba -> f5305c603
HBASE-11974 When a disabled table is scanned, NotServingRegionException is thrown instead of TableNotEnabledException (Ted Yu) Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/f5305c60 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/f5305c60 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/f5305c60 Branch: refs/heads/branch-1 Commit: f5305c60390232892983c6990c2fa571a0a2d94a Parents: 22320ee Author: Enis Soztutar <e...@apache.org> Authored: Sun Sep 21 15:26:59 2014 -0700 Committer: Enis Soztutar <e...@apache.org> Committed: Sun Sep 21 15:27:18 2014 -0700 ---------------------------------------------------------------------- .../hadoop/hbase/client/ClusterConnection.java | 4 +-- .../hadoop/hbase/client/ConnectionAdapter.java | 2 +- .../hadoop/hbase/client/ConnectionManager.java | 12 ++++--- .../hadoop/hbase/client/ConnectionUtils.java | 34 +++++++++++++++++++- .../RpcRetryingCallerWithReadReplicas.java | 6 +++- .../apache/hadoop/hbase/client/TestAdmin.java | 14 +++++++- .../hadoop/hbase/client/TestReplicasClient.java | 7 ++++ 7 files changed, 68 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/f5305c60/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java index 8b576d8..a6db04a 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java @@ -113,11 +113,11 @@ public interface ClusterConnection extends HConnection { * @param tableName name of the table <i>row</i> is in * @param row row key you're trying to find the region of * @param replicaId the replicaId of the region - * @return HRegionLocation that describes where to find the region in + * @return RegionLocations that describe where to find the region in * question * @throws IOException if a remote or network exception occurs */ - HRegionLocation relocateRegion(final TableName tableName, + RegionLocations relocateRegion(final TableName tableName, final byte [] row, int replicaId) throws IOException; /** http://git-wip-us.apache.org/repos/asf/hbase/blob/f5305c60/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java index 9d1570d..12b549f 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java @@ -300,7 +300,7 @@ class ConnectionAdapter implements ClusterConnection { } @Override - public HRegionLocation relocateRegion(TableName tableName, byte[] row, int replicaId) + public RegionLocations relocateRegion(TableName tableName, byte[] row, int replicaId) throws IOException { return wrappedConnection.relocateRegion(tableName, row, replicaId); } http://git-wip-us.apache.org/repos/asf/hbase/blob/f5305c60/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java index 7c9c0b9..7fbf59d 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java @@ -1061,21 +1061,23 @@ class ConnectionManager { @Override public HRegionLocation relocateRegion(final TableName tableName, final byte [] row) throws IOException{ - return relocateRegion(tableName, row, RegionReplicaUtil.DEFAULT_REPLICA_ID); + RegionLocations locations = relocateRegion(tableName, row, + RegionReplicaUtil.DEFAULT_REPLICA_ID); + return locations == null ? null : + locations.getRegionLocation(RegionReplicaUtil.DEFAULT_REPLICA_ID); } @Override - public HRegionLocation relocateRegion(final TableName tableName, + public RegionLocations relocateRegion(final TableName tableName, final byte [] row, int replicaId) throws IOException{ // Since this is an explicit request not to use any caching, finding // disabled tables should not be desirable. This will ensure that an exception is thrown when // the first time a disabled table is interacted with. - if (isTableDisabled(tableName)) { + if (!tableName.equals(TableName.META_TABLE_NAME) && isTableDisabled(tableName)) { throw new TableNotEnabledException(tableName.getNameAsString() + " is disabled."); } - RegionLocations locations = locateRegion(tableName, row, false, true, replicaId); - return locations == null ? null : locations.getRegionLocation(replicaId); + return locateRegion(tableName, row, false, true, replicaId); } @Override http://git-wip-us.apache.org/repos/asf/hbase/blob/f5305c60/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java index 742ade4..86afc06 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java @@ -19,14 +19,19 @@ package org.apache.hadoop.hbase.client; import java.io.IOException; import java.util.Random; +import java.util.concurrent.ExecutorService; import org.apache.commons.logging.Log; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.AdminService; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ClientService; +import org.apache.hadoop.hbase.security.User; + +import com.google.common.annotations.VisibleForTesting; /** * Utility used by client connections. @@ -67,7 +72,7 @@ public class ConnectionUtils { } return newPause; } - + /** * @param conn The connection for which to replace the generator. * @param cnm Replaces the nonce generator used, for testing. @@ -123,4 +128,31 @@ public class ConnectionUtils { } }; } + + /** + * Setup the connection class, so that it will not depend on master being online. Used for testing + * @param conf configuration to set + */ + @VisibleForTesting + public static void setupMasterlessConnection(Configuration conf) { + conf.set(HConnection.HBASE_CLIENT_CONNECTION_IMPL, + MasterlessConnection.class.getName()); + } + + /** + * Some tests shut down the master. But table availability is a master RPC which is performed on + * region re-lookups. + */ + static class MasterlessConnection extends ConnectionManager.HConnectionImplementation { + MasterlessConnection(Configuration conf, boolean managed, + ExecutorService pool, User user) throws IOException { + super(conf, managed, pool, user); + } + + @Override + public boolean isTableDisabled(TableName tableName) throws IOException { + // treat all tables as enabled + return false; + } + } } http://git-wip-us.apache.org/repos/asf/hbase/blob/f5305c60/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerWithReadReplicas.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerWithReadReplicas.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerWithReadReplicas.java index f15ad02..ca59556 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerWithReadReplicas.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerWithReadReplicas.java @@ -283,7 +283,11 @@ public class RpcRetryingCallerWithReadReplicas { RegionLocations rl; try { - rl = cConnection.locateRegion(tableName, row, useCache, true, replicaId); + if (!useCache) { + rl = cConnection.relocateRegion(tableName, row, replicaId); + } else { + rl = cConnection.locateRegion(tableName, row, useCache, true, replicaId); + } } catch (DoNotRetryIOException e) { throw e; } catch (RetriesExhaustedException e) { http://git-wip-us.apache.org/repos/asf/hbase/blob/f5305c60/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java ---------------------------------------------------------------------- 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 29beaf9..e7b748e 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 @@ -265,7 +265,19 @@ public class TestAdmin { boolean ok = false; try { ht.get(get); - } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) { + } catch (TableNotEnabledException e) { + ok = true; + } + ok = false; + // verify that scan encounters correct exception + Scan scan = new Scan(); + try { + ResultScanner scanner = ht.getScanner(scan); + Result res = null; + do { + res = scanner.next(); + } while (res != null); + } catch (TableNotEnabledException e) { ok = true; } assertTrue(ok); http://git-wip-us.apache.org/repos/asf/hbase/blob/f5305c60/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java index 3fa6c95..ac6c178 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java @@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.client; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.commons.logging.impl.Log4JLogger; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.HBaseTestingUtility; @@ -44,6 +45,7 @@ import org.apache.hadoop.hbase.regionserver.StorefileRefresherChore; import org.apache.hadoop.hbase.regionserver.TestRegionServerNoMaster; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.zookeeper.ZKAssign; +import org.apache.log4j.Level; import org.apache.zookeeper.KeeperException; import org.junit.After; import org.junit.AfterClass; @@ -73,6 +75,10 @@ import java.util.concurrent.atomic.AtomicReference; public class TestReplicasClient { private static final Log LOG = LogFactory.getLog(TestReplicasClient.class); + static { + ((Log4JLogger)RpcRetryingCaller.LOG).getLogger().setLevel(Level.ALL); + } + private static final int NB_SERVERS = 1; private static HTable table = null; private static final byte[] row = TestReplicasClient.class.getName().getBytes(); @@ -156,6 +162,7 @@ public class TestReplicasClient { HTU.getConfiguration().setInt( StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD, REFRESH_PERIOD); HTU.getConfiguration().setBoolean("hbase.client.log.scanner.activity", true); + ConnectionUtils.setupMasterlessConnection(HTU.getConfiguration()); HTU.startMiniCluster(NB_SERVERS); // Create table then get the single region for our new table.