diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java index 3282838..9dfbac7 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java @@ -391,12 +391,10 @@ public class MetaTableAccessor { TableName tableName, final boolean excludeOfflinedSplitParents) throws IOException { List> result; - try { - result = getTableRegionsAndLocations(connection, tableName, - excludeOfflinedSplitParents); - } catch (InterruptedException e) { - throw (InterruptedIOException)new InterruptedIOException().initCause(e); - } + + result = getTableRegionsAndLocations(connection, tableName, + excludeOfflinedSplitParents); + return getListOfHRegionInfos(result); } @@ -459,11 +457,10 @@ public class MetaTableAccessor { * @param tableName table we're looking for * @return Return list of regioninfos and server. * @throws IOException - * @throws InterruptedException */ public static List> getTableRegionsAndLocations(Connection connection, TableName tableName) - throws IOException, InterruptedException { + throws IOException { return getTableRegionsAndLocations(connection, tableName, true); } @@ -473,11 +470,10 @@ public class MetaTableAccessor { * @param tableName table to work with * @return Return list of regioninfos and server addresses. * @throws IOException - * @throws InterruptedException */ public static List> getTableRegionsAndLocations( Connection connection, final TableName tableName, - final boolean excludeOfflinedSplitParents) throws IOException, InterruptedException { + final boolean excludeOfflinedSplitParents) throws IOException { if (tableName.equals(TableName.META_TABLE_NAME)) { throw new IOException("This method can't be used to locate meta regions;" + " use MetaTableLocator instead"); diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/UnknownRegionException.java hbase-client/src/main/java/org/apache/hadoop/hbase/UnknownRegionException.java index 2c16eba..2ebba32 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/UnknownRegionException.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/UnknownRegionException.java @@ -20,13 +20,14 @@ package org.apache.hadoop.hbase; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; +import org.apache.hadoop.hbase.client.DoNotRetryRegionException; /** * Thrown when we are asked to operate on a region we know nothing about. */ @InterfaceAudience.Public @InterfaceStability.Stable -public class UnknownRegionException extends RegionException { +public class UnknownRegionException extends DoNotRetryRegionException { private static final long serialVersionUID = 1968858760475205392L; public UnknownRegionException(String regionName) { diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java index a08cf79..06f44f5 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java @@ -18,6 +18,7 @@ */ package org.apache.hadoop.hbase.client; + import java.io.Closeable; import java.io.IOException; import java.util.List; @@ -27,7 +28,6 @@ import java.util.regex.Pattern; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.Abortable; import org.apache.hadoop.hbase.ClusterStatus; -import org.apache.hadoop.hbase.HBaseIOException; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HTableDescriptor; @@ -38,7 +38,6 @@ import org.apache.hadoop.hbase.TableExistsException; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.UnknownRegionException; -import org.apache.hadoop.hbase.ZooKeeperConnectionException; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; @@ -55,8 +54,6 @@ import org.apache.hadoop.hbase.snapshot.SnapshotCreationException; import org.apache.hadoop.hbase.snapshot.UnknownSnapshotException; import org.apache.hadoop.hbase.util.Pair; -import com.google.protobuf.ServiceException; - /** * The administrative API for HBase. Obtain an instance from an {@link Connection#getAdmin()} and * call {@link #close()} afterwards. @@ -85,13 +82,6 @@ public interface Admin extends Abortable, Closeable { Connection getConnection(); /** - * @return - true if the master server is running. Throws an exception otherwise. - * @throws ZooKeeperConnectionException - * @throws MasterNotRunningException - */ - boolean isMasterRunning() throws MasterNotRunningException, ZooKeeperConnectionException; - - /** * @param tableName Table to check. * @return True if table exists already. * @throws IOException @@ -99,9 +89,7 @@ public interface Admin extends Abortable, Closeable { boolean tableExists(final TableName tableName) throws IOException; /** - * List all the userspace tables. In other words, scan the hbase:meta table. If we wanted this to - * be really fast, we could implement a special catalog table that just contains table names and - * their descriptors. Right now, it only exists as part of the hbase:meta table's region info. + * List all the userspace tables. * * @return - returns an array of HTableDescriptors * @throws IOException if a remote or network exception occurs @@ -500,36 +488,32 @@ public interface Admin extends Abortable, Closeable { * * @param tableName table to flush * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void flush(final TableName tableName) throws IOException, InterruptedException; + void flush(final TableName tableName) throws IOException; /** * Flush an individual region. Synchronous operation. * * @param regionName region to flush * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void flushRegion(final byte[] regionName) throws IOException, InterruptedException; + void flushRegion(final byte[] regionName) throws IOException; /** * Compact a table. Asynchronous operation. * * @param tableName table to compact * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void compact(final TableName tableName) throws IOException, InterruptedException; + void compact(final TableName tableName) throws IOException; /** * Compact an individual region. Asynchronous operation. * * @param regionName region to compact * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void compactRegion(final byte[] regionName) throws IOException, InterruptedException; + void compactRegion(final byte[] regionName) throws IOException; /** * Compact a column family within a table. Asynchronous operation. @@ -537,10 +521,9 @@ public interface Admin extends Abortable, Closeable { * @param tableName table to compact * @param columnFamily column family within a table * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ void compact(final TableName tableName, final byte[] columnFamily) - throws IOException, InterruptedException; + throws IOException; /** * Compact a column family within a region. Asynchronous operation. @@ -548,28 +531,25 @@ public interface Admin extends Abortable, Closeable { * @param regionName region to compact * @param columnFamily column family within a region * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ void compactRegion(final byte[] regionName, final byte[] columnFamily) - throws IOException, InterruptedException; + throws IOException; /** * Major compact a table. Asynchronous operation. * * @param tableName table to major compact * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void majorCompact(TableName tableName) throws IOException, InterruptedException; + void majorCompact(TableName tableName) throws IOException; /** * Major compact a table or an individual region. Asynchronous operation. * * @param regionName region to major compact * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void majorCompactRegion(final byte[] regionName) throws IOException, InterruptedException; + void majorCompactRegion(final byte[] regionName) throws IOException; /** * Major compact a column family within a table. Asynchronous operation. @@ -577,10 +557,9 @@ public interface Admin extends Abortable, Closeable { * @param tableName table to major compact * @param columnFamily column family within a table * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ void majorCompact(TableName tableName, final byte[] columnFamily) - throws IOException, InterruptedException; + throws IOException; /** * Major compact a column family within region. Asynchronous operation. @@ -588,10 +567,9 @@ public interface Admin extends Abortable, Closeable { * @param regionName egion to major compact * @param columnFamily column family within a region * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ void majorCompactRegion(final byte[] regionName, final byte[] columnFamily) - throws IOException, InterruptedException; + throws IOException; /** * Move the region r to dest. @@ -605,20 +583,15 @@ public interface Admin extends Abortable, Closeable { * Here is an example: host187.example.com,60020,1289493121758 * @throws UnknownRegionException Thrown if we can't find a region named * encodedRegionName - * @throws ZooKeeperConnectionException - * @throws MasterNotRunningException */ void move(final byte[] encodedRegionName, final byte[] destServerName) - throws HBaseIOException, MasterNotRunningException, ZooKeeperConnectionException; + throws IOException; /** * @param regionName Region name to assign. - * @throws MasterNotRunningException - * @throws ZooKeeperConnectionException - * @throws IOException */ void assign(final byte[] regionName) - throws MasterNotRunningException, ZooKeeperConnectionException, IOException; + throws IOException; /** * Unassign a region from current hosting regionserver. Region will then be assigned to a @@ -628,12 +601,9 @@ public interface Admin extends Abortable, Closeable { * @param regionName Region to unassign. Will clear any existing RegionPlan if one found. * @param force If true, force unassign (Will remove region from regions-in-transition too if * present. If results in double assignment use hbck -fix to resolve. To be used by experts). - * @throws MasterNotRunningException - * @throws ZooKeeperConnectionException - * @throws IOException */ void unassign(final byte[] regionName, final boolean force) - throws MasterNotRunningException, ZooKeeperConnectionException, IOException; + throws IOException; /** * Offline specified region from master's in-memory state. It will not attempt to reassign the @@ -650,12 +620,11 @@ public interface Admin extends Abortable, Closeable { /** * Turn the load balancer on or off. * - * @param on If true, enable balancer. If false, disable balancer. * @param synchronous If true, it waits until current balance() call, if outstanding, to return. * @return Previous balancer value */ boolean setBalancerRunning(final boolean on, final boolean synchronous) - throws MasterNotRunningException, ZooKeeperConnectionException; + throws IOException; /** * Invoke the balancer. Will run the balancer and if regions to move, it will go ahead and do the @@ -663,35 +632,28 @@ public interface Admin extends Abortable, Closeable { * * @return True if balancer ran, false otherwise. */ - boolean balancer() - throws MasterNotRunningException, ZooKeeperConnectionException, ServiceException; + boolean balancer() throws IOException; /** * Enable/Disable the catalog janitor * * @param enable if true enables the catalog janitor * @return the previous state - * @throws ServiceException - * @throws MasterNotRunningException */ - boolean enableCatalogJanitor(boolean enable) throws ServiceException, MasterNotRunningException; + boolean enableCatalogJanitor(boolean enable) throws IOException; /** * Ask for a scan of the catalog table * * @return the number of entries cleaned - * @throws ServiceException - * @throws MasterNotRunningException */ - int runCatalogScan() throws ServiceException, MasterNotRunningException; + int runCatalogScan() throws IOException; /** * Query on the catalog janitor state (Enabled/Disabled?) * - * @throws ServiceException - * @throws org.apache.hadoop.hbase.MasterNotRunningException */ - boolean isCatalogJanitorEnabled() throws ServiceException, MasterNotRunningException; + boolean isCatalogJanitorEnabled() throws IOException; /** * Merge two regions. Asynchronous operation. @@ -710,18 +672,16 @@ public interface Admin extends Abortable, Closeable { * * @param tableName table to split * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void split(final TableName tableName) throws IOException, InterruptedException; + void split(final TableName tableName) throws IOException; /** * Split an individual region. Asynchronous operation. * * @param regionName region to split * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ - void splitRegion(final byte[] regionName) throws IOException, InterruptedException; + void splitRegion(final byte[] regionName) throws IOException; /** * Split a table. Asynchronous operation. @@ -729,10 +689,9 @@ public interface Admin extends Abortable, Closeable { * @param tableName table to split * @param splitPoint the explicit position to split on * @throws IOException if a remote or network exception occurs - * @throws InterruptedException interrupt exception occurred */ void split(final TableName tableName, final byte[] splitPoint) - throws IOException, InterruptedException; + throws IOException; /** * Split an individual region. Asynchronous operation. @@ -740,10 +699,9 @@ public interface Admin extends Abortable, Closeable { * @param regionName region to split * @param splitPoint the explicit position to split on * @throws IOException if a remote or network exception occurs - * @throws InterruptedException interrupt exception occurred */ void splitRegion(final byte[] regionName, final byte[] splitPoint) - throws IOException, InterruptedException; + throws IOException; /** * Modify an existing table, more IRB friendly version. Asynchronous operation. This means that @@ -753,7 +711,8 @@ public interface Admin extends Abortable, Closeable { * @param htd modified description of the table * @throws IOException if a remote or network exception occurs */ - void modifyTable(final TableName tableName, final HTableDescriptor htd) throws IOException; + void modifyTable(final TableName tableName, final HTableDescriptor htd) + throws IOException; /** * Shuts down the HBase cluster @@ -796,7 +755,8 @@ public interface Admin extends Abortable, Closeable { * @param descriptor descriptor which describes the new namespace * @throws IOException */ - void createNamespace(final NamespaceDescriptor descriptor) throws IOException; + void createNamespace(final NamespaceDescriptor descriptor) + throws IOException; /** * Modify an existing namespace @@ -804,7 +764,8 @@ public interface Admin extends Abortable, Closeable { * @param descriptor descriptor which describes the new namespace * @throws IOException */ - void modifyNamespace(final NamespaceDescriptor descriptor) throws IOException; + void modifyNamespace(final NamespaceDescriptor descriptor) + throws IOException; /** * Delete an existing namespace. Only empty namespaces (no tables) can be removed. @@ -821,7 +782,8 @@ public interface Admin extends Abortable, Closeable { * @return A descriptor * @throws IOException */ - NamespaceDescriptor getNamespaceDescriptor(final String name) throws IOException; + NamespaceDescriptor getNamespaceDescriptor(final String name) + throws IOException; /** * List available namespace descriptors @@ -829,7 +791,8 @@ public interface Admin extends Abortable, Closeable { * @return List of descriptors * @throws IOException */ - NamespaceDescriptor[] listNamespaceDescriptors() throws IOException; + NamespaceDescriptor[] listNamespaceDescriptors() + throws IOException; /** * Get list of table descriptors by namespace @@ -838,7 +801,8 @@ public interface Admin extends Abortable, Closeable { * @return A descriptor * @throws IOException */ - HTableDescriptor[] listTableDescriptorsByNamespace(final String name) throws IOException; + HTableDescriptor[] listTableDescriptorsByNamespace(final String name) + throws IOException; /** * Get list of table names by namespace @@ -847,7 +811,8 @@ public interface Admin extends Abortable, Closeable { * @return The list of table names in the namespace * @throws IOException */ - TableName[] listTableNamesByNamespace(final String name) throws IOException; + TableName[] listTableNamesByNamespace(final String name) + throws IOException; /** * Get the regions of a given table. @@ -856,7 +821,8 @@ public interface Admin extends Abortable, Closeable { * @return List of {@link HRegionInfo}. * @throws IOException */ - List getTableRegions(final TableName tableName) throws IOException; + List getTableRegions(final TableName tableName) + throws IOException; @Override void close() throws IOException; @@ -868,7 +834,8 @@ public interface Admin extends Abortable, Closeable { * @return HTD[] the tableDescriptor * @throws IOException if a remote or network exception occurs */ - HTableDescriptor[] getTableDescriptorsByTableName(List tableNames) throws IOException; + HTableDescriptor[] getTableDescriptorsByTableName(List tableNames) + throws IOException; /** * Get tableDescriptors @@ -877,7 +844,8 @@ public interface Admin extends Abortable, Closeable { * @return HTD[] the tableDescriptor * @throws IOException if a remote or network exception occurs */ - HTableDescriptor[] getTableDescriptors(List names) throws IOException; + HTableDescriptor[] getTableDescriptors(List names) + throws IOException; /** * Roll the log writer. That is, start writing log messages to a new file. @@ -891,14 +859,15 @@ public interface Admin extends Abortable, Closeable { * @throws IOException if a remote or network exception occurs * @throws org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException */ - byte[][] rollHLogWriter(String serverName) throws IOException, FailedLogCloseException; + byte[][] rollHLogWriter(String serverName) + throws IOException, FailedLogCloseException; /** * Helper delegage to getClusterStatus().getMasterCoprocessors(). * @return an array of master coprocessors * @see org.apache.hadoop.hbase.ClusterStatus#getMasterCoprocessors() */ - String[] getMasterCoprocessors(); + String[] getMasterCoprocessors() throws IOException; /** * Get the current compaction state of a table. It could be in a major compaction, a minor @@ -907,10 +876,9 @@ public interface Admin extends Abortable, Closeable { * @param tableName table to examine * @return the current compaction state * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ AdminProtos.GetRegionInfoResponse.CompactionState getCompactionState(final TableName tableName) - throws IOException, InterruptedException; + throws IOException; /** * Get the current compaction state of region. It could be in a major compaction, a minor @@ -919,10 +887,9 @@ public interface Admin extends Abortable, Closeable { * @param regionName region to examine * @return the current compaction state * @throws IOException if a remote or network exception occurs - * @throws InterruptedException */ AdminProtos.GetRegionInfoResponse.CompactionState getCompactionStateForRegion( - final byte[] regionName) throws IOException, InterruptedException; + final byte[] regionName) throws IOException; /** * Take a snapshot for the given table. If the table is enabled, a FLUSH-type snapshot will be @@ -1106,7 +1073,7 @@ public interface Admin extends Abortable, Closeable { * @throws IllegalArgumentException if the specified table has not a valid name */ void cloneSnapshot(final byte[] snapshotName, final TableName tableName) - throws IOException, TableExistsException, RestoreSnapshotException, InterruptedException; + throws IOException, TableExistsException, RestoreSnapshotException; /** * Create a new table by cloning the snapshot content. @@ -1119,7 +1086,7 @@ public interface Admin extends Abortable, Closeable { * @throws IllegalArgumentException if the specified table has not a valid name */ void cloneSnapshot(final String snapshotName, final TableName tableName) - throws IOException, TableExistsException, RestoreSnapshotException, InterruptedException; + throws IOException, TableExistsException, RestoreSnapshotException; /** * Execute a distributed procedure on a cluster. @@ -1279,7 +1246,7 @@ public interface Admin extends Abortable, Closeable { * @return A RegionServerCoprocessorRpcChannel instance */ CoprocessorRpcChannel coprocessorService(ServerName sn); - + /** * Update the configuration and trigger an online config change diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java index 398ecad..ba07ce4 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/ClusterConnection.java @@ -39,8 +39,10 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MasterService; // classes and unit tests only. public interface ClusterConnection extends HConnection { - /** @return - true if the master server is running */ + /** @return - true if the master server is running + * @deprecated this has been deprecated without a replacement */ @Override + @Deprecated boolean isMasterRunning() throws MasterNotRunningException, ZooKeeperConnectionException; diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java index b3a6295..0442fb9 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java @@ -44,6 +44,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.Chore; +import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HRegionInfo; @@ -854,6 +855,7 @@ class ConnectionManager { * @throws MasterNotRunningException - if the master is not running * @throws ZooKeeperConnectionException */ + @Deprecated @Override public boolean isMasterRunning() throws MasterNotRunningException, ZooKeeperConnectionException { @@ -1454,18 +1456,14 @@ class ConnectionManager { * @return A stub to do intf against the master * @throws MasterNotRunningException */ - @edu.umd.cs.findbugs.annotations.SuppressWarnings (value="SWL_SLEEP_WITH_LOCK_HELD") - Object makeStub() throws MasterNotRunningException { + Object makeStub() throws IOException { // The lock must be at the beginning to prevent multiple master creations // (and leaks) in a multithread context synchronized (masterAndZKLock) { Exception exceptionCaught = null; - Object stub = null; - int tries = 0; - while (!closed && stub == null) { - tries++; + if (!closed) { try { - stub = makeStubNoRetries(); + return makeStubNoRetries(); } catch (IOException e) { exceptionCaught = e; } catch (KeeperException e) { @@ -1474,34 +1472,10 @@ class ConnectionManager { exceptionCaught = e; } - if (exceptionCaught != null) - // It failed. If it's not the last try, we're going to wait a little - if (tries < numTries && !ExceptionUtil.isInterrupt(exceptionCaught)) { - // tries at this point is 1 or more; decrement to start from 0. - long pauseTime = ConnectionUtils.getPauseTime(pause, tries - 1); - LOG.info("getMaster attempt " + tries + " of " + numTries + - " failed; retrying after sleep of " + pauseTime + ", exception=" + - exceptionCaught); - - try { - Thread.sleep(pauseTime); - } catch (InterruptedException e) { - throw new MasterNotRunningException( - "Thread was interrupted while trying to connect to master.", e); - } - } else { - // Enough tries, we stop now - LOG.info("getMaster attempt " + tries + " of " + numTries + - " failed; no more retrying.", exceptionCaught); - throw new MasterNotRunningException(exceptionCaught); - } - } - - if (stub == null) { - // implies this.closed true - throw new MasterNotRunningException("Connection was closed while trying to get master"); + throw new MasterNotRunningException(exceptionCaught); + } else { + throw new DoNotRetryIOException("Connection was closed while trying to get master"); } - return stub; } } } @@ -1517,8 +1491,7 @@ class ConnectionManager { } @Override - @edu.umd.cs.findbugs.annotations.SuppressWarnings("SWL_SLEEP_WITH_LOCK_HELD") - MasterService.BlockingInterface makeStub() throws MasterNotRunningException { + MasterService.BlockingInterface makeStub() throws IOException { return (MasterService.BlockingInterface)super.makeStub(); } @@ -1724,7 +1697,14 @@ class ConnectionManager { synchronized (masterAndZKLock) { if (!isKeepAliveMasterConnectedAndRunning(this.masterServiceState)) { MasterServiceStubMaker stubMaker = new MasterServiceStubMaker(); - this.masterServiceState.stub = stubMaker.makeStub(); + try { + this.masterServiceState.stub = stubMaker.makeStub(); + } catch (MasterNotRunningException ex) { + throw ex; + } catch (IOException e) { + // rethrow as MasterNotRunningException so that we can keep the method sig + throw new MasterNotRunningException(e); + } } resetMasterServiceState(this.masterServiceState); } @@ -2396,6 +2376,10 @@ class ConnectionManager { close(); } + /** + * @deprecated Use {@link Admin#listTables()} instead + */ + @Deprecated @Override public HTableDescriptor[] listTables() throws IOException { MasterKeepAliveConnection master = getKeepAliveMasterService(); @@ -2410,6 +2394,10 @@ class ConnectionManager { } } + /** + * @deprecated Use {@link Admin#listTableNames()} instead + */ + @Deprecated @Override public String[] getTableNames() throws IOException { TableName[] tableNames = listTableNames(); @@ -2420,6 +2408,10 @@ class ConnectionManager { return result; } + /** + * @deprecated Use {@link Admin#listTableNames()} instead + */ + @Deprecated @Override public TableName[] listTableNames() throws IOException { MasterKeepAliveConnection master = getKeepAliveMasterService(); @@ -2434,6 +2426,10 @@ class ConnectionManager { } } + /** + * @deprecated Use {@link Admin#getTableDescriptorsByTableName(List)} instead + */ + @Deprecated @Override public HTableDescriptor[] getHTableDescriptorsByTableName( List tableNames) throws IOException { @@ -2450,6 +2446,10 @@ class ConnectionManager { } } + /** + * @deprecated Use {@link Admin#getTableDescriptorsByTableName(List)} instead + */ + @Deprecated @Override public HTableDescriptor[] getHTableDescriptors( List names) throws IOException { @@ -2471,7 +2471,9 @@ class ConnectionManager { * @param tableName table name * @throws IOException if the connection to master fails or if the table * is not found. + * @deprecated Use {@link Admin#getTableDescriptor(TableName)} instead */ + @Deprecated @Override public HTableDescriptor getHTableDescriptor(final TableName tableName) throws IOException { @@ -2493,6 +2495,10 @@ class ConnectionManager { throw new TableNotFoundException(tableName.getNameAsString()); } + /** + * @deprecated Use {@link Admin#getTableDescriptor(TableName)} instead + */ + @Deprecated @Override public HTableDescriptor getHTableDescriptor(final byte[] tableName) throws IOException { diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/DoNotRetryRegionException.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/DoNotRetryRegionException.java new file mode 100644 index 0000000..2ce30b4 --- /dev/null +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/DoNotRetryRegionException.java @@ -0,0 +1,38 @@ +/** + * 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.client; + +import org.apache.hadoop.hbase.DoNotRetryIOException; + +/** + * Similar to RegionException, but disables retries. + */ +public class DoNotRetryRegionException extends DoNotRetryIOException { + + private static final long serialVersionUID = 6907047686199321701L; + + public DoNotRetryRegionException() { + super(); + } + + public DoNotRetryRegionException(String s) { + super(s); + } + +} diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index 7136f72..d07293c 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -18,8 +18,6 @@ */ package org.apache.hadoop.hbase.client; - -import java.io.Closeable; import java.io.IOException; import java.io.InterruptedIOException; import java.net.SocketTimeoutException; @@ -39,8 +37,8 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.Abortable; import org.apache.hadoop.hbase.ClusterStatus; +import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.HBaseConfiguration; -import org.apache.hadoop.hbase.HBaseIOException; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HRegionInfo; @@ -65,7 +63,6 @@ import org.apache.hadoop.hbase.classification.InterfaceStability; import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitor; import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitorBase; import org.apache.hadoop.hbase.exceptions.DeserializationException; -import org.apache.hadoop.hbase.exceptions.MergeRegionException; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.MasterCoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController; @@ -113,6 +110,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterSta import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusResponse; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsProcedureDoneRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsProcedureDoneResponse; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsRestoreSnapshotDoneRequest; @@ -275,8 +273,9 @@ public class HBaseAdmin implements Admin { * otherwise. * @throws ZooKeeperConnectionException * @throws MasterNotRunningException + * @deprecated this has been deprecated without a replacement */ - @Override + @Deprecated public boolean isMasterRunning() throws MasterNotRunningException, ZooKeeperConnectionException { return connection.isMasterRunning(); @@ -314,7 +313,14 @@ public class HBaseAdmin implements Admin { */ @Override public HTableDescriptor[] listTables() throws IOException { - return this.connection.listTables(); + return executeCallable(new MasterCallable(getConnection()) { + @Override + public HTableDescriptor[] call(int callTimeout) throws ServiceException { + GetTableDescriptorsRequest req = + RequestConverter.buildGetTableDescriptorsRequest((List)null); + return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(null, req)); + } + }); } /** @@ -354,10 +360,16 @@ public class HBaseAdmin implements Admin { * List all of the names of userspace tables. * @return String[] table names * @throws IOException if a remote or network exception occurs + * @deprecated Use {@link Admin#listTableNames()} instead */ @Deprecated public String[] getTableNames() throws IOException { - return this.connection.getTableNames(); + TableName[] tableNames = listTableNames(); + String result[] = new String[tableNames.length]; + for (int i = 0; i < tableNames.length; i++) { + result[i] = tableNames[i].getNameAsString(); + } + return result; } /** @@ -365,11 +377,12 @@ public class HBaseAdmin implements Admin { * @param pattern The regular expression to match against * @return String[] table names * @throws IOException if a remote or network exception occurs + * @deprecated Use {@link Admin#listTables(Pattern)} instead. */ @Deprecated public String[] getTableNames(Pattern pattern) throws IOException { List matched = new ArrayList(); - for (String name: this.connection.getTableNames()) { + for (String name: getTableNames()) { if (pattern.matcher(name).matches()) { matched.add(name); } @@ -382,6 +395,7 @@ public class HBaseAdmin implements Admin { * @param regex The regular expression to match against * @return String[] table names * @throws IOException if a remote or network exception occurs + * @deprecated Use {@link Admin#listTables(Pattern)} instead. */ @Deprecated public String[] getTableNames(String regex) throws IOException { @@ -395,7 +409,14 @@ public class HBaseAdmin implements Admin { */ @Override public TableName[] listTableNames() throws IOException { - return this.connection.listTableNames(); + return executeCallable(new MasterCallable(getConnection()) { + @Override + public TableName[] call(int callTimeout) throws ServiceException { + return ProtobufUtil.getTableNameArray(master.getTableNames(null, + GetTableNamesRequest.newBuilder().build()) + .getTableNamesList()); + } + }); } /** @@ -408,7 +429,28 @@ public class HBaseAdmin implements Admin { @Override public HTableDescriptor getTableDescriptor(final TableName tableName) throws TableNotFoundException, IOException { - return this.connection.getHTableDescriptor(tableName); + if (tableName == null) return null; + if (tableName.equals(TableName.META_TABLE_NAME)) { + return HTableDescriptor.META_TABLEDESC; + } + HTableDescriptor htd = executeCallable(new MasterCallable(getConnection()) { + @Override + public HTableDescriptor call(int callTimeout) throws ServiceException { + GetTableDescriptorsResponse htds; + GetTableDescriptorsRequest req = + RequestConverter.buildGetTableDescriptorsRequest(tableName); + htds = master.getTableDescriptors(null, req); + + if (!htds.getTableSchemaList().isEmpty()) { + return HTableDescriptor.convert(htds.getTableSchemaList().get(0)); + } + return null; + } + }); + if (htd != null) { + return htd; + } + throw new TableNotFoundException(tableName.getNameAsString()); } public HTableDescriptor getTableDescriptor(final byte[] tableName) @@ -1488,7 +1530,7 @@ public class HBaseAdmin implements Admin { * {@inheritDoc} */ @Override - public void flush(final TableName tableName) throws IOException, InterruptedException { + public void flush(final TableName tableName) throws IOException { checkTableExists(tableName); if (isTableDisabled(tableName)) { LOG.info("Table is disabled: " + tableName.getNameAsString()); @@ -1502,7 +1544,7 @@ public class HBaseAdmin implements Admin { * {@inheritDoc} */ @Override - public void flushRegion(final byte[] regionName) throws IOException, InterruptedException { + public void flushRegion(final byte[] regionName) throws IOException { Pair regionServerPair = getRegion(regionName); if (regionServerPair == null) { throw new IllegalArgumentException("Unknown regionname: " + Bytes.toStringBinary(regionName)); @@ -1555,7 +1597,7 @@ public class HBaseAdmin implements Admin { */ @Override public void compact(final TableName tableName) - throws IOException, InterruptedException { + throws IOException { compact(tableName, null, false); } @@ -1564,7 +1606,7 @@ public class HBaseAdmin implements Admin { */ @Override public void compactRegion(final byte[] regionName) - throws IOException, InterruptedException { + throws IOException { compactRegion(regionName, null, false); } @@ -1574,7 +1616,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void compact(final String tableNameOrRegionName) - throws IOException, InterruptedException { + throws IOException { compact(Bytes.toBytes(tableNameOrRegionName)); } @@ -1584,7 +1626,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void compact(final byte[] tableNameOrRegionName) - throws IOException, InterruptedException { + throws IOException { try { compactRegion(tableNameOrRegionName, null, false); } catch (IllegalArgumentException e) { @@ -1597,7 +1639,7 @@ public class HBaseAdmin implements Admin { */ @Override public void compact(final TableName tableName, final byte[] columnFamily) - throws IOException, InterruptedException { + throws IOException { compact(tableName, columnFamily, false); } @@ -1606,7 +1648,7 @@ public class HBaseAdmin implements Admin { */ @Override public void compactRegion(final byte[] regionName, final byte[] columnFamily) - throws IOException, InterruptedException { + throws IOException { compactRegion(regionName, columnFamily, false); } @@ -1616,7 +1658,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void compact(String tableOrRegionName, String columnFamily) - throws IOException, InterruptedException { + throws IOException { compact(Bytes.toBytes(tableOrRegionName), Bytes.toBytes(columnFamily)); } @@ -1626,7 +1668,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void compact(final byte[] tableNameOrRegionName, final byte[] columnFamily) - throws IOException, InterruptedException { + throws IOException { try { compactRegion(tableNameOrRegionName, columnFamily, false); } catch (IllegalArgumentException e) { @@ -1640,7 +1682,7 @@ public class HBaseAdmin implements Admin { */ @Override public void majorCompact(final TableName tableName) - throws IOException, InterruptedException { + throws IOException { compact(tableName, null, true); } @@ -1649,7 +1691,7 @@ public class HBaseAdmin implements Admin { */ @Override public void majorCompactRegion(final byte[] regionName) - throws IOException, InterruptedException { + throws IOException { compactRegion(regionName, null, true); } @@ -1659,7 +1701,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void majorCompact(final String tableNameOrRegionName) - throws IOException, InterruptedException { + throws IOException { majorCompact(Bytes.toBytes(tableNameOrRegionName)); } @@ -1669,7 +1711,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void majorCompact(final byte[] tableNameOrRegionName) - throws IOException, InterruptedException { + throws IOException { try { compactRegion(tableNameOrRegionName, null, true); } catch (IllegalArgumentException e) { @@ -1683,7 +1725,7 @@ public class HBaseAdmin implements Admin { */ @Override public void majorCompact(final TableName tableName, final byte[] columnFamily) - throws IOException, InterruptedException { + throws IOException { compact(tableName, columnFamily, true); } @@ -1692,7 +1734,7 @@ public class HBaseAdmin implements Admin { */ @Override public void majorCompactRegion(final byte[] regionName, final byte[] columnFamily) - throws IOException, InterruptedException { + throws IOException { compactRegion(regionName, columnFamily, true); } @@ -1702,7 +1744,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void majorCompact(final String tableNameOrRegionName, final String columnFamily) - throws IOException, InterruptedException { + throws IOException { majorCompact(Bytes.toBytes(tableNameOrRegionName), Bytes.toBytes(columnFamily)); } @@ -1712,7 +1754,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void majorCompact(final byte[] tableNameOrRegionName, final byte[] columnFamily) - throws IOException, InterruptedException { + throws IOException { try { compactRegion(tableNameOrRegionName, columnFamily, true); } catch (IllegalArgumentException e) { @@ -1732,7 +1774,7 @@ public class HBaseAdmin implements Admin { * @throws InterruptedException */ private void compact(final TableName tableName, final byte[] columnFamily,final boolean major) - throws IOException, InterruptedException { + throws IOException { ZooKeeperWatcher zookeeper = null; try { checkTableExists(tableName); @@ -1775,7 +1817,7 @@ public class HBaseAdmin implements Admin { * @throws InterruptedException */ private void compactRegion(final byte[] regionName, final byte[] columnFamily,final boolean major) - throws IOException, InterruptedException { + throws IOException { Pair regionServerPair = getRegion(regionName); if (regionServerPair == null) { throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName)); @@ -1811,28 +1853,25 @@ public class HBaseAdmin implements Admin { * host187.example.com,60020,1289493121758 * @throws UnknownRegionException Thrown if we can't find a region named * encodedRegionName - * @throws ZooKeeperConnectionException - * @throws MasterNotRunningException */ @Override public void move(final byte [] encodedRegionName, final byte [] destServerName) - throws HBaseIOException, MasterNotRunningException, ZooKeeperConnectionException { - MasterKeepAliveConnection stub = connection.getKeepAliveMasterService(); - try { - MoveRegionRequest request = - RequestConverter.buildMoveRegionRequest(encodedRegionName, destServerName); - stub.moveRegion(null, request); - } catch (ServiceException se) { - IOException ioe = ProtobufUtil.getRemoteException(se); - if (ioe instanceof HBaseIOException) { - throw (HBaseIOException)ioe; + throws IOException { + + executeCallable(new MasterCallable(getConnection()) { + @Override + public Void call(int callTimeout) throws ServiceException { + try { + MoveRegionRequest request = + RequestConverter.buildMoveRegionRequest(encodedRegionName, destServerName); + master.moveRegion(null, request); + } catch (DeserializationException de) { + LOG.error("Could not parse destination server name: " + de); + throw new ServiceException(new DoNotRetryIOException(de)); + } + return null; } - LOG.error("Unexpected exception: " + se + " from calling HMaster.moveRegion"); - } catch (DeserializationException de) { - LOG.error("Could not parse destination server name: " + de); - } finally { - stub.close(); - } + }); } /** @@ -1901,14 +1940,13 @@ public class HBaseAdmin implements Admin { @Override public void offline(final byte [] regionName) throws IOException { - MasterKeepAliveConnection master = connection.getKeepAliveMasterService(); - try { - master.offlineRegion(null,RequestConverter.buildOfflineRegionRequest(regionName)); - } catch (ServiceException se) { - throw ProtobufUtil.getRemoteException(se); - } finally { - master.close(); - } + executeCallable(new MasterCallable(getConnection()) { + @Override + public Void call(int callTimeout) throws ServiceException { + master.offlineRegion(null,RequestConverter.buildOfflineRegionRequest(regionName)); + return null; + } + }); } /** @@ -1919,27 +1957,15 @@ public class HBaseAdmin implements Admin { */ @Override public boolean setBalancerRunning(final boolean on, final boolean synchronous) - throws MasterNotRunningException, ZooKeeperConnectionException { - MasterKeepAliveConnection stub = connection.getKeepAliveMasterService(); - try { - SetBalancerRunningRequest req = - RequestConverter.buildSetBalancerRunningRequest(on, synchronous); - return stub.setBalancerRunning(null, req).getPrevBalanceValue(); - } catch (ServiceException se) { - IOException ioe = ProtobufUtil.getRemoteException(se); - if (ioe instanceof MasterNotRunningException) { - throw (MasterNotRunningException)ioe; - } - if (ioe instanceof ZooKeeperConnectionException) { - throw (ZooKeeperConnectionException)ioe; + throws IOException { + return executeCallable(new MasterCallable(getConnection()) { + @Override + public Boolean call(int callTimeout) throws ServiceException { + SetBalancerRunningRequest req = + RequestConverter.buildSetBalancerRunningRequest(on, synchronous); + return master.setBalancerRunning(null, req).getPrevBalanceValue(); } - - // Throwing MasterNotRunningException even though not really valid in order to not - // break interface by adding additional exception type. - throw new MasterNotRunningException("Unexpected exception when calling balanceSwitch",se); - } finally { - stub.close(); - } + }); } /** @@ -1949,66 +1975,62 @@ public class HBaseAdmin implements Admin { * @return True if balancer ran, false otherwise. */ @Override - public boolean balancer() - throws MasterNotRunningException, ZooKeeperConnectionException, ServiceException { - MasterKeepAliveConnection stub = connection.getKeepAliveMasterService(); - try { - return stub.balance(null, RequestConverter.buildBalanceRequest()).getBalancerRan(); - } finally { - stub.close(); - } + public boolean balancer() throws IOException { + return executeCallable(new MasterCallable(getConnection()) { + @Override + public Boolean call(int callTimeout) throws ServiceException { + return master.balance(null, RequestConverter.buildBalanceRequest()).getBalancerRan(); + } + }); } /** * Enable/Disable the catalog janitor * @param enable if true enables the catalog janitor * @return the previous state - * @throws ServiceException * @throws MasterNotRunningException */ @Override - public boolean enableCatalogJanitor(boolean enable) - throws ServiceException, MasterNotRunningException { - MasterKeepAliveConnection stub = connection.getKeepAliveMasterService(); - try { - return stub.enableCatalogJanitor(null, - RequestConverter.buildEnableCatalogJanitorRequest(enable)).getPrevValue(); - } finally { - stub.close(); - } + public boolean enableCatalogJanitor(final boolean enable) + throws IOException { + return executeCallable(new MasterCallable(getConnection()) { + @Override + public Boolean call(int callTimeout) throws ServiceException { + return master.enableCatalogJanitor(null, + RequestConverter.buildEnableCatalogJanitorRequest(enable)).getPrevValue(); + } + }); } /** * Ask for a scan of the catalog table * @return the number of entries cleaned - * @throws ServiceException * @throws MasterNotRunningException */ @Override - public int runCatalogScan() throws ServiceException, MasterNotRunningException { - MasterKeepAliveConnection stub = connection.getKeepAliveMasterService(); - try { - return stub.runCatalogScan(null, - RequestConverter.buildCatalogScanRequest()).getScanResult(); - } finally { - stub.close(); - } + public int runCatalogScan() throws IOException { + return executeCallable(new MasterCallable(getConnection()) { + @Override + public Integer call(int callTimeout) throws ServiceException { + return master.runCatalogScan(null, + RequestConverter.buildCatalogScanRequest()).getScanResult(); + } + }); } /** * Query on the catalog janitor state (Enabled/Disabled?) - * @throws ServiceException * @throws org.apache.hadoop.hbase.MasterNotRunningException */ @Override - public boolean isCatalogJanitorEnabled() throws ServiceException, MasterNotRunningException { - MasterKeepAliveConnection stub = connection.getKeepAliveMasterService(); - try { - return stub.isCatalogJanitorEnabled(null, - RequestConverter.buildIsCatalogJanitorEnabledRequest()).getValue(); - } finally { - stub.close(); - } + public boolean isCatalogJanitorEnabled() throws IOException { + return executeCallable(new MasterCallable(getConnection()) { + @Override + public Boolean call(int callTimeout) throws ServiceException { + return master.isCatalogJanitorEnabled(null, + RequestConverter.buildIsCatalogJanitorEnabledRequest()).getValue(); + } + }); } /** @@ -2023,28 +2045,21 @@ public class HBaseAdmin implements Admin { public void mergeRegions(final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB, final boolean forcible) throws IOException { - MasterKeepAliveConnection master = connection - .getKeepAliveMasterService(); - try { - DispatchMergingRegionsRequest request = RequestConverter - .buildDispatchMergingRegionsRequest(encodedNameOfRegionA, - encodedNameOfRegionB, forcible); - master.dispatchMergingRegions(null, request); - } catch (ServiceException se) { - IOException ioe = ProtobufUtil.getRemoteException(se); - if (ioe instanceof UnknownRegionException) { - throw (UnknownRegionException) ioe; - } - if (ioe instanceof MergeRegionException) { - throw (MergeRegionException) ioe; + + executeCallable(new MasterCallable(getConnection()) { + @Override + public Void call(int callTimeout) throws ServiceException { + try { + DispatchMergingRegionsRequest request = RequestConverter + .buildDispatchMergingRegionsRequest(encodedNameOfRegionA, + encodedNameOfRegionB, forcible); + master.dispatchMergingRegions(null, request); + } catch (DeserializationException de) { + LOG.error("Could not parse destination server name: " + de); + } + return null; } - LOG.error("Unexpected exception: " + se - + " from calling HMaster.dispatchMergingRegions"); - } catch (DeserializationException de) { - LOG.error("Could not parse destination server name: " + de); - } finally { - master.close(); - } + }); } /** @@ -2052,7 +2067,7 @@ public class HBaseAdmin implements Admin { */ @Override public void split(final TableName tableName) - throws IOException, InterruptedException { + throws IOException { split(tableName, null); } @@ -2061,7 +2076,7 @@ public class HBaseAdmin implements Admin { */ @Override public void splitRegion(final byte[] regionName) - throws IOException, InterruptedException { + throws IOException { splitRegion(regionName, null); } @@ -2090,7 +2105,7 @@ public class HBaseAdmin implements Admin { */ @Override public void split(final TableName tableName, final byte [] splitPoint) - throws IOException, InterruptedException { + throws IOException { ZooKeeperWatcher zookeeper = null; try { checkTableExists(tableName); @@ -2125,7 +2140,7 @@ public class HBaseAdmin implements Admin { */ @Override public void splitRegion(final byte[] regionName, final byte [] splitPoint) - throws IOException, InterruptedException { + throws IOException { Pair regionServerPair = getRegion(regionName); if (regionServerPair == null) { throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName)); @@ -2142,7 +2157,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void split(final String tableNameOrRegionName, - final String splitPoint) throws IOException, InterruptedException { + final String splitPoint) throws IOException { split(Bytes.toBytes(tableNameOrRegionName), Bytes.toBytes(splitPoint)); } @@ -2152,7 +2167,7 @@ public class HBaseAdmin implements Admin { */ @Deprecated public void split(final byte[] tableNameOrRegionName, - final byte [] splitPoint) throws IOException, InterruptedException { + final byte [] splitPoint) throws IOException { try { splitRegion(tableNameOrRegionName, splitPoint); } catch (IllegalArgumentException e) { @@ -2167,6 +2182,7 @@ public class HBaseAdmin implements Admin { Bytes.compareTo(hri.getStartKey(), splitPoint) == 0) { throw new IOException("should not give a splitkey which equals to startkey!"); } + // TODO: This is not executed via retries AdminService.BlockingInterface admin = this.connection.getAdmin(sn); ProtobufUtil.split(admin, hri, splitPoint); } @@ -2614,9 +2630,16 @@ public class HBaseAdmin implements Admin { * @throws IOException if a remote or network exception occurs */ @Override - public HTableDescriptor[] getTableDescriptorsByTableName(List tableNames) + public HTableDescriptor[] getTableDescriptorsByTableName(final List tableNames) throws IOException { - return this.connection.getHTableDescriptorsByTableName(tableNames); + return executeCallable(new MasterCallable(getConnection()) { + @Override + public HTableDescriptor[] call(int callTimeout) throws Exception { + GetTableDescriptorsRequest req = + RequestConverter.buildGetTableDescriptorsRequest(tableNames); + return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(null, req)); + } + }); } /** @@ -2683,7 +2706,7 @@ public class HBaseAdmin implements Admin { */ @Override public CompactionState getCompactionState(final TableName tableName) - throws IOException, InterruptedException { + throws IOException { CompactionState state = CompactionState.NONE; ZooKeeperWatcher zookeeper = new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(), @@ -2753,7 +2776,7 @@ public class HBaseAdmin implements Admin { */ @Override public CompactionState getCompactionStateForRegion(final byte[] regionName) - throws IOException, InterruptedException { + throws IOException { try { Pair regionServerPair = getRegion(regionName); if (regionServerPair == null) { @@ -3138,12 +3161,7 @@ public class HBaseAdmin implements Admin { // The table does not exists, switch to clone. if (!tableExists(tableName)) { - try { - cloneSnapshot(snapshotName, tableName); - } catch (InterruptedException e) { - throw new InterruptedIOException("Interrupted when restoring a nonexistent table: " + - e.getMessage()); - } + cloneSnapshot(snapshotName, tableName); return; } @@ -3210,7 +3228,7 @@ public class HBaseAdmin implements Admin { * @throws IllegalArgumentException if the specified table has not a valid name */ public void cloneSnapshot(final byte[] snapshotName, final byte[] tableName) - throws IOException, TableExistsException, RestoreSnapshotException, InterruptedException { + throws IOException, TableExistsException, RestoreSnapshotException { cloneSnapshot(Bytes.toString(snapshotName), TableName.valueOf(tableName)); } @@ -3226,7 +3244,7 @@ public class HBaseAdmin implements Admin { */ @Override public void cloneSnapshot(final byte[] snapshotName, final TableName tableName) - throws IOException, TableExistsException, RestoreSnapshotException, InterruptedException { + throws IOException, TableExistsException, RestoreSnapshotException { cloneSnapshot(Bytes.toString(snapshotName), tableName); } @@ -3259,7 +3277,7 @@ public class HBaseAdmin implements Admin { */ @Override public void cloneSnapshot(final String snapshotName, final TableName tableName) - throws IOException, TableExistsException, RestoreSnapshotException, InterruptedException { + throws IOException, TableExistsException, RestoreSnapshotException { if (tableExists(tableName)) { throw new TableExistsException(tableName); } @@ -3614,45 +3632,6 @@ public class HBaseAdmin implements Admin { return QuotaRetriever.open(conf, filter); } - /** - * Parent of {@link MasterCallable} and {@link MasterCallable}. - * Has common methods. - * @param - */ - abstract static class MasterCallable implements RetryingCallable, Closeable { - protected HConnection connection; - protected MasterKeepAliveConnection master; - - public MasterCallable(final HConnection connection) { - this.connection = connection; - } - - @Override - public void prepare(boolean reload) throws IOException { - this.master = this.connection.getKeepAliveMasterService(); - } - - @Override - public void close() throws IOException { - // The above prepare could fail but this would still be called though masterAdmin is null - if (this.master != null) this.master.close(); - } - - @Override - public void throwable(Throwable t, boolean retrying) { - } - - @Override - public String getExceptionMessageAdditionalDetail() { - return ""; - } - - @Override - public long sleep(long pause, int tries) { - return ConnectionUtils.getPauseTime(pause, tries); - } - } - private V executeCallable(MasterCallable callable) throws IOException { RpcRetryingCaller caller = rpcCallerFactory.newCaller(); try { @@ -3730,7 +3709,7 @@ public class HBaseAdmin implements Admin { public CoprocessorRpcChannel coprocessorService(ServerName sn) { return new RegionServerCoprocessorRpcChannel(connection, sn); } - + @Override public void updateConfiguration(ServerName server) throws IOException { try { diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java index b5328bf..9a4ef69 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java @@ -21,7 +21,6 @@ package org.apache.hadoop.hbase.client; import java.io.IOException; import java.util.List; import java.util.concurrent.ExecutorService; - import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HRegionLocation; import org.apache.hadoop.hbase.HTableDescriptor; @@ -252,22 +251,27 @@ public interface HConnection extends Connection { /** * List all the userspace tables. In other words, scan the hbase:meta table. * - * If we wanted this to be really fast, we could implement a special - * catalog table that just contains table names and their descriptors. - * Right now, it only exists as part of the hbase:meta table's region info. - * * @return - returns an array of HTableDescriptors * @throws IOException if a remote or network exception occurs + * @deprecated Use {@link Admin#listTables()} instead. */ + @Deprecated HTableDescriptor[] listTables() throws IOException; // This is a bit ugly - We call this getTableNames in 0.94 and the // successor function, returning TableName, listTableNames in later versions // because Java polymorphism doesn't consider return value types + /** + * @deprecated Use {@link Admin#listTableNames()} instead. + */ @Deprecated String[] getTableNames() throws IOException; + /** + * @deprecated Use {@link Admin#listTables()} instead. + */ + @Deprecated TableName[] listTableNames() throws IOException; /** @@ -275,6 +279,7 @@ public interface HConnection extends Connection { * @return table metadata * @throws IOException if a remote or network exception occurs */ + @Deprecated HTableDescriptor getHTableDescriptor(TableName tableName) throws IOException; @@ -544,7 +549,9 @@ public interface HConnection extends Connection { * @param tableNames List of table names * @return HTD[] table metadata * @throws IOException if a remote or network exception occurs + * @deprecated Use {@link Admin#getTableDescriptor(TableName)} instead. */ + @Deprecated HTableDescriptor[] getHTableDescriptorsByTableName(List tableNames) throws IOException; @Deprecated diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java index c3a94e3..ca21f91 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java @@ -49,6 +49,7 @@ import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.RegionLocations; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; import org.apache.hadoop.hbase.client.AsyncProcess.AsyncRequestFuture; @@ -68,6 +69,8 @@ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateResponse; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction; import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.CompareType; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.util.Threads; @@ -563,8 +566,39 @@ public class HTable implements HTableInterface, RegionLocator { */ @Override public HTableDescriptor getTableDescriptor() throws IOException { - return new UnmodifyableHTableDescriptor( - this.connection.getHTableDescriptor(this.tableName)); + // TODO: This is the same as HBaseAdmin.getTableDescriptor(). Only keep one. + if (tableName == null) return null; + if (tableName.equals(TableName.META_TABLE_NAME)) { + return HTableDescriptor.META_TABLEDESC; + } + HTableDescriptor htd = executeMasterCallable( + new MasterCallable(getConnection()) { + @Override + public HTableDescriptor call(int callTimeout) throws ServiceException { + GetTableDescriptorsResponse htds; + GetTableDescriptorsRequest req = + RequestConverter.buildGetTableDescriptorsRequest(tableName); + htds = master.getTableDescriptors(null, req); + + if (!htds.getTableSchemaList().isEmpty()) { + return HTableDescriptor.convert(htds.getTableSchemaList().get(0)); + } + return null; + } + }); + if (htd != null) { + return new UnmodifyableHTableDescriptor(htd); + } + throw new TableNotFoundException(tableName.getNameAsString()); + } + + private V executeMasterCallable(MasterCallable callable) throws IOException { + RpcRetryingCaller caller = rpcCallerFactory.newCaller(); + try { + return caller.callWithRetries(callable, operationTimeout); + } finally { + callable.close(); + } } /** diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/MasterCallable.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/MasterCallable.java new file mode 100644 index 0000000..a636533 --- /dev/null +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/MasterCallable.java @@ -0,0 +1,60 @@ +/** + * 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.client; + +import java.io.Closeable; +import java.io.IOException; + +/** + * A RetryingCallable for master operations. + * @param return type + */ +abstract class MasterCallable implements RetryingCallable, Closeable { + protected HConnection connection; + protected MasterKeepAliveConnection master; + + public MasterCallable(final HConnection connection) { + this.connection = connection; + } + + @Override + public void prepare(boolean reload) throws IOException { + this.master = this.connection.getKeepAliveMasterService(); + } + + @Override + public void close() throws IOException { + // The above prepare could fail but this would still be called though masterAdmin is null + if (this.master != null) this.master.close(); + } + + @Override + public void throwable(Throwable t, boolean retrying) { + } + + @Override + public String getExceptionMessageAdditionalDetail() { + return ""; + } + + @Override + public long sleep(long pause, int tries) { + return ConnectionUtils.getPauseTime(pause, tries); + } +} \ No newline at end of file diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/NoServerForRegionException.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/NoServerForRegionException.java index e2e06b9..3b2630e 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/NoServerForRegionException.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/NoServerForRegionException.java @@ -27,7 +27,7 @@ import org.apache.hadoop.hbase.classification.InterfaceStability; */ @InterfaceAudience.Public @InterfaceStability.Stable -public class NoServerForRegionException extends RegionException { +public class NoServerForRegionException extends DoNotRetryRegionException { private static final long serialVersionUID = 1L << 11 - 1L; /** default constructor */ diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/RowTooBigException.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/RowTooBigException.java index 53ed7c9..e32127c 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/RowTooBigException.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/RowTooBigException.java @@ -18,7 +18,7 @@ */ package org.apache.hadoop.hbase.client; -import org.apache.hadoop.hbase.RegionException; + import org.apache.hadoop.hbase.classification.InterfaceAudience; /** @@ -27,7 +27,7 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience; * hbase.table.max.rowsize). */ @InterfaceAudience.Public -public class RowTooBigException extends RegionException { +public class RowTooBigException extends DoNotRetryRegionException { public RowTooBigException(String message) { super(message); diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java index 3a33760..71e2c38 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java @@ -40,6 +40,8 @@ import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HConnection; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.replication.ReplicationException; @@ -467,7 +469,14 @@ public class ReplicationAdmin implements Closeable { */ public List> listReplicated() throws IOException { List> replicationColFams = new ArrayList>(); - HTableDescriptor[] tables = this.connection.listTables(); + + Admin admin = new HBaseAdmin(this.connection.getConfiguration()); + HTableDescriptor[] tables; + try { + tables = admin.listTables(); + } finally { + if (admin!= null) admin.close(); + } for (HTableDescriptor table : tables) { HColumnDescriptor[] columns = table.getColumnFamilies(); diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/MergeRegionException.java hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/MergeRegionException.java index 3042ad8..b87e400 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/MergeRegionException.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/MergeRegionException.java @@ -17,16 +17,18 @@ */ package org.apache.hadoop.hbase.exceptions; -import org.apache.hadoop.hbase.RegionException; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; +import org.apache.hadoop.hbase.client.DoNotRetryRegionException; + + /** * Thrown when something is wrong in trying to merge two regions. */ @InterfaceAudience.Public @InterfaceStability.Stable -public class MergeRegionException extends RegionException { +public class MergeRegionException extends DoNotRetryRegionException { private static final long serialVersionUID = 4970899110066124122L; diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/procedure/flush/MasterFlushTableProcedureManager.java hbase-server/src/main/java/org/apache/hadoop/hbase/procedure/flush/MasterFlushTableProcedureManager.java index bc248b9..a529c4e 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/procedure/flush/MasterFlushTableProcedureManager.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/procedure/flush/MasterFlushTableProcedureManager.java @@ -126,20 +126,15 @@ public class MasterFlushTableProcedureManager extends MasterProcedureManager { // Each region server will get its own online regions for the table. // We may still miss regions that need to be flushed. List> regionsAndLocations; - try { - if (TableName.META_TABLE_NAME.equals(tableName)) { - regionsAndLocations = new MetaTableLocator().getMetaRegionsAndLocations( - master.getZooKeeper()); - } else { - regionsAndLocations = MetaTableAccessor.getTableRegionsAndLocations( - master.getShortCircuitConnection(), tableName, false); - } - } catch (InterruptedException e1) { - String msg = "Failed to get regions for '" + desc.getInstance() + "'"; - LOG.error(msg); - throw new IOException(msg, e1); + if (TableName.META_TABLE_NAME.equals(tableName)) { + regionsAndLocations = new MetaTableLocator().getMetaRegionsAndLocations( + master.getZooKeeper()); + } else { + regionsAndLocations = MetaTableAccessor.getTableRegionsAndLocations( + master.getShortCircuitConnection(), tableName, false); } + Set regionServers = new HashSet(regionsAndLocations.size()); for (Pair region : regionsAndLocations) { if (region != null && region.getFirst() != null && region.getSecond() != null) { diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java index beeedeb..56967f9 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java @@ -91,7 +91,7 @@ public class HBaseFsckRepair { * @throws KeeperException */ public static void fixUnassigned(Admin admin, HRegionInfo region) - throws IOException, KeeperException { + throws IOException, KeeperException, InterruptedException { HRegionInfo actualRegion = new HRegionInfo(region); // Force ZK node to OFFLINE so master assigns @@ -111,7 +111,7 @@ public class HBaseFsckRepair { * in comparators that is addressed by HBASE-5563. */ private static void forceOfflineInZK(Admin admin, final HRegionInfo region) - throws ZooKeeperConnectionException, KeeperException, IOException { + throws ZooKeeperConnectionException, KeeperException, IOException, InterruptedException { admin.assign(region.getRegionName()); } diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java index 415b7bb..0a99ff0 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java @@ -276,12 +276,8 @@ public class TestFromClientSide { TEST_UTIL.waitFor(6000, new Waiter.Predicate() { @Override public boolean evaluate() throws IOException { - try { - return TEST_UTIL.getHBaseAdmin().getCompactionState(TABLENAME) == - AdminProtos.GetRegionInfoResponse.CompactionState.NONE; - } catch (InterruptedException e) { - throw new IOException(e); - } + return TEST_UTIL.getHBaseAdmin().getCompactionState(TABLENAME) == + AdminProtos.GetRegionInfoResponse.CompactionState.NONE; } }); diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHBaseAdminNoCluster.java hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHBaseAdminNoCluster.java index 7521bb7..acf8e51 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHBaseAdminNoCluster.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHBaseAdminNoCluster.java @@ -18,8 +18,11 @@ package org.apache.hadoop.hbase.client; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.io.IOException; +import java.util.ArrayList; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.testclassification.ClientTests; @@ -32,10 +35,22 @@ import org.apache.hadoop.hbase.MasterNotRunningException; import org.apache.hadoop.hbase.PleaseHoldException; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.ZooKeeperConnectionException; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.BalanceRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest; import org.junit.Test; import org.junit.experimental.categories.Category; import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.mortbay.log.Log; import com.google.protobuf.RpcController; @@ -46,10 +61,10 @@ public class TestHBaseAdminNoCluster { /** * Verify that PleaseHoldException gets retried. * HBASE-8764 - * @throws IOException - * @throws ZooKeeperConnectionException - * @throws MasterNotRunningException - * @throws ServiceException + * @throws IOException + * @throws ZooKeeperConnectionException + * @throws MasterNotRunningException + * @throws ServiceException */ @Test public void testMasterMonitorCollableRetries() @@ -90,4 +105,219 @@ public class TestHBaseAdminNoCluster { if (connection != null)HConnectionManager.deleteConnection(configuration); } } + + @Test + public void testMasterOperationsRetries() throws Exception { + + // Admin.listTables() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.listTables(); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .getTableDescriptors((RpcController)Mockito.any(), + (GetTableDescriptorsRequest)Mockito.any()); + } + }); + + // Admin.listTableNames() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.listTableNames(); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .getTableNames((RpcController)Mockito.any(), + (GetTableNamesRequest)Mockito.any()); + } + }); + + // Admin.getTableDescriptor() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.getTableDescriptor(TableName.valueOf("getTableDescriptor")); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .getTableDescriptors((RpcController)Mockito.any(), + (GetTableDescriptorsRequest)Mockito.any()); + } + }); + + // Admin.getTableDescriptorsByTableName() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.getTableDescriptorsByTableName(new ArrayList()); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .getTableDescriptors((RpcController)Mockito.any(), + (GetTableDescriptorsRequest)Mockito.any()); + } + }); + + // Admin.move() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.move(new byte[0], null); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .moveRegion((RpcController)Mockito.any(), + (MoveRegionRequest)Mockito.any()); + } + }); + + // Admin.offline() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.offline(new byte[0]); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .offlineRegion((RpcController)Mockito.any(), + (OfflineRegionRequest)Mockito.any()); + } + }); + + // Admin.setBalancerRunning() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.setBalancerRunning(true, true); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .setBalancerRunning((RpcController)Mockito.any(), + (SetBalancerRunningRequest)Mockito.any()); + } + }); + + // Admin.balancer() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.balancer(); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .balance((RpcController)Mockito.any(), + (BalanceRequest)Mockito.any()); + } + }); + + // Admin.enabledCatalogJanitor() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.enableCatalogJanitor(true); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .enableCatalogJanitor((RpcController)Mockito.any(), + (EnableCatalogJanitorRequest)Mockito.any()); + } + }); + + // Admin.runCatalogScan() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.runCatalogScan(); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .runCatalogScan((RpcController)Mockito.any(), + (RunCatalogScanRequest)Mockito.any()); + } + }); + + // Admin.isCatalogJanitorEnabled() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.isCatalogJanitorEnabled(); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .isCatalogJanitorEnabled((RpcController)Mockito.any(), + (IsCatalogJanitorEnabledRequest)Mockito.any()); + } + }); + + // Admin.mergeRegions() + testMasterOperationIsRetried(new MethodCaller() { + @Override + public void call(Admin admin) throws Exception { + admin.mergeRegions(new byte[0], new byte[0], true); + } + @Override + public void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception { + Mockito.verify(masterAdmin, Mockito.atLeast(count)) + .dispatchMergingRegions((RpcController)Mockito.any(), + (DispatchMergingRegionsRequest)Mockito.any()); + } + }); + } + + private static interface MethodCaller { + void call(Admin admin) throws Exception; + void verify(MasterKeepAliveConnection masterAdmin, int count) throws Exception; + } + + private void testMasterOperationIsRetried(MethodCaller caller) throws Exception { + Configuration configuration = HBaseConfiguration.create(); + // Set the pause and retry count way down. + configuration.setLong(HConstants.HBASE_CLIENT_PAUSE, 1); + final int count = 10; + configuration.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, count); + + ClusterConnection connection = mock(ClusterConnection.class); + when(connection.getConfiguration()).thenReturn(configuration); + MasterKeepAliveConnection masterAdmin = + Mockito.mock(MasterKeepAliveConnection.class, new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + if (invocation.getMethod().getName().equals("close")) { + return null; + } + throw new MasterNotRunningException(); // all methods will throw an exception + } + }); + Mockito.when(connection.getKeepAliveMasterService()).thenReturn(masterAdmin); + + Admin admin = null; + try { + admin = new HBaseAdmin(connection); + + try { + caller.call(admin); // invoke the HBaseAdmin method + fail(); + } catch (RetriesExhaustedException e) { + Log.info("Expected fail", e); + } + // Assert we were called 'count' times. + caller.verify(masterAdmin, count); + } finally { + if (admin != null) {admin.close();} + } + } } \ No newline at end of file diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java index bd7e275..837e37b 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java @@ -40,7 +40,6 @@ import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HTableDescriptor; -import org.apache.hadoop.hbase.MasterNotRunningException; import org.apache.hadoop.hbase.NotServingRegionException; import org.apache.hadoop.hbase.RegionLocations; import org.apache.hadoop.hbase.TableNotFoundException; @@ -186,16 +185,6 @@ public class TestReplicasClient { TestRegionServerNoMaster.stopMasterAndAssignMeta(HTU); Configuration c = new Configuration(HTU.getConfiguration()); c.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1); - Admin ha = new HBaseAdmin(c); - for (boolean masterRuns = true; masterRuns; ) { - Thread.sleep(100); - try { - masterRuns = false; - masterRuns = ha.isMasterRunning(); - } catch (MasterNotRunningException ignored) { - } - } - ha.close(); LOG.info("Master has stopped"); } diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMaster.java hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMaster.java index 73a1663..74e35e5 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMaster.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMaster.java @@ -46,6 +46,7 @@ import org.apache.hadoop.hbase.testclassification.MasterTests; import org.apache.hadoop.hbase.testclassification.MediumTests; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; +import org.apache.hadoop.util.StringUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -64,6 +65,8 @@ public class TestMaster { @BeforeClass public static void beforeAllTests() throws Exception { + // we will retry operations when PleaseHoldException is thrown + TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3); // Start a cluster of two regionservers. TEST_UTIL.startMiniCluster(2); admin = TEST_UTIL.getHBaseAdmin(); @@ -173,7 +176,7 @@ public class TestMaster { admin.move(tableRegions.get(0).getEncodedNameAsBytes(), null); fail("Region should not be moved since master is not initialized"); } catch (IOException ioe) { - assertTrue(ioe instanceof PleaseHoldException); + assertTrue(StringUtils.stringifyException(ioe).contains("PleaseHoldException")); } finally { master.initialized = true; TEST_UTIL.deleteTable(tableName); diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionMergeTransactionOnCluster.java hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionMergeTransactionOnCluster.java index 1a14571..03586f8 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionMergeTransactionOnCluster.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionMergeTransactionOnCluster.java @@ -68,6 +68,7 @@ import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.FSUtils; import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.util.PairOfSameType; +import org.apache.hadoop.util.StringUtils; import org.apache.zookeeper.KeeperException; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -293,8 +294,9 @@ public class TestRegionMergeTransactionOnCluster { admin.mergeRegions(a.getEncodedNameAsBytes(), b.getEncodedNameAsBytes(), false); fail("Offline regions should not be able to merge"); } catch (IOException ie) { + System.out.println(ie); assertTrue("Exception should mention regions not online", - ie.getMessage().contains("regions not online") + StringUtils.stringifyException(ie).contains("regions not online") && ie instanceof MergeRegionException); } try { @@ -303,7 +305,7 @@ public class TestRegionMergeTransactionOnCluster { fail("A region should not be able to merge with itself, even forcifully"); } catch (IOException ie) { assertTrue("Exception should mention regions not online", - ie.getMessage().contains("region to itself") + StringUtils.stringifyException(ie).contains("region to itself") && ie instanceof MergeRegionException); } try { diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java index 29073ed..11fc280 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java @@ -40,7 +40,6 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.Abortable; import org.apache.hadoop.hbase.CoordinatedStateManager; import org.apache.hadoop.hbase.Coprocessor; -import org.apache.hadoop.hbase.HBaseIOException; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HConstants; @@ -227,33 +226,33 @@ public class TestSplitTransactionOnCluster { byte[] cf = Bytes.toBytes("cf"); htd.addFamily(new HColumnDescriptor(cf)); admin.createTable(htd); - + for (int i = 0; cluster.getRegions(tableName).size() == 0 && i < 100; i++) { Thread.sleep(100); } assertEquals(1, cluster.getRegions(tableName).size()); - + HRegion region = cluster.getRegions(tableName).get(0); Store store = region.getStore(cf); int regionServerIndex = cluster.getServerWith(region.getRegionName()); HRegionServer regionServer = cluster.getRegionServer(regionServerIndex); - + Table t = new HTable(conf, tableName); // insert data insertData(tableName, admin, t); insertData(tableName, admin, t); - + int fileNum = store.getStorefiles().size(); // 0, Compaction Request store.triggerMajorCompaction(); CompactionContext cc = store.requestCompaction(); assertNotNull(cc); - // 1, A timeout split - // 1.1 close region + // 1, A timeout split + // 1.1 close region assertEquals(2, region.close(false).get(cf).size()); // 1.2 rollback and Region initialize again region.initialize(); - + // 2, Run Compaction cc assertFalse(region.compact(cc, store)); assertTrue(fileNum > store.getStorefiles().size()); @@ -264,7 +263,7 @@ public class TestSplitTransactionOnCluster { st.execute(regionServer, regionServer); assertEquals(2, cluster.getRegions(tableName).size()); } - + public static class FailingSplitRegionObserver extends BaseRegionObserver { static volatile CountDownLatch latch = new CountDownLatch(1); @Override @@ -1059,7 +1058,7 @@ public class TestSplitTransactionOnCluster { */ private int ensureTableRegionNotOnSameServerAsMeta(final Admin admin, final HRegionInfo hri) - throws HBaseIOException, MasterNotRunningException, + throws IOException, MasterNotRunningException, ZooKeeperConnectionException, InterruptedException { // Now make sure that the table region is not on same server as that hosting // hbase:meta We don't want hbase:meta replay polluting our test when we later crash diff --git hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java index caf0524..7d2441e 100644 --- hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java +++ hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java @@ -686,8 +686,6 @@ public class ThriftServerRunner implements Runnable { public void compact(ByteBuffer tableNameOrRegionName) throws IOError { try{ getHBaseAdmin().compact(getBytes(tableNameOrRegionName)); - } catch (InterruptedException e) { - throw new IOError(e.getMessage()); } catch (IOException e) { LOG.warn(e.getMessage(), e); throw new IOError(e.getMessage()); @@ -698,9 +696,6 @@ public class ThriftServerRunner implements Runnable { public void majorCompact(ByteBuffer tableNameOrRegionName) throws IOError { try{ getHBaseAdmin().majorCompact(getBytes(tableNameOrRegionName)); - } catch (InterruptedException e) { - LOG.warn(e.getMessage(), e); - throw new IOError(e.getMessage()); } catch (IOException e) { LOG.warn(e.getMessage(), e); throw new IOError(e.getMessage());