From 807142024f37a117d2ba8a76a274ce0dc64ba075 Mon Sep 17 00:00:00 2001 From: Srikanth Srungarapu Date: Sun, 26 Apr 2015 16:36:13 -0700 Subject: [PATCH] HBASE-13537 Change the admin interface for async operations to return Future. --- .../org/apache/hadoop/hbase/client/Admin.java | 74 +++++++++------- .../hadoop/hbase/client/HBaseAdmin.java | 84 +++---------------- 2 files changed, 58 insertions(+), 100 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java index 9453924d41d..a79f6668dd3 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java @@ -23,6 +23,7 @@ import java.io.Closeable; import java.io.IOException; import java.util.List; import java.util.Map; +import java.util.concurrent.Future; import java.util.regex.Pattern; import org.apache.hadoop.conf.Configuration; @@ -242,19 +243,21 @@ public interface Admin extends Abortable, Closeable { void createTable(final HTableDescriptor desc, byte[][] splitKeys) throws IOException; /** - * Creates a new table but does not block and wait for it to come online. Asynchronous operation. - * To check if the table exists, use {@link #isTableAvailable} -- it is not safe to create an - * HTable instance to this table before it is available. Note : Avoid passing empty split key. + * Creates a new table but does not block and wait for it to come online. + * You can use Future.get(long, TimeUnit) to wait on the operation to complete. + * It may throw ExecutionException if there was an error while executing the operation + * or TimeoutException in case the wait timeout was not long enough to allow the + * operation to complete. * * @param desc table descriptor for table - * @throws IllegalArgumentException Bad table name, if the split keys are repeated and if the - * split key has empty byte array. - * @throws MasterNotRunningException if master is not running - * @throws org.apache.hadoop.hbase.TableExistsException if table already exists (If concurrent - * threads, the table may have been created between test-for-existence and attempt-at-creation). - * @throws IOException + * @param splitKeys keys to check if the table has been created with all split keys + * @throws IllegalArgumentException Bad table name, if the split keys + * are repeated and if the split key has empty byte array. + * @throws IOException if a remote or network exception occurs + * @return the result of the async creation. You can use Future.get(long, TimeUnit) + * to wait on the operation to complete. */ - void createTableAsync(final HTableDescriptor desc, final byte[][] splitKeys) throws IOException; + Future createTableAsync(final HTableDescriptor desc, final byte[][] splitKeys) throws IOException; /** * Deletes a table. Synchronous operation. @@ -264,6 +267,20 @@ public interface Admin extends Abortable, Closeable { */ void deleteTable(final TableName tableName) throws IOException; + /** + * Deletes the table but does not block and wait for it be completely removed. + * You can use Future.get(long, TimeUnit) to wait on the operation to complete. + * It may throw ExecutionException if there was an error while executing the operation + * or TimeoutException in case the wait timeout was not long enough to allow the + * operation to complete. + * + * @param tableName name of table to delete + * @throws IOException if a remote or network exception occurs + * @return the result of the async delete. You can use Future.get(long, TimeUnit) + * to wait on the operation to complete. + */ + Future deleteTableAsync(TableName tableName) throws IOException; + /** * Deletes tables matching the passed in pattern and wait on completion. Warning: Use this method * carefully, there is no prompting and the effect is immediate. Consider using {@link @@ -316,16 +333,18 @@ public interface Admin extends Abortable, Closeable { void enableTable(final TableName tableName) throws IOException; /** - * Brings a table on-line (enables it). Method returns immediately though enable of table may - * take some time to complete, especially if the table is large (All regions are opened as part of - * enabling process). Check {@link #isTableEnabled(org.apache.hadoop.hbase.TableName)} to learn - * when table is fully online. If table is taking too long to online, check server logs. + * Enable the table but does not block and wait for it be completely enabled. + * You can use Future.get(long, TimeUnit) to wait on the operation to complete. + * It may throw ExecutionException if there was an error while executing the operation + * or TimeoutException in case the wait timeout was not long enough to allow the + * operation to complete. * - * @param tableName - * @throws IOException - * @since 0.90.0 + * @param tableName name of table to delete + * @throws IOException if a remote or network exception occurs + * @return the result of the async enable. You can use Future.get(long, TimeUnit) + * to wait on the operation to complete. */ - void enableTableAsync(final TableName tableName) throws IOException; + Future enableTableAsync(final TableName tableName) throws IOException; /** * Enable tables matching the passed in pattern and wait on completion. Warning: Use this method @@ -351,19 +370,18 @@ public interface Admin extends Abortable, Closeable { HTableDescriptor[] enableTables(Pattern pattern) throws IOException; /** - * Starts the disable of a table. If it is being served, the master will tell the servers to stop - * serving it. This method returns immediately. The disable of a table can take some time if the - * table is large (all regions are closed as part of table disable operation). Call {@link - * #isTableDisabled(org.apache.hadoop.hbase.TableName)} to check for when disable completes. If - * table is taking too long to online, check server logs. + * Disable the table but does not block and wait for it be completely disabled. + * You can use Future.get(long, TimeUnit) to wait on the operation to complete. + * It may throw ExecutionException if there was an error while executing the operation + * or TimeoutException in case the wait timeout was not long enough to allow the + * operation to complete. * - * @param tableName name of table + * @param tableName name of table to delete * @throws IOException if a remote or network exception occurs - * @see #isTableDisabled(org.apache.hadoop.hbase.TableName) - * @see #isTableEnabled(org.apache.hadoop.hbase.TableName) - * @since 0.90.0 + * @return the result of the async disable. You can use Future.get(long, TimeUnit) + * to wait on the operation to complete. */ - void disableTableAsync(final TableName tableName) throws IOException; + Future disableTableAsync(final TableName tableName) throws IOException; /** * Disable table and wait on completion. May timeout eventually. Use {@link diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index efbc7d2f3b3..11fcff5f437 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -21,7 +21,6 @@ package org.apache.hadoop.hbase.client; import java.io.Closeable; import java.io.IOException; import java.io.InterruptedIOException; -import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -53,13 +52,11 @@ import org.apache.hadoop.hbase.MasterNotRunningException; import org.apache.hadoop.hbase.MetaTableAccessor; import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.NotServingRegionException; -import org.apache.hadoop.hbase.RegionException; import org.apache.hadoop.hbase.RegionLocations; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableExistsException; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableNotDisabledException; -import org.apache.hadoop.hbase.TableNotEnabledException; import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.UnknownRegionException; import org.apache.hadoop.hbase.ZooKeeperConnectionException; @@ -557,7 +554,7 @@ public class HBaseAdmin implements Admin { @Override public void createTable(final HTableDescriptor desc, byte [][] splitKeys) throws IOException { - Future future = createTableAsyncV2(desc, splitKeys); + Future future = createTableAsync(desc, splitKeys); try { // TODO: how long should we wait? spin forever? future.get(syncWaitTimeout, TimeUnit.MILLISECONDS); @@ -575,28 +572,6 @@ public class HBaseAdmin implements Admin { } } - /** - * Creates a new table but does not block and wait for it to come online. - * Asynchronous operation. To check if the table exists, use - * {@link #isTableAvailable} -- it is not safe to create an HTable - * instance to this table before it is available. - * Note : Avoid passing empty split key. - * @param desc table descriptor for table - * - * @throws IllegalArgumentException Bad table name, if the split keys - * are repeated and if the split key has empty byte array. - * @throws MasterNotRunningException if master is not running - * @throws org.apache.hadoop.hbase.TableExistsException if table already exists (If concurrent - * threads, the table may have been created between test-for-existence - * and attempt-at-creation). - * @throws IOException - */ - @Override - public void createTableAsync(final HTableDescriptor desc, final byte [][] splitKeys) - throws IOException { - createTableAsyncV2(desc, splitKeys); - } - /** * Creates a new table but does not block and wait for it to come online. * You can use Future.get(long, TimeUnit) to wait on the operation to complete. @@ -612,8 +587,8 @@ public class HBaseAdmin implements Admin { * @return the result of the async creation. You can use Future.get(long, TimeUnit) * to wait on the operation to complete. */ - // TODO: This should be called Async but it will break binary compatibility - private Future createTableAsyncV2(final HTableDescriptor desc, final byte[][] splitKeys) + @Override + public Future createTableAsync(final HTableDescriptor desc, final byte[][] splitKeys) throws IOException { if (desc.getTableName() == null) { throw new IllegalArgumentException("TableName cannot be null"); @@ -776,7 +751,7 @@ public class HBaseAdmin implements Admin { */ @Override public void deleteTable(final TableName tableName) throws IOException { - Future future = deleteTableAsyncV2(tableName); + Future future = deleteTableAsync(tableName); try { future.get(syncWaitTimeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -799,14 +774,13 @@ public class HBaseAdmin implements Admin { * or TimeoutException in case the wait timeout was not long enough to allow the * operation to complete. * - * @param desc table descriptor for table * @param tableName name of table to delete * @throws IOException if a remote or network exception occurs * @return the result of the async delete. You can use Future.get(long, TimeUnit) * to wait on the operation to complete. */ - // TODO: This should be called Async but it will break binary compatibility - private Future deleteTableAsyncV2(final TableName tableName) throws IOException { + @Override + public Future deleteTableAsync(final TableName tableName) throws IOException { DeleteTableResponse response = executeCallable( new MasterCallable(getConnection()) { @Override @@ -946,7 +920,7 @@ public class HBaseAdmin implements Admin { @Override public void enableTable(final TableName tableName) throws IOException { - Future future = enableTableAsyncV2(tableName); + Future future = enableTableAsync(tableName); try { future.get(syncWaitTimeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -1013,22 +987,6 @@ public class HBaseAdmin implements Admin { } } - /** - * Brings a table on-line (enables it). Method returns immediately though - * enable of table may take some time to complete, especially if the table - * is large (All regions are opened as part of enabling process). Check - * {@link #isTableEnabled(byte[])} to learn when table is fully online. If - * table is taking too long to online, check server logs. - * @param tableName - * @throws IOException - * @since 0.90.0 - */ - @Override - public void enableTableAsync(final TableName tableName) - throws IOException { - enableTableAsyncV2(tableName); - } - public void enableTableAsync(final byte[] tableName) throws IOException { enableTable(TableName.valueOf(tableName)); @@ -1051,8 +1009,8 @@ public class HBaseAdmin implements Admin { * @return the result of the async enable. You can use Future.get(long, TimeUnit) * to wait on the operation to complete. */ - // TODO: This should be called Async but it will break binary compatibility - private Future enableTableAsyncV2(final TableName tableName) throws IOException { + @Override + public Future enableTableAsync(final TableName tableName) throws IOException { TableName.isLegalFullyQualifiedTableName(tableName.getName()); EnableTableResponse response = executeCallable( new MasterCallable(getConnection()) { @@ -1160,24 +1118,6 @@ public class HBaseAdmin implements Admin { return failed.toArray(new HTableDescriptor[failed.size()]); } - /** - * Starts the disable of a table. If it is being served, the master - * will tell the servers to stop serving it. This method returns immediately. - * The disable of a table can take some time if the table is large (all - * regions are closed as part of table disable operation). - * Call {@link #isTableDisabled(byte[])} to check for when disable completes. - * If table is taking too long to online, check server logs. - * @param tableName name of table - * @throws IOException if a remote or network exception occurs - * @see #isTableDisabled(byte[]) - * @see #isTableEnabled(byte[]) - * @since 0.90.0 - */ - @Override - public void disableTableAsync(final TableName tableName) throws IOException { - disableTableAsyncV2(tableName); - } - public void disableTableAsync(final byte[] tableName) throws IOException { disableTableAsync(TableName.valueOf(tableName)); } @@ -1200,7 +1140,7 @@ public class HBaseAdmin implements Admin { @Override public void disableTable(final TableName tableName) throws IOException { - Future future = disableTableAsyncV2(tableName); + Future future = disableTableAsync(tableName); try { future.get(syncWaitTimeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -1238,8 +1178,8 @@ public class HBaseAdmin implements Admin { * @return the result of the async disable. You can use Future.get(long, TimeUnit) * to wait on the operation to complete. */ - // TODO: This should be called Async but it will break binary compatibility - private Future disableTableAsyncV2(final TableName tableName) throws IOException { + @Override + public Future disableTableAsync(final TableName tableName) throws IOException { TableName.isLegalFullyQualifiedTableName(tableName.getName()); DisableTableResponse response = executeCallable( new MasterCallable(getConnection()) {