diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/AsyncMetaTableAccessor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/AsyncMetaTableAccessor.java index 6988047ffac..18fca6b0a05 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/AsyncMetaTableAccessor.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/AsyncMetaTableAccessor.java @@ -22,6 +22,7 @@ import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.NavigableMap; @@ -30,6 +31,7 @@ import java.util.SortedMap; import java.util.concurrent.CompletableFuture; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -37,6 +39,7 @@ import org.apache.hadoop.hbase.MetaTableAccessor.CollectingVisitor; import org.apache.hadoop.hbase.MetaTableAccessor.QueryType; import org.apache.hadoop.hbase.MetaTableAccessor.Visitor; import org.apache.hadoop.hbase.classification.InterfaceAudience; +import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.Consistency; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.RawAsyncTable; @@ -45,6 +48,7 @@ import org.apache.hadoop.hbase.client.RegionReplicaUtil; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.TableState; +import org.apache.hadoop.hbase.client.Scan.ReadType; import org.apache.hadoop.hbase.exceptions.DeserializationException; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; @@ -98,34 +102,72 @@ public class AsyncMetaTableAccessor { return future; } - public static CompletableFuture> getRegion(RawAsyncTable metaTable, - byte[] regionName) { - CompletableFuture> future = new CompletableFuture<>(); - byte[] row = regionName; - HRegionInfo parsedInfo = null; + /** + * Returns the HRegionLocation from meta for the given region + * @param metaTable + * @param regionName region we're looking for + * @return HRegionLocation for the given region + */ + public static CompletableFuture> getRegionLocation( + RawAsyncTable metaTable, byte[] regionName) { + CompletableFuture> future = new CompletableFuture<>(); try { - parsedInfo = MetaTableAccessor.parseRegionInfoFromRegionName(regionName); - row = MetaTableAccessor.getMetaKeyForRegion(parsedInfo); - } catch (Exception parseEx) { - // Ignore if regionName is a encoded region name. + HRegionInfo parsedRegionInfo = MetaTableAccessor.parseRegionInfoFromRegionName(regionName); + metaTable.get( + new Get(MetaTableAccessor.getMetaKeyForRegion(parsedRegionInfo)) + .addFamily(HConstants.CATALOG_FAMILY)).whenComplete( + (r, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } + future.complete(getRegionLocations(r).map( + locations -> locations.getRegionLocation(parsedRegionInfo.getReplicaId()))); + }); + } catch (IOException parseEx) { + LOG.warn("Failed to parse the passed region name: " + Bytes.toStringBinary(regionName)); + future.completeExceptionally(parseEx); } + return future; + } - final HRegionInfo finalHRI = parsedInfo; - metaTable.get(new Get(row).addFamily(HConstants.CATALOG_FAMILY)).whenComplete((r, err) -> { - if (err != null) { - future.completeExceptionally(err); - return; - } - RegionLocations locations = MetaTableAccessor.getRegionLocations(r); - HRegionLocation hrl = locations == null ? null - : locations.getRegionLocation(finalHRI == null ? 0 : finalHRI.getReplicaId()); - if (hrl == null) { - future.complete(null); - } else { - future.complete(new Pair<>(hrl.getRegionInfo(), hrl.getServerName())); - } - }); - + /** + * Returns the HRegionLocation from meta for the given encoded region name + * @param metaTable + * @param encodedRegionName region we're looking for + * @return HRegionLocation for the given region + */ + public static CompletableFuture> getRegionLocationWithEncodedName( + RawAsyncTable metaTable, byte[] encodedRegionName) { + CompletableFuture> future = new CompletableFuture<>(); + metaTable.scanAll(new Scan().setReadType(ReadType.PREAD).addFamily(HConstants.CATALOG_FAMILY)) + .whenComplete( + (results, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } + String encodedRegionNameStr = Bytes.toString(encodedRegionName); + results + .stream() + .filter(result -> !result.isEmpty()) + .filter(result -> MetaTableAccessor.getHRegionInfo(result) != null) + .forEach( + result -> { + getRegionLocations(result).ifPresent( + locations -> { + for (HRegionLocation location : locations.getRegionLocations()) { + if (location != null + && encodedRegionNameStr.equals(location.getRegionInfo() + .getEncodedName())) { + future.complete(Optional.of(location)); + return; + } + } + }); + }); + future.complete(Optional.empty()); + }); return future; } @@ -143,15 +185,29 @@ public class AsyncMetaTableAccessor { } /** - * Used to get table regions' info and server. + * Used to get all region locations for the specific table. * @param metaTable * @param tableName table we're looking for, can be null for getting all regions - * @return the list of regioninfos and server. The return value will be wrapped by a + * @return the list of region locations. The return value will be wrapped by a * {@link CompletableFuture}. */ - public static CompletableFuture>> getTableRegionsAndLocations( + public static CompletableFuture> getTableHRegionLocations( RawAsyncTable metaTable, final Optional tableName) { - return getTableRegionsAndLocations(metaTable, tableName, true); + CompletableFuture> future = new CompletableFuture<>(); + getTableRegionsAndLocations(metaTable, tableName, true).whenComplete( + (locations, err) -> { + if (err != null) { + future.completeExceptionally(err); + } else if (locations == null || locations.isEmpty()) { + future.complete(Collections.emptyList()); + } else { + List regionLocations = locations.stream() + .map(loc -> new HRegionLocation(loc.getFirst(), loc.getSecond())) + .collect(Collectors.toList()); + future.complete(regionLocations); + } + }); + return future; } /** @@ -162,7 +218,7 @@ public class AsyncMetaTableAccessor { * @return the list of regioninfos and server. The return value will be wrapped by a * {@link CompletableFuture}. */ - public static CompletableFuture>> getTableRegionsAndLocations( + private static CompletableFuture>> getTableRegionsAndLocations( RawAsyncTable metaTable, final Optional tableName, final boolean excludeOfflinedSplitParents) { CompletableFuture>> future = new CompletableFuture<>(); diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java index 9eb5111dcb1..3870fd19945 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java @@ -364,13 +364,12 @@ public class MetaTableAccessor { * is stored in the name, so the returned object should only be used for the fields * in the regionName. */ - protected static HRegionInfo parseRegionInfoFromRegionName(byte[] regionName) - throws IOException { + public static HRegionInfo parseRegionInfoFromRegionName(byte[] regionName) throws IOException { byte[][] fields = HRegionInfo.parseRegionName(regionName); - long regionId = Long.parseLong(Bytes.toString(fields[2])); + long regionId = Long.parseLong(Bytes.toString(fields[2])); int replicaId = fields.length > 3 ? Integer.parseInt(Bytes.toString(fields[3]), 16) : 0; - return new HRegionInfo( - TableName.valueOf(fields[0]), fields[1], fields[1], false, regionId, replicaId); + return new HRegionInfo(TableName.valueOf(fields[0]), fields[1], fields[1], false, regionId, + replicaId); } /** diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java index 1a3cae21e95..3b022f4750b 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.client; import java.util.List; import java.util.Collection; import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.regex.Pattern; @@ -42,7 +43,7 @@ import org.apache.hadoop.hbase.util.Pair; * This feature is still under development, so marked as IA.Private. Will change to public when * done. Use it with caution. */ -@InterfaceAudience.Private +@InterfaceAudience.Public public interface AsyncAdmin { /** @@ -55,63 +56,50 @@ public interface AsyncAdmin { * @return True if table exists already. The return value will be wrapped by a * {@link CompletableFuture}. */ - CompletableFuture tableExists(final TableName tableName); + CompletableFuture tableExists(TableName tableName); /** * List all the userspace tables. - * @return - returns an array of TableDescriptors wrapped by a {@link CompletableFuture}. - * @see #listTables(Pattern, boolean) + * @return - returns a list of TableDescriptors wrapped by a {@link CompletableFuture}. + * @see #listTables(Optional, boolean) */ - CompletableFuture listTables(); - - /** - * List all the tables matching the given pattern. - * @param regex The regular expression to match against - * @param includeSysTables False to match only against userspace tables - * @return - returns an array of TableDescriptors wrapped by a {@link CompletableFuture}. - * @see #listTables(Pattern, boolean) - */ - CompletableFuture listTables(String regex, boolean includeSysTables); + default CompletableFuture> listTables() { + return listTables(Optional.empty(), false); + } /** * List all the tables matching the given pattern. * @param pattern The compiled regular expression to match against * @param includeSysTables False to match only against userspace tables - * @return - returns an array of TableDescriptors wrapped by a {@link CompletableFuture}. + * @return - returns a list of TableDescriptors wrapped by a {@link CompletableFuture}. */ - CompletableFuture listTables(Pattern pattern, boolean includeSysTables); + CompletableFuture> listTables(Optional pattern, + boolean includeSysTables); /** * List all of the names of userspace tables. - * @return TableName[] an array of table names wrapped by a {@link CompletableFuture}. - * @see #listTableNames(Pattern, boolean) + * @return a list of table names wrapped by a {@link CompletableFuture}. + * @see #listTableNames(Optional, boolean) */ - CompletableFuture listTableNames(); - - /** - * List all of the names of userspace tables. - * @param regex The regular expression to match against - * @param includeSysTables False to match only against userspace tables - * @return TableName[] an array of table names wrapped by a {@link CompletableFuture}. - * @see #listTableNames(Pattern, boolean) - */ - CompletableFuture listTableNames(final String regex, final boolean includeSysTables); + default CompletableFuture> listTableNames() { + return listTableNames(Optional.empty(), false); + } /** * List all of the names of userspace tables. * @param pattern The regular expression to match against * @param includeSysTables False to match only against userspace tables - * @return TableName[] an array of table names wrapped by a {@link CompletableFuture}. + * @return a list of table names wrapped by a {@link CompletableFuture}. */ - CompletableFuture listTableNames(final Pattern pattern, - final boolean includeSysTables); + CompletableFuture> listTableNames(Optional pattern, + boolean includeSysTables); /** * Method for getting the tableDescriptor * @param tableName as a {@link TableName} * @return the read-only tableDescriptor wrapped by a {@link CompletableFuture}. */ - CompletableFuture getTableDescriptor(final TableName tableName); + CompletableFuture getTableDescriptor(TableName tableName); /** * Creates a new table. @@ -140,94 +128,63 @@ public interface AsyncAdmin { * @param desc table descriptor for table * @param splitKeys array of split keys for the initial regions of the table */ - CompletableFuture createTable(final TableDescriptor desc, byte[][] splitKeys); + CompletableFuture createTable(TableDescriptor desc, byte[][] splitKeys); /** * Deletes a table. * @param tableName name of table to delete */ - CompletableFuture deleteTable(final TableName tableName); - - /** - * 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 #listTables(String, boolean)} and - * {@link #deleteTable(org.apache.hadoop.hbase.TableName)} - * @param regex The regular expression to match table names against - * @return Table descriptors for tables that couldn't be deleted. The return value will be wrapped - * by a {@link CompletableFuture}. The return HTDs are read-only. - */ - CompletableFuture deleteTables(String regex); + CompletableFuture deleteTable(TableName tableName); /** * Delete 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 #listTables(Pattern, boolean) } and + * {@link #listTableNames(Optional, boolean) } and * {@link #deleteTable(org.apache.hadoop.hbase.TableName)} * @param pattern The pattern to match table names against * @return Table descriptors for tables that couldn't be deleted. The return value will be wrapped * by a {@link CompletableFuture}. The return HTDs are read-only. */ - CompletableFuture deleteTables(Pattern pattern); + CompletableFuture> deleteTables(Pattern pattern); /** * Truncate a table. * @param tableName name of table to truncate * @param preserveSplits True if the splits should be preserved */ - CompletableFuture truncateTable(final TableName tableName, final boolean preserveSplits); + CompletableFuture truncateTable(TableName tableName, boolean preserveSplits); /** * Enable a table. The table has to be in disabled state for it to be enabled. * @param tableName name of the table */ - CompletableFuture enableTable(final TableName tableName); + CompletableFuture enableTable(TableName tableName); /** * Enable tables matching the passed in pattern. Warning: Use this method carefully, there is no - * prompting and the effect is immediate. Consider using {@link #listTables(Pattern, boolean)} and - * {@link #enableTable(TableName)} - * @param regex The regular expression to match table names against - * @return Table descriptors for tables that couldn't be enabled. The return value will be wrapped - * by a {@link CompletableFuture}. The return HTDs are read-only. - */ - CompletableFuture enableTables(String regex); - - /** - * Enable tables matching the passed in pattern. Warning: Use this method carefully, there is no - * prompting and the effect is immediate. Consider using {@link #listTables(Pattern, boolean)} and + * prompting and the effect is immediate. Consider using {@link #listTables(Optional, boolean)} and * {@link #enableTable(TableName)} * @param pattern The pattern to match table names against * @return Table descriptors for tables that couldn't be enabled. The return value will be wrapped * by a {@link CompletableFuture}. The return HTDs are read-only. */ - CompletableFuture enableTables(Pattern pattern); + CompletableFuture> enableTables(Pattern pattern); /** * Disable a table. The table has to be in enabled state for it to be disabled. * @param tableName */ - CompletableFuture disableTable(final TableName tableName); + CompletableFuture disableTable(TableName tableName); /** * Disable tables matching the passed in pattern. Warning: Use this method carefully, there is no - * prompting and the effect is immediate. Consider using {@link #listTables(Pattern, boolean)} and - * {@link #disableTable(TableName)} - * @param regex The regular expression to match table names against - * @return Table descriptors for tables that couldn't be disabled. The return value will be wrapped by a - * {@link CompletableFuture}. The return HTDs are read-only. - */ - CompletableFuture disableTables(String regex); - - /** - * Disable tables matching the passed in pattern. Warning: Use this method carefully, there is no - * prompting and the effect is immediate. Consider using {@link #listTables(Pattern, boolean)} and + * prompting and the effect is immediate. Consider using {@link #listTables(Optional, boolean)} and * {@link #disableTable(TableName)} * @param pattern The pattern to match table names against * @return Table descriptors for tables that couldn't be disabled. The return value will be wrapped by a * {@link CompletableFuture}. The return HTDs are read-only. */ - CompletableFuture disableTables(Pattern pattern); + CompletableFuture> disableTables(Pattern pattern); /** * @param tableName name of table to check @@ -261,61 +218,61 @@ public interface AsyncAdmin { * yet to be updated Pair.getSecond() is the total number of regions of the table. The * return value will be wrapped by a {@link CompletableFuture}. */ - CompletableFuture> getAlterStatus(final TableName tableName); + CompletableFuture> getAlterStatus(TableName tableName); /** * Add a column family to an existing table. * @param tableName name of the table to add column family to * @param columnFamily column family descriptor of column family to be added */ - CompletableFuture addColumnFamily(final TableName tableName, - final ColumnFamilyDescriptor columnFamily); + CompletableFuture addColumnFamily(TableName tableName, + ColumnFamilyDescriptor columnFamily); /** * Delete a column family from a table. * @param tableName name of table * @param columnFamily name of column family to be deleted */ - CompletableFuture deleteColumnFamily(final TableName tableName, final byte[] columnFamily); + CompletableFuture deleteColumnFamily(TableName tableName, byte[] columnFamily); /** * Modify an existing column family on a table. * @param tableName name of table * @param columnFamily new column family descriptor to use */ - CompletableFuture modifyColumnFamily(final TableName tableName, - final ColumnFamilyDescriptor columnFamily); + CompletableFuture modifyColumnFamily(TableName tableName, + ColumnFamilyDescriptor columnFamily); /** * Create a new namespace. * @param descriptor descriptor which describes the new namespace */ - CompletableFuture createNamespace(final NamespaceDescriptor descriptor); + CompletableFuture createNamespace(NamespaceDescriptor descriptor); /** * Modify an existing namespace. * @param descriptor descriptor which describes the new namespace */ - CompletableFuture modifyNamespace(final NamespaceDescriptor descriptor); + CompletableFuture modifyNamespace(NamespaceDescriptor descriptor); /** * Delete an existing namespace. Only empty namespaces (no tables) can be removed. * @param name namespace name */ - CompletableFuture deleteNamespace(final String name); + CompletableFuture deleteNamespace(String name); /** * Get a namespace descriptor by name * @param name name of namespace descriptor * @return A descriptor wrapped by a {@link CompletableFuture}. */ - CompletableFuture getNamespaceDescriptor(final String name); + CompletableFuture getNamespaceDescriptor(String name); /** * List available namespace descriptors * @return List of descriptors wrapped by a {@link CompletableFuture}. */ - CompletableFuture listNamespaceDescriptors(); + CompletableFuture> listNamespaceDescriptors(); /** * @param tableName name of table to check @@ -329,7 +286,7 @@ public interface AsyncAdmin { * @param on * @return Previous balancer value wrapped by a {@link CompletableFuture}. */ - CompletableFuture setBalancerRunning(final boolean on); + CompletableFuture setBalancerOn(boolean on); /** * Invoke the balancer. Will run the balancer and if regions to move, it will go ahead and do the @@ -337,72 +294,38 @@ public interface AsyncAdmin { * @return True if balancer ran, false otherwise. The return value will be wrapped by a * {@link CompletableFuture}. */ - CompletableFuture balancer(); + default CompletableFuture balance() { + return balance(false); + } /** * Invoke the balancer. Will run the balancer and if regions to move, it will go ahead and do the * reassignments. If there is region in transition, force parameter of true would still run * balancer. Can *not* run for other reasons. Check logs. - * @param force whether we should force balance even if there is region in transition. + * @param forcible whether we should force balance even if there is region in transition. * @return True if balancer ran, false otherwise. The return value will be wrapped by a * {@link CompletableFuture}. */ - CompletableFuture balancer(boolean force); + CompletableFuture balance(boolean forcible); /** * Query the current state of the balancer. - * @return true if the balancer is enabled, false otherwise. - * The return value will be wrapped by a {@link CompletableFuture}. + * @return true if the balance switch is on, false otherwise The return value will be wrapped by a + * {@link CompletableFuture}. */ - CompletableFuture isBalancerEnabled(); + CompletableFuture isBalancerOn(); /** - * Close a region. For expert-admins. Runs close on the regionserver. The master will not be + * Close a region. For expert-admins Runs close on the regionserver. The master will not be * informed of the close. - * - * @param regionname region name to close - * @param serverName If supplied, we'll use this location rather than the one currently in - * hbase:meta - */ - CompletableFuture closeRegion(String regionname, String serverName); - - /** - * Close a region. For expert-admins Runs close on the regionserver. The master will not be - * informed of the close. - * - * @param regionname region name to close - * @param serverName The servername of the regionserver. If passed null we will use servername - * found in the hbase:meta table. A server name is made of host, port and startcode. Here is an - * example: host187.example.com,60020,1289493121758 - */ - CompletableFuture closeRegion(byte[] regionname, String serverName); - - /** - * For expert-admins. Runs close on the regionserver. Closes a region based on the encoded region - * name. The region server name is mandatory. If the servername is provided then based on the - * online regions in the specified regionserver the specified region will be closed. The master - * will not be informed of the close. Note that the regionname is the encoded regionname. - * - * @param encodedRegionName The encoded region name; i.e. the hash that makes up the region name - * suffix: e.g. if regionname is - * TestTable,0094429456,1289497600452.527db22f95c8a9e0116f0cc13c680396., - * then the encoded region name is: 527db22f95c8a9e0116f0cc13c680396. - * @param serverName The servername of the regionserver. A server name is made of host, port and - * startcode. This is mandatory. Here is an example: - * host187.example.com,60020,1289493121758 + * @param regionName region name to close + * @param serverName The servername of the regionserver. If not present, we will use servername + * found in the hbase:meta table. A server name is made of host, port and startcode. Here + * is an example: host187.example.com,60020,1289493121758 * @return true if the region was closed, false if not. The return value will be wrapped by a - * {@link CompletableFuture}. + * {@link CompletableFuture}. */ - CompletableFuture closeRegionWithEncodedRegionName(String encodedRegionName, String serverName); - - /** - * Close a region. For expert-admins Runs close on the regionserver. The master will not be - * informed of the close. - * - * @param sn - * @param hri - */ - CompletableFuture closeRegion(ServerName sn, HRegionInfo hri); + CompletableFuture closeRegion(byte[] regionName, Optional serverName); /** * Get all the online regions on a region server. @@ -422,60 +345,80 @@ public interface AsyncAdmin { CompletableFuture flushRegion(byte[] regionName); /** - * Compact a table. Asynchronous operation even if CompletableFuture.get(). + * Compact a table. When the returned CompletableFuture is done, it only means the compact request + * was sent to HBase and may need some time to finish the compact operation. * @param tableName table to compact */ - CompletableFuture compact(TableName tableName); + default CompletableFuture compact(TableName tableName) { + return compact(tableName, Optional.empty()); + } /** - * Compact a column family within a table. Asynchronous operation even if CompletableFuture.get(). + * Compact a column family within a table. When the returned CompletableFuture is done, it only + * means the compact request was sent to HBase and may need some time to finish the compact + * operation. * @param tableName table to compact - * @param columnFamily column family within a table + * @param columnFamily column family within a table. If not present, compact the table's all + * column families. */ - CompletableFuture compact(TableName tableName, byte[] columnFamily); + CompletableFuture compact(TableName tableName, Optional columnFamily); /** - * Compact an individual region. Asynchronous operation even if CompletableFuture.get(). + * Compact an individual region. When the returned CompletableFuture is done, it only means the + * compact request was sent to HBase and may need some time to finish the compact operation. * @param regionName region to compact */ - CompletableFuture compactRegion(byte[] regionName); + default CompletableFuture compactRegion(byte[] regionName) { + return compactRegion(regionName, Optional.empty()); + } /** - * Compact a column family within a region. Asynchronous operation even if - * CompletableFuture.get(). + * Compact a column family within a region. When the returned CompletableFuture is done, it only + * means the compact request was sent to HBase and may need some time to finish the compact + * operation. * @param regionName region to compact - * @param columnFamily column family within a region + * @param columnFamily column family within a region. If not present, compact the region's all + * column families. */ - CompletableFuture compactRegion(byte[] regionName, byte[] columnFamily); + CompletableFuture compactRegion(byte[] regionName, Optional columnFamily); /** - * Major compact a table. Asynchronous operation even if CompletableFuture.get(). + * Major compact a table. When the returned CompletableFuture is done, it only means the compact + * request was sent to HBase and may need some time to finish the compact operation. * @param tableName table to major compact */ - CompletableFuture majorCompact(TableName tableName); + default CompletableFuture majorCompact(TableName tableName) { + return majorCompact(tableName, Optional.empty()); + } /** - * Major compact a column family within a table. Asynchronous operation even if - * CompletableFuture.get(). + * Major compact a column family within a table. When the returned CompletableFuture is done, it + * only means the compact request was sent to HBase and may need some time to finish the compact + * operation. * @param tableName table to major compact - * @param columnFamily column family within a table + * @param columnFamily column family within a table. If not present, major compact the table's all + * column families. */ - CompletableFuture majorCompact(TableName tableName, byte[] columnFamily); + CompletableFuture majorCompact(TableName tableName, Optional columnFamily); /** - * Major compact a table or an individual region. Asynchronous operation even if - * CompletableFuture.get(). + * Major compact a region. When the returned CompletableFuture is done, it only means the compact + * request was sent to HBase and may need some time to finish the compact operation. * @param regionName region to major compact */ - CompletableFuture majorCompactRegion(byte[] regionName); + default CompletableFuture majorCompactRegion(byte[] regionName) { + return majorCompactRegion(regionName, Optional.empty()); + } /** - * Major compact a column family within region. Asynchronous operation even if - * CompletableFuture.get(). - * @param regionName egion to major compact - * @param columnFamily column family within a region + * Major compact a column family within region. When the returned CompletableFuture is done, it + * only means the compact request was sent to HBase and may need some time to finish the compact + * operation. + * @param regionName region to major compact + * @param columnFamily column family within a region. If not present, major compact the region's + * all column families. */ - CompletableFuture majorCompactRegion(byte[] regionName, byte[] columnFamily); + CompletableFuture majorCompactRegion(byte[] regionName, Optional columnFamily); /** * Compact all regions on the region server. @@ -496,51 +439,54 @@ public interface AsyncAdmin { * @param forcible true if do a compulsory merge, otherwise we will only merge two adjacent * regions */ - CompletableFuture mergeRegions(final byte[] nameOfRegionA, final byte[] nameOfRegionB, - final boolean forcible); + CompletableFuture mergeRegions(byte[] nameOfRegionA, byte[] nameOfRegionB, + boolean forcible); /** * Split a table. The method will execute split action for each region in table. * @param tableName table to split */ - CompletableFuture split(final TableName tableName); + CompletableFuture split(TableName tableName); /** * Split an individual region. * @param regionName region to split */ - CompletableFuture splitRegion(final byte[] regionName); + default CompletableFuture splitRegion(byte[] regionName) { + return splitRegion(regionName, Optional.empty()); + } /** * Split a table. * @param tableName table to split * @param splitPoint the explicit position to split on */ - CompletableFuture split(final TableName tableName, final byte[] splitPoint); + CompletableFuture split(TableName tableName, byte[] splitPoint); /** * Split an individual region. * @param regionName region to split - * @param splitPoint the explicit position to split on + * @param splitPoint the explicit position to split on. If not present, it will decide by region + * server. */ - CompletableFuture splitRegion(final byte[] regionName, final byte[] splitPoint); + CompletableFuture splitRegion(byte[] regionName, Optional splitPoint); /** * @param regionName Encoded or full name of region to assign. */ - CompletableFuture assign(final byte[] regionName); + CompletableFuture assign(byte[] regionName); /** * Unassign a region from current hosting regionserver. Region will then be assigned to a * regionserver chosen at random. Region could be reassigned back to the same server. Use - * {@link #move(byte[], byte[])} if you want to control the region movement. + * {@link #move(byte[], Optional)} if you want to control the region movement. * @param regionName Encoded or full name of 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 + * @param forcible 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). */ - CompletableFuture unassign(final byte[] regionName, final boolean force); + CompletableFuture unassign(byte[] regionName, boolean forcible); /** * Offline specified region from master's in-memory state. It will not attempt to reassign the @@ -550,22 +496,22 @@ public interface AsyncAdmin { * experts or hbck. * @param regionName Encoded or full name of region to offline */ - CompletableFuture offline(final byte[] regionName); + CompletableFuture offline(byte[] regionName); /** * Move the region r to dest. * @param regionName Encoded or full name of region to move. - * @param destServerName The servername of the destination regionserver. If passed the empty byte - * array we'll assign to a random server. A server name is made of host, port and - * startcode. Here is an example: host187.example.com,60020,1289493121758 + * @param destServerName The servername of the destination regionserver. If not present, we'll + * assign to a random server. A server name is made of host, port and startcode. Here is + * an example: host187.example.com,60020,1289493121758 */ - CompletableFuture move(final byte[] regionName, final byte[] destServerName); + CompletableFuture move(byte[] regionName, Optional destServerName); /** * Apply the new quota settings. * @param quota the quota settings */ - CompletableFuture setQuota(final QuotaSettings quota); + CompletableFuture setQuota(QuotaSettings quota); /** * List the quotas based on the filter. @@ -579,41 +525,41 @@ public interface AsyncAdmin { * @param peerId a short name that identifies the peer * @param peerConfig configuration for the replication slave cluster */ - CompletableFuture addReplicationPeer(final String peerId, - final ReplicationPeerConfig peerConfig); + CompletableFuture addReplicationPeer(String peerId, + ReplicationPeerConfig peerConfig); /** * Remove a peer and stop the replication * @param peerId a short name that identifies the peer */ - CompletableFuture removeReplicationPeer(final String peerId); + CompletableFuture removeReplicationPeer(String peerId); /** * Restart the replication stream to the specified peer * @param peerId a short name that identifies the peer */ - CompletableFuture enableReplicationPeer(final String peerId); + CompletableFuture enableReplicationPeer(String peerId); /** * Stop the replication stream to the specified peer * @param peerId a short name that identifies the peer */ - CompletableFuture disableReplicationPeer(final String peerId); + CompletableFuture disableReplicationPeer(String peerId); /** * Returns the configured ReplicationPeerConfig for the specified peer * @param peerId a short name that identifies the peer * @return ReplicationPeerConfig for the peer wrapped by a {@link CompletableFuture}. */ - CompletableFuture getReplicationPeerConfig(final String peerId); + CompletableFuture getReplicationPeerConfig(String peerId); /** * Update the peerConfig for the specified peer * @param peerId a short name that identifies the peer * @param peerConfig new config for the peer */ - CompletableFuture updateReplicationPeerConfig(final String peerId, - final ReplicationPeerConfig peerConfig); + CompletableFuture updateReplicationPeerConfig(String peerId, + ReplicationPeerConfig peerConfig); /** * Append the replicable table-cf config of the specified peer @@ -636,15 +582,9 @@ public interface AsyncAdmin { * @return a list of replication peers description. The return value will be wrapped by a * {@link CompletableFuture}. */ - CompletableFuture> listReplicationPeers(); - - /** - * Return a list of replication peers. - * @param regex The regular expression to match peer id - * @return a list of replication peers description. The return value will be wrapped by a - * {@link CompletableFuture}. - */ - CompletableFuture> listReplicationPeers(String regex); + default CompletableFuture> listReplicationPeers() { + return listReplicationPeers(Optional.empty()); + } /** * Return a list of replication peers. @@ -652,7 +592,8 @@ public interface AsyncAdmin { * @return a list of replication peers description. The return value will be wrapped by a * {@link CompletableFuture}. */ - CompletableFuture> listReplicationPeers(Pattern pattern); + CompletableFuture> + listReplicationPeers(Optional pattern); /** * Find all table and column families that are replicated from this cluster @@ -686,7 +627,7 @@ public interface AsyncAdmin { * @param tableName name of the table to snapshot * @param type type of snapshot to take */ - CompletableFuture snapshot(final String snapshotName, final TableName tableName, + CompletableFuture snapshot(String snapshotName, TableName tableName, SnapshotType type); /** @@ -718,7 +659,7 @@ public interface AsyncAdmin { * @return true if the snapshot is completed, false if the snapshot is still * running */ - CompletableFuture isSnapshotFinished(final SnapshotDescription snapshot); + CompletableFuture isSnapshotFinished(SnapshotDescription snapshot); /** * Restore the specified snapshot on the original table. (The table must be disabled) If the @@ -747,7 +688,7 @@ public interface AsyncAdmin { * @param snapshotName name of the snapshot to be cloned * @param tableName name of the table where the snapshot will be restored */ - CompletableFuture cloneSnapshot(final String snapshotName, final TableName tableName); + CompletableFuture cloneSnapshot(String snapshotName, TableName tableName); /** * List completed snapshots. @@ -756,13 +697,6 @@ public interface AsyncAdmin { */ CompletableFuture> listSnapshots(); - /** - * List all the completed snapshots matching the given regular expression. - * @param regex The regular expression to match against - * @return - returns a List of SnapshotDescription wrapped by a {@link CompletableFuture} - */ - CompletableFuture> listSnapshots(String regex); - /** * List all the completed snapshots matching the given pattern. * @param pattern The compiled regular expression to match against @@ -770,17 +704,6 @@ public interface AsyncAdmin { */ CompletableFuture> listSnapshots(Pattern pattern); - /** - * List all the completed snapshots matching the given table name regular expression and snapshot - * name regular expression. - * @param tableNameRegex The table name regular expression to match against - * @param snapshotNameRegex The snapshot name regular expression to match against - * @return - returns a List of completed SnapshotDescription wrapped by a - * {@link CompletableFuture} - */ - CompletableFuture> listTableSnapshots(String tableNameRegex, - String snapshotNameRegex); - /** * List all the completed snapshots matching the given table name regular expression and snapshot * name regular expression. @@ -798,26 +721,12 @@ public interface AsyncAdmin { */ CompletableFuture deleteSnapshot(String snapshotName); - /** - * Delete existing snapshots whose names match the pattern passed. - * @param regex The regular expression to match against - */ - CompletableFuture deleteSnapshots(String regex); - /** * Delete existing snapshots whose names match the pattern passed. * @param pattern pattern for names of the snapshot to match */ CompletableFuture deleteSnapshots(Pattern pattern); - /** - * Delete all existing snapshots matching the given table name regular expression and snapshot - * name regular expression. - * @param tableNameRegex The table name regular expression to match against - * @param snapshotNameRegex The snapshot name regular expression to match against - */ - CompletableFuture deleteTableSnapshots(String tableNameRegex, String snapshotNameRegex); - /** * Delete all existing snapshots matching the given table name regular expression and snapshot * name regular expression. @@ -861,7 +770,7 @@ public interface AsyncAdmin { * @param instance The instance name of the procedure * @param props Property/Value pairs of properties passing to the procedure * @return true if the specified procedure is finished successfully, false if it is still running. - * The value is vrapped by {@link CompletableFuture} + * The value is wrapped by {@link CompletableFuture} */ CompletableFuture isProcedureFinished(String signature, String instance, Map props); @@ -879,5 +788,5 @@ public interface AsyncAdmin { * List procedures * @return procedure list wrapped by {@link CompletableFuture} */ - CompletableFuture listProcedures(); + CompletableFuture> listProcedures(); } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java index c972b4c1d20..8505241452f 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java @@ -40,10 +40,13 @@ import com.google.common.annotations.VisibleForTesting; import io.netty.util.Timeout; import io.netty.util.TimerTask; + import java.util.stream.Stream; + import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.directory.api.util.OptionalComponentsMonitor; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HRegionLocation; import org.apache.hadoop.hbase.MetaTableAccessor; @@ -190,7 +193,6 @@ import org.apache.hadoop.hbase.util.Pair; * The implementation of AsyncAdmin. */ @InterfaceAudience.Private -@InterfaceStability.Evolving public class AsyncHBaseAdmin implements AsyncAdmin { public static final String FLUSH_TABLE_PROCEDURE_SIGNATURE = "flush-table-proc"; @@ -278,7 +280,6 @@ public class AsyncHBaseAdmin implements AsyncAdmin { return future; } - //TODO abstract call and adminCall into a single method. private CompletableFuture adminCall(HBaseRpcController controller, AdminService.Interface stub, PREQ preq, AdminRpcCall rpcCall, Converter respConverter) { @@ -318,25 +319,26 @@ public class AsyncHBaseAdmin implements AsyncAdmin { CompletableFuture operate(TableName table); } - private CompletableFuture batchTableOperations(Pattern pattern, + private CompletableFuture> batchTableOperations(Pattern pattern, TableOperator operator, String operationType) { - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); List failed = new LinkedList<>(); - listTables(pattern, false).whenComplete( + listTables(Optional.ofNullable(pattern), false).whenComplete( (tables, error) -> { if (error != null) { future.completeExceptionally(error); return; } - CompletableFuture[] futures = Arrays.stream(tables) - .map((table) -> operator.operate(table.getTableName()).whenComplete((v, ex) -> { - if (ex != null) { - LOG.info("Failed to " + operationType + " table " + table.getTableName(), ex); - failed.add(table); - } - })). toArray(size -> new CompletableFuture[size]); + CompletableFuture[] futures = + tables.stream() + .map((table) -> operator.operate(table.getTableName()).whenComplete((v, ex) -> { + if (ex != null) { + LOG.info("Failed to " + operationType + " table " + table.getTableName(), ex); + failed.add(table); + } + })). toArray(size -> new CompletableFuture[size]); CompletableFuture.allOf(futures).thenAccept((v) -> { - future.complete(failed.toArray(new TableDescriptor[failed.size()])); + future.complete(failed); }); }); return future; @@ -353,47 +355,28 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture listTables() { - return listTables((Pattern) null, false); + public CompletableFuture> listTables(Optional pattern, + boolean includeSysTables) { + return this.> newMasterCaller() + .action((controller, stub) -> this + .> call( + controller, stub, + RequestConverter.buildGetTableDescriptorsRequest(pattern, includeSysTables), + (s, c, req, done) -> s.getTableDescriptors(c, req, done), + (resp) -> ProtobufUtil.toTableDescriptorList(resp))) + .call(); } @Override - public CompletableFuture listTables(String regex, boolean includeSysTables) { - return listTables(Pattern.compile(regex), false); - } - - @Override - public CompletableFuture listTables(Pattern pattern, boolean includeSysTables) { - return this - .newMasterCaller() - .action( - (controller, stub) -> this - . call( - controller, stub, RequestConverter.buildGetTableDescriptorsRequest(pattern, - includeSysTables), (s, c, req, done) -> s.getTableDescriptors(c, req, done), ( - resp) -> ProtobufUtil.getTableDescriptorArray(resp))).call(); - } - - @Override - public CompletableFuture listTableNames() { - return listTableNames((Pattern) null, false); - } - - @Override - public CompletableFuture listTableNames(String regex, boolean includeSysTables) { - return listTableNames(Pattern.compile(regex), false); - } - - @Override - public CompletableFuture listTableNames(Pattern pattern, boolean includeSysTables) { - return this - .newMasterCaller() - .action( - (controller, stub) -> this - . call(controller, stub, - RequestConverter.buildGetTableNamesRequest(pattern, includeSysTables), (s, c, req, - done) -> s.getTableNames(c, req, done), (resp) -> ProtobufUtil - .getTableNameArray(resp.getTableNamesList()))).call(); + public CompletableFuture> listTableNames(Optional pattern, + boolean includeSysTables) { + return this.> newMasterCaller() + .action((controller, stub) -> this + .> call(controller, stub, + RequestConverter.buildGetTableNamesRequest(pattern, includeSysTables), + (s, c, req, done) -> s.getTableNames(c, req, done), + (resp) -> ProtobufUtil.toTableNameList(resp.getTableNamesList()))) + .call(); } @Override @@ -472,12 +455,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture deleteTables(String regex) { - return deleteTables(Pattern.compile(regex)); - } - - @Override - public CompletableFuture deleteTables(Pattern pattern) { + public CompletableFuture> deleteTables(Pattern pattern) { return batchTableOperations(pattern, (table) -> deleteTable(table), "DELETE"); } @@ -498,12 +476,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture enableTables(String regex) { - return enableTables(Pattern.compile(regex)); - } - - @Override - public CompletableFuture enableTables(Pattern pattern) { + public CompletableFuture> enableTables(Pattern pattern) { return batchTableOperations(pattern, (table) -> enableTable(table), "ENABLE"); } @@ -516,16 +489,10 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture disableTables(String regex) { - return disableTables(Pattern.compile(regex)); - } - - @Override - public CompletableFuture disableTables(Pattern pattern) { + public CompletableFuture> disableTables(Pattern pattern) { return batchTableOperations(pattern, (table) -> disableTable(table), "DISABLE"); } - @Override public CompletableFuture isTableEnabled(TableName tableName) { CompletableFuture future = new CompletableFuture<>(); @@ -577,7 +544,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { if (!enabled) { future.complete(false); } else { - AsyncMetaTableAccessor.getTableRegionsAndLocations(metaTable, Optional.of(tableName)) + AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)) .whenComplete( (locations, error1) -> { if (error1 != null) { @@ -586,12 +553,12 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } int notDeployed = 0; int regionCount = 0; - for (Pair pair : locations) { - HRegionInfo info = pair.getFirst(); - if (pair.getSecond() == null) { + for (HRegionLocation location : locations) { + HRegionInfo info = location.getRegionInfo(); + if (location.getServerName() == null) { if (LOG.isDebugEnabled()) { LOG.debug("Table " + tableName + " has not deployed region " - + pair.getFirst().getEncodedName()); + + info.getEncodedName()); } notDeployed++; } else if (splitKeys != null @@ -706,21 +673,21 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture listNamespaceDescriptors() { + public CompletableFuture> listNamespaceDescriptors() { return this - . newMasterCaller() + .> newMasterCaller() .action( (controller, stub) -> this - . call( + .> call( controller, stub, ListNamespaceDescriptorsRequest.newBuilder().build(), (s, c, req, done) -> s.listNamespaceDescriptors(c, req, done), (resp) -> ProtobufUtil - .getNamespaceDescriptorArray(resp))).call(); + .toNamespaceDescriptorList(resp))).call(); } @Override - public CompletableFuture setBalancerRunning(final boolean on) { + public CompletableFuture setBalancerOn(final boolean on) { return this - .newMasterCaller() + . newMasterCaller() .action( (controller, stub) -> this . call(controller, @@ -730,24 +697,19 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture balancer() { - return balancer(false); - } - - @Override - public CompletableFuture balancer(boolean force) { + public CompletableFuture balance(boolean forcible) { return this - .newMasterCaller() + . newMasterCaller() .action( (controller, stub) -> this. call(controller, - stub, RequestConverter.buildBalanceRequest(force), + stub, RequestConverter.buildBalanceRequest(forcible), (s, c, req, done) -> s.balance(c, req, done), (resp) -> resp.getBalancerRan())).call(); } @Override - public CompletableFuture isBalancerEnabled() { + public CompletableFuture isBalancerOn() { return this - .newMasterCaller() + . newMasterCaller() .action( (controller, stub) -> this. call( controller, stub, RequestConverter.buildIsBalancerEnabledRequest(), @@ -756,109 +718,38 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture closeRegion(String regionname, String serverName) { - return closeRegion(Bytes.toBytes(regionname), serverName); - } - - @Override - public CompletableFuture closeRegion(byte[] regionName, String serverName) { - CompletableFuture future = new CompletableFuture<>(); - getRegion(regionName).whenComplete((p, err) -> { + public CompletableFuture closeRegion(byte[] regionName, Optional serverName) { + CompletableFuture future = new CompletableFuture<>(); + getRegionLocation(regionName).whenComplete((location, err) -> { if (err != null) { future.completeExceptionally(err); return; } - if (p == null || p.getFirst() == null) { - future.completeExceptionally(new UnknownRegionException(Bytes.toStringBinary(regionName))); - return; - } - if (serverName != null) { - closeRegion(ServerName.valueOf(serverName), p.getFirst()).whenComplete((p2, err2) -> { + ServerName server = serverName.isPresent() ? serverName.get() : location.getServerName(); + if (server == null) { + future.completeExceptionally(new NotServingRegionException(regionName)); + } else { + closeRegion(location.getRegionInfo(), server).whenComplete((result, err2) -> { if (err2 != null) { future.completeExceptionally(err2); - }else{ - future.complete(null); + } else { + future.complete(result); } }); - } else { - if (p.getSecond() == null) { - future.completeExceptionally(new NotServingRegionException(regionName)); - } else { - closeRegion(p.getSecond(), p.getFirst()).whenComplete((p2, err2) -> { - if (err2 != null) { - future.completeExceptionally(err2); - }else{ - future.complete(null); - } - }); - } } }); return future; } - CompletableFuture> getRegion(byte[] regionName) { - if (regionName == null) { - return failedFuture(new IllegalArgumentException("Pass region name")); - } - CompletableFuture> future = new CompletableFuture<>(); - AsyncMetaTableAccessor.getRegion(metaTable, regionName).whenComplete( - (p, err) -> { - if (err != null) { - future.completeExceptionally(err); - } else if (p != null) { - future.complete(p); - } else { - metaTable.scanAll( - new Scan().setReadType(ReadType.PREAD).addFamily(HConstants.CATALOG_FAMILY)) - .whenComplete((results, err2) -> { - if (err2 != null) { - future.completeExceptionally(err2); - return; - } - String encodedName = Bytes.toString(regionName); - if (results != null && !results.isEmpty()) { - for (Result r : results) { - if (r.isEmpty() || MetaTableAccessor.getHRegionInfo(r) == null) continue; - RegionLocations rl = MetaTableAccessor.getRegionLocations(r); - if (rl != null) { - for (HRegionLocation h : rl.getRegionLocations()) { - if (h != null && encodedName.equals(h.getRegionInfo().getEncodedName())) { - future.complete(new Pair<>(h.getRegionInfo(), h.getServerName())); - return; - } - } - } - } - } - future.complete(null); - }); - } - }); - return future; - } - - @Override - public CompletableFuture closeRegionWithEncodedRegionName(String encodedRegionName, - String serverName) { + private CompletableFuture closeRegion(HRegionInfo hri, ServerName serverName) { return this . newAdminCaller() .action( (controller, stub) -> this. adminCall( controller, stub, - ProtobufUtil.buildCloseRegionRequest(ServerName.valueOf(serverName), encodedRegionName), - (s, c, req, done) -> s.closeRegion(controller, req, done), (resp) -> resp.getClosed())) - .serverName(ServerName.valueOf(serverName)).call(); - } - - @Override - public CompletableFuture closeRegion(ServerName sn, HRegionInfo hri) { - return this. newAdminCaller() - .action( - (controller, stub) -> this. adminCall( - controller, stub, ProtobufUtil.buildCloseRegionRequest(sn, hri.getRegionName()), - (s, c, req, done) -> s.closeRegion(controller, req, done), resp -> null)) - .serverName(sn).call(); + ProtobufUtil.buildCloseRegionRequest(serverName, hri.getRegionName()), + (s, c, req, done) -> s.closeRegion(controller, req, done), resp -> resp.getClosed())) + .serverName(serverName).call(); } @Override @@ -905,75 +796,54 @@ public class AsyncHBaseAdmin implements AsyncAdmin { @Override public CompletableFuture flushRegion(byte[] regionName) { CompletableFuture future = new CompletableFuture<>(); - getRegion(regionName).whenComplete((p, err) -> { - if (err != null) { - future.completeExceptionally(err); - return; - } - if (p == null || p.getFirst() == null) { - future.completeExceptionally( - new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName))); - return; - } - if (p.getSecond() == null) { - future.completeExceptionally( - new NoServerForRegionException(Bytes.toStringBinary(regionName))); - return; - } + getRegionLocation(regionName).whenComplete( + (location, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } + ServerName serverName = location.getServerName(); + if (serverName == null) { + future.completeExceptionally(new NoServerForRegionException(Bytes + .toStringBinary(regionName))); + return; + } - this. newAdminCaller().serverName(p.getSecond()) - .action((controller, stub) -> this - . adminCall(controller, stub, - RequestConverter.buildFlushRegionRequest(p.getFirst().getRegionName()), - (s, c, req, done) -> s.flushRegion(c, req, done), resp -> null)) - .call().whenComplete((ret, err2) -> { - if (err2 != null) { - future.completeExceptionally(err2); - } else { - future.complete(ret); - } - }); - }); + HRegionInfo regionInfo = location.getRegionInfo(); + this. newAdminCaller() + .serverName(serverName) + .action( + (controller, stub) -> this. adminCall( + controller, stub, RequestConverter.buildFlushRegionRequest(regionInfo + .getRegionName()), (s, c, req, done) -> s.flushRegion(c, req, done), + resp -> null)).call().whenComplete((ret, err2) -> { + if (err2 != null) { + future.completeExceptionally(err2); + } else { + future.complete(ret); + } + }); + }); return future; } @Override - public CompletableFuture compact(TableName tableName) { - return compact(tableName, null, false, CompactType.NORMAL); - } - - @Override - public CompletableFuture compact(TableName tableName, byte[] columnFamily) { + public CompletableFuture compact(TableName tableName, Optional columnFamily) { return compact(tableName, columnFamily, false, CompactType.NORMAL); } @Override - public CompletableFuture compactRegion(byte[] regionName) { - return compactRegion(regionName, null, false); - } - - @Override - public CompletableFuture compactRegion(byte[] regionName, byte[] columnFamily) { + public CompletableFuture compactRegion(byte[] regionName, Optional columnFamily) { return compactRegion(regionName, columnFamily, false); } @Override - public CompletableFuture majorCompact(TableName tableName) { - return compact(tableName, null, true, CompactType.NORMAL); - } - - @Override - public CompletableFuture majorCompact(TableName tableName, byte[] columnFamily) { + public CompletableFuture majorCompact(TableName tableName, Optional columnFamily) { return compact(tableName, columnFamily, true, CompactType.NORMAL); } @Override - public CompletableFuture majorCompactRegion(byte[] regionName) { - return compactRegion(regionName, null, true); - } - - @Override - public CompletableFuture majorCompactRegion(byte[] regionName, byte[] columnFamily) { + public CompletableFuture majorCompactRegion(byte[] regionName, Optional columnFamily) { return compactRegion(regionName, columnFamily, true); } @@ -996,7 +866,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } List> compactFutures = new ArrayList<>(); if (hRegionInfos != null) { - hRegionInfos.forEach(region -> compactFutures.add(compact(sn, region, major, null))); + hRegionInfos.forEach(region -> compactFutures.add(compact(sn, region, major, Optional.empty()))); } CompletableFuture .allOf(compactFutures.toArray(new CompletableFuture[compactFutures.size()])) @@ -1011,33 +881,30 @@ public class AsyncHBaseAdmin implements AsyncAdmin { return future; } - private CompletableFuture compactRegion(final byte[] regionName, final byte[] columnFamily, - final boolean major) { + private CompletableFuture compactRegion(byte[] regionName, Optional columnFamily, + boolean major) { CompletableFuture future = new CompletableFuture<>(); - getRegion(regionName).whenComplete((p, err) -> { - if (err != null) { - future.completeExceptionally(err); - return; - } - if (p == null || p.getFirst() == null) { - future.completeExceptionally( - new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName))); - return; - } - if (p.getSecond() == null) { - // found a region without region server assigned. - future.completeExceptionally( - new NoServerForRegionException(Bytes.toStringBinary(regionName))); - return; - } - compact(p.getSecond(), p.getFirst(), major, columnFamily).whenComplete((ret, err2) -> { - if (err2 != null) { - future.completeExceptionally(err2); - } else { - future.complete(ret); + getRegionLocation(regionName).whenComplete( + (location, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; } + ServerName serverName = location.getServerName(); + if (serverName == null) { + future.completeExceptionally(new NoServerForRegionException(Bytes + .toStringBinary(regionName))); + return; + } + compact(location.getServerName(), location.getRegionInfo(), major, columnFamily) + .whenComplete((ret, err2) -> { + if (err2 != null) { + future.completeExceptionally(err2); + } else { + future.complete(ret); + } + }); }); - }); return future; } @@ -1045,45 +912,34 @@ public class AsyncHBaseAdmin implements AsyncAdmin { * List all region locations for the specific table. */ private CompletableFuture> getTableHRegionLocations(TableName tableName) { - CompletableFuture> future = new CompletableFuture<>(); if (TableName.META_TABLE_NAME.equals(tableName)) { + CompletableFuture> future = new CompletableFuture<>(); // For meta table, we use zk to fetch all locations. AsyncRegistry registry = AsyncRegistryFactory.getRegistry(connection.getConfiguration()); - registry.getMetaRegionLocation().whenComplete((metaRegions, err) -> { - if (err != null) { - future.completeExceptionally(err); - } else if (metaRegions == null || metaRegions.isEmpty() - || metaRegions.getDefaultRegionLocation() == null) { - future.completeExceptionally(new IOException("meta region does not found")); - } else { - future.complete(Collections.singletonList(metaRegions.getDefaultRegionLocation())); - } - // close the registry. - IOUtils.closeQuietly(registry); - }); + registry.getMetaRegionLocation().whenComplete( + (metaRegions, err) -> { + if (err != null) { + future.completeExceptionally(err); + } else if (metaRegions == null || metaRegions.isEmpty() + || metaRegions.getDefaultRegionLocation() == null) { + future.completeExceptionally(new IOException("meta region does not found")); + } else { + future.complete(Collections.singletonList(metaRegions.getDefaultRegionLocation())); + } + // close the registry. + IOUtils.closeQuietly(registry); + }); + return future; } else { // For non-meta table, we fetch all locations by scanning hbase:meta table - AsyncMetaTableAccessor.getTableRegionsAndLocations(metaTable, Optional.of(tableName)) - .whenComplete((locations, err) -> { - if (err != null) { - future.completeExceptionally(err); - } else if (locations == null || locations.isEmpty()) { - future.complete(Collections.emptyList()); - } else { - List regionLocations = locations.stream() - .map(loc -> new HRegionLocation(loc.getFirst(), loc.getSecond())) - .collect(Collectors.toList()); - future.complete(regionLocations); - } - }); + return AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)); } - return future; } /** * Compact column family of a table, Asynchronous operation even if CompletableFuture.get() */ - private CompletableFuture compact(final TableName tableName, final byte[] columnFamily, + private CompletableFuture compact(final TableName tableName, Optional columnFamily, final boolean major, CompactType compactType) { if (CompactType.MOB.equals(compactType)) { // TODO support MOB compact. @@ -1120,13 +976,15 @@ public class AsyncHBaseAdmin implements AsyncAdmin { * Compact the region at specific region server. */ private CompletableFuture compact(final ServerName sn, final HRegionInfo hri, - final boolean major, final byte[] family) { - return this. newAdminCaller().serverName(sn) - .action((controller, stub) -> this - . adminCall(controller, stub, - RequestConverter.buildCompactRegionRequest(hri.getRegionName(), major, family), - (s, c, req, done) -> s.compactRegion(c, req, done), resp -> null)) - .call(); + final boolean major, Optional columnFamily) { + return this + . newAdminCaller() + .serverName(sn) + .action( + (controller, stub) -> this. adminCall( + controller, stub, RequestConverter.buildCompactRegionRequest(hri.getRegionName(), + major, columnFamily), (s, c, req, done) -> s.compactRegion(c, req, done), + resp -> null)).call(); } private byte[] toEncodeRegionName(byte[] regionName) { @@ -1140,32 +998,29 @@ public class AsyncHBaseAdmin implements AsyncAdmin { private void checkAndGetTableName(byte[] encodeRegionName, AtomicReference tableName, CompletableFuture result) { - getRegion(encodeRegionName).whenComplete((p, err) -> { - if (err != null) { - result.completeExceptionally(err); - return; - } - if (p == null) { - result.completeExceptionally(new UnknownRegionException( - "Can't invoke merge on unknown region " + Bytes.toStringBinary(encodeRegionName))); - return; - } - if (p.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) { - result.completeExceptionally( - new IllegalArgumentException("Can't invoke merge on non-default regions directly")); - return; - } - if (!tableName.compareAndSet(null, p.getFirst().getTable())) { - if (!tableName.get().equals(p.getFirst().getTable())) { - // tables of this two region should be same. - result.completeExceptionally( - new IllegalArgumentException("Cannot merge regions from two different tables " - + tableName.get() + " and " + p.getFirst().getTable())); - } else { - result.complete(tableName.get()); + getRegionLocation(encodeRegionName).whenComplete( + (location, err) -> { + if (err != null) { + result.completeExceptionally(err); + return; } - } - }); + HRegionInfo regionInfo = location.getRegionInfo(); + if (regionInfo.getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) { + result.completeExceptionally(new IllegalArgumentException( + "Can't invoke merge on non-default regions directly")); + return; + } + if (!tableName.compareAndSet(null, regionInfo.getTable())) { + if (!tableName.get().equals(regionInfo.getTable())) { + // tables of this two region should be same. + result.completeExceptionally(new IllegalArgumentException( + "Cannot merge regions from two different tables " + tableName.get() + " and " + + regionInfo.getTable())); + } else { + result.complete(tableName.get()); + } + } + }); } private CompletableFuture checkRegionsAndGetTableName(byte[] encodeRegionNameA, @@ -1249,7 +1104,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { if (hri == null || hri.isSplitParent() || hri.getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) continue; - splitFutures.add(split(h.getServerName(), hri, null)); + splitFutures.add(split(h.getServerName(), hri, Optional.empty())); } } } @@ -1271,11 +1126,6 @@ public class AsyncHBaseAdmin implements AsyncAdmin { return future; } - @Override - public CompletableFuture splitRegion(byte[] regionName) { - return splitRegion(regionName, null); - } - @Override public CompletableFuture split(TableName tableName, byte[] splitPoint) { CompletableFuture result = new CompletableFuture<>(); @@ -1290,7 +1140,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { result.completeExceptionally(new IllegalArgumentException( "Region does not found: rowKey=" + Bytes.toStringBinary(splitPoint))); } else { - splitRegion(loc.getRegionInfo().getRegionName(), splitPoint) + splitRegion(loc.getRegionInfo().getRegionName(), Optional.of(splitPoint)) .whenComplete((ret, err2) -> { if (err2 != null) { result.completeExceptionally(err2); @@ -1305,182 +1155,149 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture splitRegion(byte[] regionName, byte[] splitPoint) { + public CompletableFuture splitRegion(byte[] regionName, Optional splitPoint) { CompletableFuture future = new CompletableFuture<>(); - getRegion(regionName).whenComplete((p, err) -> { - if (p == null) { - future.completeExceptionally( - new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName))); - return; - } - if (p.getFirst() != null && p.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) { - future.completeExceptionally(new IllegalArgumentException("Can't split replicas directly. " - + "Replicas are auto-split when their primary is split.")); - return; - } - if (p.getSecond() == null) { - future.completeExceptionally( - new NoServerForRegionException(Bytes.toStringBinary(regionName))); - return; - } - split(p.getSecond(), p.getFirst(), splitPoint).whenComplete((ret, err2) -> { - if (err2 != null) { - future.completeExceptionally(err2); - } else { - future.complete(ret); + getRegionLocation(regionName).whenComplete( + (location, err) -> { + HRegionInfo regionInfo = location.getRegionInfo(); + if (regionInfo.getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) { + future.completeExceptionally(new IllegalArgumentException( + "Can't split replicas directly. " + + "Replicas are auto-split when their primary is split.")); + return; } + ServerName serverName = location.getServerName(); + if (serverName == null) { + future.completeExceptionally(new NoServerForRegionException(Bytes + .toStringBinary(regionName))); + return; + } + split(serverName, regionInfo, splitPoint).whenComplete((ret, err2) -> { + if (err2 != null) { + future.completeExceptionally(err2); + } else { + future.complete(ret); + } + }); }); - }); return future; } - @VisibleForTesting - public CompletableFuture split(final ServerName sn, final HRegionInfo hri, - byte[] splitPoint) { - if (hri.getStartKey() != null && splitPoint != null - && Bytes.compareTo(hri.getStartKey(), splitPoint) == 0) { - return failedFuture( - new IllegalArgumentException("should not give a splitkey which equals to startkey!")); + private CompletableFuture split(final ServerName sn, final HRegionInfo hri, + Optional splitPoint) { + if (hri.getStartKey() != null && splitPoint.isPresent() + && Bytes.compareTo(hri.getStartKey(), splitPoint.get()) == 0) { + return failedFuture(new IllegalArgumentException( + "should not give a splitkey which equals to startkey!")); } - return this. newAdminCaller() + return this + . newAdminCaller() .action( (controller, stub) -> this. adminCall( - controller, stub, ProtobufUtil.buildSplitRegionRequest(hri.getRegionName(), splitPoint), + controller, stub, + ProtobufUtil.buildSplitRegionRequest(hri.getRegionName(), splitPoint), (s, c, req, done) -> s.splitRegion(controller, req, done), resp -> null)) .serverName(sn).call(); } - /** - * Turn regionNameOrEncodedRegionName into regionName, if region does not found, then it'll throw - * an IllegalArgumentException wrapped by a {@link CompletableFuture} - * @param regionNameOrEncodedRegionName - * @return - */ - CompletableFuture getRegionName(byte[] regionNameOrEncodedRegionName) { - CompletableFuture future = new CompletableFuture<>(); - if (Bytes - .equals(regionNameOrEncodedRegionName, HRegionInfo.FIRST_META_REGIONINFO.getRegionName()) - || Bytes.equals(regionNameOrEncodedRegionName, - HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes())) { - future.complete(HRegionInfo.FIRST_META_REGIONINFO.getRegionName()); - return future; - } - - getRegion(regionNameOrEncodedRegionName).whenComplete((p, err) -> { - if (err != null) { - future.completeExceptionally(err); - } - if (p != null && p.getFirst() != null) { - future.complete(p.getFirst().getRegionName()); - } else { - future.completeExceptionally( - new IllegalArgumentException("Invalid region name or encoded region name: " - + Bytes.toStringBinary(regionNameOrEncodedRegionName))); - } - }); - return future; - } - @Override public CompletableFuture assign(byte[] regionName) { CompletableFuture future = new CompletableFuture<>(); - getRegionName(regionName).whenComplete((fullRegionName, err) -> { - if (err != null) { - future.completeExceptionally(err); - } else { + getRegionInfo(regionName).whenComplete( + (regionInfo, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } this. newMasterCaller() .action( ((controller, stub) -> this. call( - controller, stub, RequestConverter.buildAssignRegionRequest(fullRegionName), - (s, c, req, done) -> s.assignRegion(c, req, done), resp -> null))) - .call().whenComplete((ret, err2) -> { + controller, stub, RequestConverter.buildAssignRegionRequest(regionInfo + .getRegionName()), (s, c, req, done) -> s.assignRegion(c, req, done), + resp -> null))).call().whenComplete((ret, err2) -> { if (err2 != null) { future.completeExceptionally(err2); } else { future.complete(ret); } }); - } - }); + }); return future; } @Override - public CompletableFuture unassign(byte[] regionName, boolean force) { + public CompletableFuture unassign(byte[] regionName, boolean forcible) { CompletableFuture future = new CompletableFuture<>(); - getRegionName(regionName).whenComplete((fullRegionName, err) -> { - if (err != null) { - future.completeExceptionally(err); - } else { + getRegionInfo(regionName).whenComplete( + (regionInfo, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } this. newMasterCaller() - .action(((controller, stub) -> this - . call(controller, stub, - RequestConverter.buildUnassignRegionRequest(fullRegionName, force), - (s, c, req, done) -> s.unassignRegion(c, req, done), resp -> null))) - .call().whenComplete((ret, err2) -> { + .action( + ((controller, stub) -> this + . call(controller, stub, + RequestConverter.buildUnassignRegionRequest(regionInfo.getRegionName(), forcible), + (s, c, req, done) -> s.unassignRegion(c, req, done), resp -> null))).call() + .whenComplete((ret, err2) -> { if (err2 != null) { future.completeExceptionally(err2); } else { future.complete(ret); } }); - } - }); + }); return future; } @Override public CompletableFuture offline(byte[] regionName) { CompletableFuture future = new CompletableFuture<>(); - getRegionName(regionName).whenComplete((fullRegionName, err) -> { - if (err != null) { - future.completeExceptionally(err); - } else { + getRegionInfo(regionName).whenComplete( + (regionInfo, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } this. newMasterCaller() .action( ((controller, stub) -> this. call( - controller, stub, RequestConverter.buildOfflineRegionRequest(fullRegionName), - (s, c, req, done) -> s.offlineRegion(c, req, done), resp -> null))) - .call().whenComplete((ret, err2) -> { + controller, stub, RequestConverter.buildOfflineRegionRequest(regionInfo + .getRegionName()), (s, c, req, done) -> s.offlineRegion(c, req, done), + resp -> null))).call().whenComplete((ret, err2) -> { if (err2 != null) { future.completeExceptionally(err2); } else { future.complete(ret); } }); - } - }); + }); return future; } @Override - public CompletableFuture move(byte[] regionName, byte[] destServerName) { + public CompletableFuture move(byte[] regionName, Optional destServerName) { CompletableFuture future = new CompletableFuture<>(); - getRegionName(regionName).whenComplete((fullRegionName, err) -> { - if (err != null) { - future.completeExceptionally(err); - } else { - final MoveRegionRequest request; - try { - request = RequestConverter.buildMoveRegionRequest( - Bytes.toBytes(HRegionInfo.encodeRegionName(fullRegionName)), destServerName); - } catch (DeserializationException e) { - future.completeExceptionally(e); + getRegionInfo(regionName).whenComplete( + (regionInfo, err) -> { + if (err != null) { + future.completeExceptionally(err); return; } this. newMasterCaller() - .action((controller, stub) -> this. call( - controller, stub, request, (s, c, req, done) -> s.moveRegion(c, req, done), - resp -> null)) - .call().whenComplete((ret, err2) -> { + .action( + (controller, stub) -> this. call( + controller, stub, RequestConverter.buildMoveRegionRequest( + regionInfo.getEncodedNameAsBytes(), destServerName), (s, c, req, done) -> s + .moveRegion(c, req, done), resp -> null)).call().whenComplete((ret, err2) -> { if (err2 != null) { future.completeExceptionally(err2); } else { future.complete(ret); } }); - } - }); + }); return future; } @@ -1644,17 +1461,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture> listReplicationPeers() { - return listReplicationPeers((Pattern) null); - } - - @Override - public CompletableFuture> listReplicationPeers(String regex) { - return listReplicationPeers(Pattern.compile(regex)); - } - - @Override - public CompletableFuture> listReplicationPeers(Pattern pattern) { + public CompletableFuture> listReplicationPeers(Optional pattern) { return this .> newMasterCaller() .action( @@ -1676,18 +1483,17 @@ public class AsyncHBaseAdmin implements AsyncAdmin { (tables, error) -> { if (!completeExceptionally(future, error)) { List replicatedTableCFs = new ArrayList<>(); - Arrays.asList(tables).forEach( - table -> { - Map cfs = new HashMap<>(); - Stream.of(table.getColumnFamilies()) - .filter(column -> column.getScope() != HConstants.REPLICATION_SCOPE_LOCAL) - .forEach(column -> { - cfs.put(column.getNameAsString(), column.getScope()); - }); - if (!cfs.isEmpty()) { - replicatedTableCFs.add(new TableCFs(table.getTableName(), cfs)); - } - }); + tables.forEach(table -> { + Map cfs = new HashMap<>(); + Stream.of(table.getColumnFamilies()) + .filter(column -> column.getScope() != HConstants.REPLICATION_SCOPE_LOCAL) + .forEach(column -> { + cfs.put(column.getNameAsString(), column.getScope()); + }); + if (!cfs.isEmpty()) { + replicatedTableCFs.add(new TableCFs(table.getTableName(), cfs)); + } + }); future.complete(replicatedTableCFs); } }); @@ -1707,8 +1513,8 @@ public class AsyncHBaseAdmin implements AsyncAdmin { @Override public CompletableFuture snapshot(SnapshotDescription snapshotDesc) { - SnapshotProtos.SnapshotDescription snapshot = - ProtobufUtil.createHBaseProtosSnapshotDesc(snapshotDesc); + SnapshotProtos.SnapshotDescription snapshot = ProtobufUtil + .createHBaseProtosSnapshotDesc(snapshotDesc); try { ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot); } catch (IllegalArgumentException e) { @@ -1717,10 +1523,10 @@ public class AsyncHBaseAdmin implements AsyncAdmin { CompletableFuture future = new CompletableFuture<>(); final SnapshotRequest request = SnapshotRequest.newBuilder().setSnapshot(snapshot).build(); this. newMasterCaller() - .action((controller, stub) -> this. call( - controller, stub, request, (s, c, req, done) -> s.snapshot(c, req, done), - resp -> resp.getExpectedTimeout())) - .call().whenComplete((expectedTimeout, err) -> { + .action( + (controller, stub) -> this. call(controller, + stub, request, (s, c, req, done) -> s.snapshot(c, req, done), + resp -> resp.getExpectedTimeout())).call().whenComplete((expectedTimeout, err) -> { if (err != null) { future.completeExceptionally(err); return; @@ -1734,25 +1540,24 @@ public class AsyncHBaseAdmin implements AsyncAdmin { @Override public void run(Timeout timeout) throws Exception { if (EnvironmentEdgeManager.currentTime() < endTime) { - isSnapshotFinished(snapshotDesc).whenComplete((done, err) -> { - if (err != null) { - future.completeExceptionally(err); + isSnapshotFinished(snapshotDesc).whenComplete((done, err2) -> { + if (err2 != null) { + future.completeExceptionally(err2); } else if (done) { future.complete(null); } else { // retry again after pauseTime. - long pauseTime = ConnectionUtils - .getPauseTime(TimeUnit.NANOSECONDS.toMillis(pauseNs), ++tries); - pauseTime = Math.min(pauseTime, maxPauseTime); - AsyncConnectionImpl.RETRY_TIMER.newTimeout(this, pauseTime, - TimeUnit.MILLISECONDS); - } - }); + long pauseTime = ConnectionUtils.getPauseTime( + TimeUnit.NANOSECONDS.toMillis(pauseNs), ++tries); + pauseTime = Math.min(pauseTime, maxPauseTime); + AsyncConnectionImpl.RETRY_TIMER + .newTimeout(this, pauseTime, TimeUnit.MILLISECONDS); + } + } ); } else { - future.completeExceptionally(new SnapshotCreationException( - "Snapshot '" + snapshot.getName() + "' wasn't completed in expectedTime:" - + expectedTimeout + " ms", - snapshotDesc)); + future.completeExceptionally(new SnapshotCreationException("Snapshot '" + + snapshot.getName() + "' wasn't completed in expectedTime:" + expectedTimeout + + " ms", snapshotDesc)); } } }; @@ -1763,13 +1568,15 @@ public class AsyncHBaseAdmin implements AsyncAdmin { @Override public CompletableFuture isSnapshotFinished(SnapshotDescription snapshot) { - return this. newMasterCaller() - .action((controller, stub) -> this - . call(controller, stub, - IsSnapshotDoneRequest.newBuilder() - .setSnapshot(ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot)).build(), - (s, c, req, done) -> s.isSnapshotDone(c, req, done), resp -> resp.getDone())) - .call(); + return this + . newMasterCaller() + .action( + (controller, stub) -> this. call( + controller, + stub, + IsSnapshotDoneRequest.newBuilder() + .setSnapshot(ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot)).build(), (s, c, + req, done) -> s.isSnapshotDone(c, req, done), resp -> resp.getDone())).call(); } @Override @@ -1780,109 +1587,110 @@ public class AsyncHBaseAdmin implements AsyncAdmin { return restoreSnapshot(snapshotName, takeFailSafeSnapshot); } - private CompletableFuture restoreSnapshotWithFailSafe(String snapshotName, - TableName tableName, boolean takeFailSafeSnapshot) { + @Override + public CompletableFuture restoreSnapshot(String snapshotName, boolean takeFailSafeSnapshot) { + CompletableFuture future = new CompletableFuture<>(); + listSnapshots(Pattern.compile(snapshotName)).whenComplete( + (snapshotDescriptions, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } + TableName tableName = null; + if (snapshotDescriptions != null && !snapshotDescriptions.isEmpty()) { + for (SnapshotDescription snap : snapshotDescriptions) { + if (snap.getName().equals(snapshotName)) { + tableName = snap.getTableName(); + break; + } + } + } + if (tableName == null) { + future.completeExceptionally(new RestoreSnapshotException( + "Unable to find the table name for snapshot=" + snapshotName)); + return; + } + final TableName finalTableName = tableName; + tableExists(finalTableName) + .whenComplete((exists, err2) -> { + if (err2 != null) { + future.completeExceptionally(err2); + } else if (!exists) { + // if table does not exist, then just clone snapshot into new table. + completeConditionalOnFuture(future, + internalRestoreSnapshot(snapshotName, finalTableName)); + } else { + isTableDisabled(finalTableName).whenComplete( + (disabled, err4) -> { + if (err4 != null) { + future.completeExceptionally(err4); + } else if (!disabled) { + future.completeExceptionally(new TableNotDisabledException(finalTableName)); + } else { + completeConditionalOnFuture(future, + restoreSnapshot(snapshotName, finalTableName, takeFailSafeSnapshot)); + } + }); + } + } ); + }); + return future; + } + + private CompletableFuture restoreSnapshot(String snapshotName, TableName tableName, + boolean takeFailSafeSnapshot) { if (takeFailSafeSnapshot) { CompletableFuture future = new CompletableFuture<>(); // Step.1 Take a snapshot of the current state - String failSafeSnapshotSnapshotNameFormat = - this.connection.getConfiguration().get(HConstants.SNAPSHOT_RESTORE_FAILSAFE_NAME, - HConstants.DEFAULT_SNAPSHOT_RESTORE_FAILSAFE_NAME); - final String failSafeSnapshotSnapshotName = - failSafeSnapshotSnapshotNameFormat.replace("{snapshot.name}", snapshotName) - .replace("{table.name}", tableName.toString().replace(TableName.NAMESPACE_DELIM, '.')) - .replace("{restore.timestamp}", String.valueOf(EnvironmentEdgeManager.currentTime())); + String failSafeSnapshotSnapshotNameFormat = this.connection.getConfiguration().get( + HConstants.SNAPSHOT_RESTORE_FAILSAFE_NAME, + HConstants.DEFAULT_SNAPSHOT_RESTORE_FAILSAFE_NAME); + final String failSafeSnapshotSnapshotName = failSafeSnapshotSnapshotNameFormat + .replace("{snapshot.name}", snapshotName) + .replace("{table.name}", tableName.toString().replace(TableName.NAMESPACE_DELIM, '.')) + .replace("{restore.timestamp}", String.valueOf(EnvironmentEdgeManager.currentTime())); LOG.info("Taking restore-failsafe snapshot: " + failSafeSnapshotSnapshotName); snapshot(failSafeSnapshotSnapshotName, tableName).whenComplete((ret, err) -> { if (err != null) { future.completeExceptionally(err); } else { // Step.2 Restore snapshot - internalRestoreSnapshot(snapshotName, tableName).whenComplete((void2, err2) -> { - if (err2 != null) { - // Step.3.a Something went wrong during the restore and try to rollback. - internalRestoreSnapshot(failSafeSnapshotSnapshotName, tableName) - .whenComplete((void3, err3) -> { - if (err3 != null) { - future.completeExceptionally(err3); - } else { - String msg = - "Restore snapshot=" + snapshotName + " failed. Rollback to snapshot=" - + failSafeSnapshotSnapshotName + " succeeded."; - future.completeExceptionally(new RestoreSnapshotException(msg)); - } - }); - } else { - // Step.3.b If the restore is succeeded, delete the pre-restore snapshot. - LOG.info("Deleting restore-failsafe snapshot: " + failSafeSnapshotSnapshotName); - deleteSnapshot(failSafeSnapshotSnapshotName).whenComplete((ret3, err3) -> { - if (err3 != null) { - LOG.error( - "Unable to remove the failsafe snapshot: " + failSafeSnapshotSnapshotName, - err3); - future.completeExceptionally(err3); - } else { - future.complete(ret3); - } - }); - } - }); + internalRestoreSnapshot(snapshotName, tableName).whenComplete((void2, err2) -> { + if (err2 != null) { + // Step.3.a Something went wrong during the restore and try to rollback. + internalRestoreSnapshot(failSafeSnapshotSnapshotName, tableName).whenComplete( + (void3, err3) -> { + if (err3 != null) { + future.completeExceptionally(err3); + } else { + String msg = "Restore snapshot=" + snapshotName + " failed. Rollback to snapshot=" + + failSafeSnapshotSnapshotName + " succeeded."; + future.completeExceptionally(new RestoreSnapshotException(msg)); + } + }); + } else { + // Step.3.b If the restore is succeeded, delete the pre-restore snapshot. + LOG.info("Deleting restore-failsafe snapshot: " + failSafeSnapshotSnapshotName); + deleteSnapshot(failSafeSnapshotSnapshotName).whenComplete( + (ret3, err3) -> { + if (err3 != null) { + LOG.error( + "Unable to remove the failsafe snapshot: " + failSafeSnapshotSnapshotName, err3); + future.completeExceptionally(err3); + } else { + future.complete(ret3); + } + }); } - }); + } ); + } + } ); return future; } else { return internalRestoreSnapshot(snapshotName, tableName); } } - @Override - public CompletableFuture restoreSnapshot(String snapshotName, - boolean takeFailSafeSnapshot) { - CompletableFuture future = new CompletableFuture<>(); - listSnapshots(snapshotName).whenComplete((snapshotDescriptions, err) -> { - if (err != null) { - future.completeExceptionally(err); - return; - } - TableName tableName = null; - if (snapshotDescriptions != null && !snapshotDescriptions.isEmpty()) { - for (SnapshotDescription snap : snapshotDescriptions) { - if (snap.getName().equals(snapshotName)) { - tableName = snap.getTableName(); - break; - } - } - } - if (tableName == null) { - future.completeExceptionally(new RestoreSnapshotException( - "Unable to find the table name for snapshot=" + snapshotName)); - return; - } - final TableName finalTableName = tableName; - tableExists(finalTableName).whenComplete((exists, err2) -> { - if (err2 != null) { - future.completeExceptionally(err2); - } else if (!exists) { - // if table does not exist, then just clone snapshot into new table. - completeConditionalOnFuture(future, - internalRestoreSnapshot(snapshotName, finalTableName)); - } else { - isTableDisabled(finalTableName).whenComplete((disabled, err4) -> { - if (err4 != null) { - future.completeExceptionally(err4); - } else if (!disabled) { - future.completeExceptionally(new TableNotDisabledException(finalTableName)); - } else { - completeConditionalOnFuture(future, - restoreSnapshotWithFailSafe(snapshotName, finalTableName, takeFailSafeSnapshot)); - } - }); - } - }); - }); - return future; - } - private void completeConditionalOnFuture(CompletableFuture dependentFuture, CompletableFuture parentFuture) { parentFuture.whenComplete((res, err) -> { @@ -1909,8 +1717,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { return future; } - private CompletableFuture internalRestoreSnapshot(String snapshotName, - TableName tableName) { + private CompletableFuture internalRestoreSnapshot(String snapshotName, TableName tableName) { SnapshotProtos.SnapshotDescription snapshot = SnapshotProtos.SnapshotDescription.newBuilder() .setName(snapshotName).setTable(tableName.getNameAsString()).build(); try { @@ -1918,86 +1725,78 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } catch (IllegalArgumentException e) { return failedFuture(e); } - return waitProcedureResult( - this. newMasterCaller() - .action((controller, stub) -> this - . call(controller, stub, - RestoreSnapshotRequest.newBuilder().setSnapshot(snapshot) - .setNonceGroup(ng.getNonceGroup()).setNonce(ng.newNonce()).build(), - (s, c, req, done) -> s.restoreSnapshot(c, req, done), - (resp) -> resp.getProcId())) - .call()); + return waitProcedureResult(this + . newMasterCaller() + .action( + (controller, stub) -> this. call( + controller, stub, RestoreSnapshotRequest.newBuilder().setSnapshot(snapshot) + .setNonceGroup(ng.getNonceGroup()).setNonce(ng.newNonce()).build(), (s, c, req, + done) -> s.restoreSnapshot(c, req, done), (resp) -> resp.getProcId())).call()); } @Override public CompletableFuture> listSnapshots() { - return this.> newMasterCaller() - .action((controller, stub) -> this - .> call( - controller, stub, GetCompletedSnapshotsRequest.newBuilder().build(), - (s, c, req, done) -> s.getCompletedSnapshots(c, req, done), - resp -> resp.getSnapshotsList().stream().map(ProtobufUtil::createSnapshotDesc) - .collect(Collectors.toList()))) + return this + .> newMasterCaller() + .action( + (controller, stub) -> this + .> call( + controller, stub, GetCompletedSnapshotsRequest.newBuilder().build(), (s, c, req, + done) -> s.getCompletedSnapshots(c, req, done), resp -> resp.getSnapshotsList() + .stream().map(ProtobufUtil::createSnapshotDesc).collect(Collectors.toList()))) .call(); } - @Override - public CompletableFuture> listSnapshots(String regex) { - return listSnapshots(Pattern.compile(regex)); - } - @Override public CompletableFuture> listSnapshots(Pattern pattern) { CompletableFuture> future = new CompletableFuture<>(); - listSnapshots().whenComplete((snapshotDescList, err) -> { - if (err != null) { - future.completeExceptionally(err); - return; - } - if (snapshotDescList == null || snapshotDescList.isEmpty()) { - future.complete(Collections.emptyList()); - return; - } - future.complete(snapshotDescList.stream() - .filter(snap -> pattern.matcher(snap.getName()).matches()).collect(Collectors.toList())); - }); + listSnapshots() + .whenComplete( + (snapshotDescList, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } + if (snapshotDescList == null || snapshotDescList.isEmpty()) { + future.complete(Collections.emptyList()); + return; + } + future.complete(snapshotDescList.stream() + .filter(snap -> pattern.matcher(snap.getName()).matches()) + .collect(Collectors.toList())); + }); return future; } - @Override - public CompletableFuture> listTableSnapshots(String tableNameRegex, - String snapshotNameRegex) { - return listTableSnapshots(Pattern.compile(tableNameRegex), Pattern.compile(snapshotNameRegex)); - } - @Override public CompletableFuture> listTableSnapshots(Pattern tableNamePattern, Pattern snapshotNamePattern) { CompletableFuture> future = new CompletableFuture<>(); - listTableNames(tableNamePattern, false).whenComplete((tableNames, err) -> { - if (err != null) { - future.completeExceptionally(err); - return; - } - if (tableNames == null || tableNames.length <= 0) { - future.complete(Collections.emptyList()); - return; - } - List tableNameList = Arrays.asList(tableNames); - listSnapshots(snapshotNamePattern).whenComplete((snapshotDescList, err2) -> { - if (err2 != null) { - future.completeExceptionally(err2); + listTableNames(Optional.ofNullable(tableNamePattern), false).whenComplete( + (tableNames, err) -> { + if (err != null) { + future.completeExceptionally(err); return; } - if (snapshotDescList == null || snapshotDescList.isEmpty()) { + if (tableNames == null || tableNames.size() <= 0) { future.complete(Collections.emptyList()); return; } - future.complete(snapshotDescList.stream() - .filter(snap -> (snap != null && tableNameList.contains(snap.getTableName()))) - .collect(Collectors.toList())); + listSnapshots(snapshotNamePattern).whenComplete( + (snapshotDescList, err2) -> { + if (err2 != null) { + future.completeExceptionally(err2); + return; + } + if (snapshotDescList == null || snapshotDescList.isEmpty()) { + future.complete(Collections.emptyList()); + return; + } + future.complete(snapshotDescList.stream() + .filter(snap -> (snap != null && tableNames.contains(snap.getTableName()))) + .collect(Collectors.toList())); + }); }); - }); return future; } @@ -2006,48 +1805,47 @@ public class AsyncHBaseAdmin implements AsyncAdmin { return internalDeleteSnapshot(new SnapshotDescription(snapshotName)); } - @Override - public CompletableFuture deleteSnapshots(String regex) { - return deleteSnapshots(Pattern.compile(regex)); - } - @Override public CompletableFuture deleteSnapshots(Pattern snapshotNamePattern) { return deleteTableSnapshots(null, snapshotNamePattern); } - @Override - public CompletableFuture deleteTableSnapshots(String tableNameRegex, - String snapshotNameRegex) { - return deleteTableSnapshots(Pattern.compile(tableNameRegex), - Pattern.compile(snapshotNameRegex)); - } - @Override public CompletableFuture deleteTableSnapshots(Pattern tableNamePattern, Pattern snapshotNamePattern) { CompletableFuture future = new CompletableFuture<>(); - listTableSnapshots(tableNamePattern, snapshotNamePattern) - .whenComplete(((snapshotDescriptions, err) -> { - if (err != null) { - future.completeExceptionally(err); - return; - } - if (snapshotDescriptions == null || snapshotDescriptions.isEmpty()) { - future.complete(null); - return; - } - List> deleteSnapshotFutures = new ArrayList<>(); - snapshotDescriptions - .forEach(snapDesc -> deleteSnapshotFutures.add(internalDeleteSnapshot(snapDesc))); - CompletableFuture - .allOf(deleteSnapshotFutures - .toArray(new CompletableFuture[deleteSnapshotFutures.size()])) - .thenAccept(v -> future.complete(v)); - })); + listTableSnapshots(tableNamePattern, snapshotNamePattern).whenComplete( + ((snapshotDescriptions, err) -> { + if (err != null) { + future.completeExceptionally(err); + return; + } + if (snapshotDescriptions == null || snapshotDescriptions.isEmpty()) { + future.complete(null); + return; + } + List> deleteSnapshotFutures = new ArrayList<>(); + snapshotDescriptions.forEach(snapDesc -> deleteSnapshotFutures + .add(internalDeleteSnapshot(snapDesc))); + CompletableFuture.allOf( + deleteSnapshotFutures.toArray(new CompletableFuture[deleteSnapshotFutures.size()])) + .thenAccept(v -> future.complete(v)); + })); return future; } + private CompletableFuture internalDeleteSnapshot(SnapshotDescription snapshot) { + return this + . newMasterCaller() + .action( + (controller, stub) -> this. call( + controller, + stub, + DeleteSnapshotRequest.newBuilder() + .setSnapshot(ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot)).build(), (s, c, + req, done) -> s.deleteSnapshot(c, req, done), resp -> null)).call(); + } + @Override public CompletableFuture execProcedure(String signature, String instance, Map props) { @@ -2072,9 +1870,9 @@ public class AsyncHBaseAdmin implements AsyncAdmin { @Override public void run(Timeout timeout) throws Exception { if (EnvironmentEdgeManager.currentTime() < endTime) { - isProcedureFinished(signature, instance, props).whenComplete((done, err) -> { - if (err != null) { - future.completeExceptionally(err); + isProcedureFinished(signature, instance, props).whenComplete((done, err2) -> { + if (err2 != null) { + future.completeExceptionally(err2); return; } if (done) { @@ -2137,24 +1935,87 @@ public class AsyncHBaseAdmin implements AsyncAdmin { } @Override - public CompletableFuture listProcedures() { - return this. newMasterCaller() - .action((controller, stub) -> this - . call(controller, stub, - ListProceduresRequest.newBuilder().build(), - (s, c, req, done) -> s.listProcedures(c, req, done), resp -> resp.getProcedureList() - .stream().map(ProtobufUtil::toProcedureInfo).toArray(ProcedureInfo[]::new))) - .call(); + public CompletableFuture> listProcedures() { + return this + .> newMasterCaller() + .action( + (controller, stub) -> this + .> call( + controller, stub, ListProceduresRequest.newBuilder().build(), + (s, c, req, done) -> s.listProcedures(c, req, done), + resp -> resp.getProcedureList().stream().map(ProtobufUtil::toProcedureInfo) + .collect(Collectors.toList()))).call(); } - private CompletableFuture internalDeleteSnapshot(SnapshotDescription snapshot) { - return this. newMasterCaller() - .action((controller, stub) -> this - . call(controller, stub, - DeleteSnapshotRequest.newBuilder() - .setSnapshot(ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot)).build(), - (s, c, req, done) -> s.deleteSnapshot(c, req, done), resp -> null)) - .call(); + /** + * Get the region location for the passed region name. The region name may be a full region name + * or encoded region name. If the region does not found, then it'll throw an + * UnknownRegionException wrapped by a {@link CompletableFuture} + * @param regionNameOrEncodedRegionName + * @return region location, wrapped by a {@link CompletableFuture} + */ + @VisibleForTesting + CompletableFuture getRegionLocation(byte[] regionNameOrEncodedRegionName) { + if (regionNameOrEncodedRegionName == null) { + return failedFuture(new IllegalArgumentException("Passed region name can't be null")); + } + try { + CompletableFuture> future; + if (HRegionInfo.isEncodedRegionName(regionNameOrEncodedRegionName)) { + future = AsyncMetaTableAccessor.getRegionLocationWithEncodedName(metaTable, + regionNameOrEncodedRegionName); + } else { + future = AsyncMetaTableAccessor.getRegionLocation(metaTable, regionNameOrEncodedRegionName); + } + + CompletableFuture returnedFuture = new CompletableFuture<>(); + future.whenComplete((location, err) -> { + if (err != null) { + returnedFuture.completeExceptionally(err); + return; + } + if (!location.isPresent() || location.get().getRegionInfo() == null) { + returnedFuture.completeExceptionally(new UnknownRegionException( + "Invalid region name or encoded region name: " + + Bytes.toStringBinary(regionNameOrEncodedRegionName))); + } else { + returnedFuture.complete(location.get()); + } + }); + return returnedFuture; + } catch (IOException e) { + return failedFuture(e); + } + } + + /** + * Get the region info for the passed region name. The region name may be a full region name or + * encoded region name. If the region does not found, then it'll throw an UnknownRegionException + * wrapped by a {@link CompletableFuture} + * @param regionNameOrEncodedRegionName + * @return region info, wrapped by a {@link CompletableFuture} + */ + private CompletableFuture getRegionInfo(byte[] regionNameOrEncodedRegionName) { + if (regionNameOrEncodedRegionName == null) { + return failedFuture(new IllegalArgumentException("Passed region name can't be null")); + } + + if (Bytes.equals(regionNameOrEncodedRegionName, + HRegionInfo.FIRST_META_REGIONINFO.getRegionName()) + || Bytes.equals(regionNameOrEncodedRegionName, + HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes())) { + return CompletableFuture.completedFuture(HRegionInfo.FIRST_META_REGIONINFO); + } + + CompletableFuture future = new CompletableFuture<>(); + getRegionLocation(regionNameOrEncodedRegionName).whenComplete((location, err) -> { + if (err != null) { + future.completeExceptionally(err); + } else { + future.complete(location.getRegionInfo()); + } + }); + return future; } private byte[][] getSplitKeys(byte[] startKey, byte[] endKey, int numRegions) { diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java index b1969115a4b..5f8924f0c14 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java @@ -33,8 +33,10 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.NavigableSet; +import java.util.Optional; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; @@ -414,18 +416,14 @@ public final class ProtobufUtil { } /** - * Get NamespaceDescriptor[] from ListNamespaceDescriptorsResponse protobuf + * Get a list of NamespaceDescriptor from ListNamespaceDescriptorsResponse protobuf * @param proto the ListNamespaceDescriptorsResponse - * @return NamespaceDescriptor[] + * @return a list of NamespaceDescriptor */ - public static NamespaceDescriptor[] getNamespaceDescriptorArray( + public static List toNamespaceDescriptorList( ListNamespaceDescriptorsResponse proto) { - List list = proto.getNamespaceDescriptorList(); - NamespaceDescriptor[] res = new NamespaceDescriptor[list.size()]; - for (int i = 0; i < list.size(); i++) { - res[i] = ProtobufUtil.toNamespaceDescriptor(list.get(i)); - } - return res; + return proto.getNamespaceDescriptorList().stream().map(ProtobufUtil::toNamespaceDescriptor) + .collect(Collectors.toList()); } /** @@ -433,7 +431,7 @@ public final class ProtobufUtil { * * @param proto the GetTableDescriptorsResponse * @return a immutable HTableDescriptor array - * @deprecated Use {@link #getTableDescriptorArray} after removing the HTableDescriptor + * @deprecated Use {@link #toTableDescriptorList} after removing the HTableDescriptor */ @Deprecated public static HTableDescriptor[] getHTableDescriptorArray(GetTableDescriptorsResponse proto) { @@ -447,18 +445,17 @@ public final class ProtobufUtil { } /** - * Get TableDescriptor[] from GetTableDescriptorsResponse protobuf + * Get a list of TableDescriptor from GetTableDescriptorsResponse protobuf * * @param proto the GetTableDescriptorsResponse - * @return TableDescriptor[] + * @return a list of TableDescriptor */ - public static TableDescriptor[] getTableDescriptorArray(GetTableDescriptorsResponse proto) { - if (proto == null) return new TableDescriptor[0]; - return proto.getTableSchemaList() - .stream() - .map(ProtobufUtil::convertToTableDesc) - .toArray(size -> new TableDescriptor[size]); + public static List toTableDescriptorList(GetTableDescriptorsResponse proto) { + if (proto == null) return new ArrayList<>(); + return proto.getTableSchemaList().stream().map(ProtobufUtil::convertToTableDesc) + .collect(Collectors.toList()); } + /** * get the split keys in form "byte [][]" from a CreateTableRequest proto * @@ -2398,6 +2395,13 @@ public final class ProtobufUtil { .setQualifier(UnsafeByteOperations.unsafeWrap(tableName.getQualifier())).build(); } + public static List toTableNameList(List tableNamesList) { + if (tableNamesList == null) { + return new ArrayList<>(); + } + return tableNamesList.stream().map(ProtobufUtil::toTableName).collect(Collectors.toList()); + } + public static TableName[] getTableNameArray(List tableNamesList) { if (tableNamesList == null) { return new TableName[0]; @@ -3345,23 +3349,33 @@ public final class ProtobufUtil { } /** - * Create a SplitRegionRequest for a given region name - * - * @param regionName the name of the region to split - * @param splitPoint the split point - * @return a SplitRegionRequest - */ - public static SplitRegionRequest buildSplitRegionRequest( - final byte[] regionName, final byte[] splitPoint) { - SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder(); - RegionSpecifier region = RequestConverter.buildRegionSpecifier( - RegionSpecifierType.REGION_NAME, regionName); - builder.setRegion(region); - if (splitPoint != null) { - builder.setSplitPoint(UnsafeByteOperations.unsafeWrap(splitPoint)); - } - return builder.build(); - } + * Create a SplitRegionRequest for a given region name + * @param regionName the name of the region to split + * @param splitPoint the split point + * @return a SplitRegionRequest + * @deprecated Use {@link #buildSplitRegionRequest(byte[], Optional)} instead. + */ + @Deprecated + public static SplitRegionRequest buildSplitRegionRequest(final byte[] regionName, + final byte[] splitPoint) { + return buildSplitRegionRequest(regionName, Optional.ofNullable(splitPoint)); + } + + /** + * Create a SplitRegionRequest for a given region name + * @param regionName the name of the region to split + * @param splitPoint the split point + * @return a SplitRegionRequest + */ + public static SplitRegionRequest buildSplitRegionRequest(byte[] regionName, + Optional splitPoint) { + SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder(); + RegionSpecifier region = + RequestConverter.buildRegionSpecifier(RegionSpecifierType.REGION_NAME, regionName); + builder.setRegion(region); + splitPoint.ifPresent(sp -> builder.setSplitPoint(UnsafeByteOperations.unsafeWrap(sp))); + return builder.build(); + } public static ProcedureDescription buildProcedureDescription(String signature, String instance, Map props) { diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java index 67f7d0a5ad6..39ae6a51717 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.shaded.protobuf; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; @@ -919,25 +920,37 @@ public final class RequestConverter { builder.setRegionInfo(HRegionInfo.convert(regionInfo)); return builder.build(); } - /** - * Create a CompactRegionRequest for a given region name - * - * @param regionName the name of the region to get info - * @param major indicator if it is a major compaction - * @return a CompactRegionRequest - */ - public static CompactRegionRequest buildCompactRegionRequest( - final byte[] regionName, final boolean major, final byte [] family) { - CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder(); - RegionSpecifier region = buildRegionSpecifier( - RegionSpecifierType.REGION_NAME, regionName); - builder.setRegion(region); - builder.setMajor(major); - if (family != null) { - builder.setFamily(UnsafeByteOperations.unsafeWrap(family)); - } - return builder.build(); - } + + /** + * Create a CompactRegionRequest for a given region name + * @param regionName the name of the region to get info + * @param major indicator if it is a major compaction + * @param columnFamily + * @return a CompactRegionRequest + * @deprecated Use {@link #buildCompactRegionRequest(byte[], boolean, Optional)} instead. + */ + @Deprecated + public static CompactRegionRequest buildCompactRegionRequest(byte[] regionName, boolean major, + byte[] columnFamily) { + return buildCompactRegionRequest(regionName, major, Optional.ofNullable(columnFamily)); + } + + /** + * Create a CompactRegionRequest for a given region name + * @param regionName the name of the region to get info + * @param major indicator if it is a major compaction + * @param columnFamily + * @return a CompactRegionRequest + */ + public static CompactRegionRequest buildCompactRegionRequest(byte[] regionName, boolean major, + Optional columnFamily) { + CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder(); + RegionSpecifier region = buildRegionSpecifier(RegionSpecifierType.REGION_NAME, regionName); + builder.setRegion(region); + builder.setMajor(major); + columnFamily.ifPresent(family -> builder.setFamily(UnsafeByteOperations.unsafeWrap(family))); + return builder.build(); + } /** * @see {@link #buildRollWALWriterRequest()} @@ -1084,12 +1097,13 @@ public final class RequestConverter { /** * Create a protocol buffer MoveRegionRequest - * * @param encodedRegionName * @param destServerName * @return A MoveRegionRequest * @throws DeserializationException + * @deprecated Use {@link #buildMoveRegionRequest(byte[], Optional)} instead. */ + @Deprecated public static MoveRegionRequest buildMoveRegionRequest( final byte [] encodedRegionName, final byte [] destServerName) throws DeserializationException { @@ -1103,6 +1117,22 @@ public final class RequestConverter { return builder.build(); } + /** + * Create a protocol buffer MoveRegionRequest + * @param encodedRegionName + * @param destServerName + * @return A MoveRegionRequest + */ + public static MoveRegionRequest buildMoveRegionRequest(byte[] encodedRegionName, + Optional destServerName) { + MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder(); + builder.setRegion(buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME, + encodedRegionName)); + destServerName.ifPresent(serverName -> builder.setDestServerName(ProtobufUtil + .toServerName(serverName))); + return builder.build(); + } + public static MergeTableRegionsRequest buildMergeTableRegionsRequest( final byte[][] encodedNameOfdaughaterRegions, final boolean forcible, @@ -1310,11 +1340,25 @@ public final class RequestConverter { * @param pattern The compiled regular expression to match against * @param includeSysTables False to match only against userspace tables * @return a GetTableDescriptorsRequest + * @deprecated Use {@link #buildGetTableDescriptorsRequest(Optional, boolean)} instead. */ + @Deprecated public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(final Pattern pattern, boolean includeSysTables) { + return buildGetTableDescriptorsRequest(Optional.ofNullable(pattern), includeSysTables); + } + + /** + * Creates a protocol buffer GetTableDescriptorsRequest + * + * @param pattern The compiled regular expression to match against + * @param includeSysTables False to match only against userspace tables + * @return a GetTableDescriptorsRequest + */ + public static GetTableDescriptorsRequest + buildGetTableDescriptorsRequest(Optional pattern, boolean includeSysTables) { GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder(); - if (pattern != null) builder.setRegex(pattern.toString()); + pattern.ifPresent(p -> builder.setRegex(p.toString())); builder.setIncludeSysTables(includeSysTables); return builder.build(); } @@ -1325,11 +1369,25 @@ public final class RequestConverter { * @param pattern The compiled regular expression to match against * @param includeSysTables False to match only against userspace tables * @return a GetTableNamesRequest + * @deprecated Use {@link #buildGetTableNamesRequest(Optional, boolean)} instead. */ + @Deprecated public static GetTableNamesRequest buildGetTableNamesRequest(final Pattern pattern, boolean includeSysTables) { + return buildGetTableNamesRequest(Optional.ofNullable(pattern), includeSysTables); + } + + /** + * Creates a protocol buffer GetTableNamesRequest + * + * @param pattern The compiled regular expression to match against + * @param includeSysTables False to match only against userspace tables + * @return a GetTableNamesRequest + */ + public static GetTableNamesRequest buildGetTableNamesRequest(Optional pattern, + boolean includeSysTables) { GetTableNamesRequest.Builder builder = GetTableNamesRequest.newBuilder(); - if (pattern != null) builder.setRegex(pattern.toString()); + pattern.ifPresent(p -> builder.setRegex(p.toString())); builder.setIncludeSysTables(includeSysTables); return builder.build(); } @@ -1635,11 +1693,18 @@ public final class RequestConverter { return builder.build(); } + /** + * @deprecated Use {@link #buildListReplicationPeersRequest(Optional)} instead. + */ + @Deprecated public static ListReplicationPeersRequest buildListReplicationPeersRequest(Pattern pattern) { + return buildListReplicationPeersRequest(Optional.ofNullable(pattern)); + } + + public static ListReplicationPeersRequest + buildListReplicationPeersRequest(Optional pattern) { ListReplicationPeersRequest.Builder builder = ListReplicationPeersRequest.newBuilder(); - if (pattern != null) { - builder.setRegex(pattern.toString()); - } + pattern.ifPresent(p -> builder.setRegex(p.toString())); return builder.build(); } diff --git a/hbase-endpoint/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldSecureEndpoint.java b/hbase-endpoint/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldSecureEndpoint.java index 10a4d19c5af..dc895f69172 100644 --- a/hbase-endpoint/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldSecureEndpoint.java +++ b/hbase-endpoint/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldSecureEndpoint.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.regionserver; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; @@ -136,7 +137,7 @@ public class TestHRegionServerBulkLoadWithOldSecureEndpoint extends TestHRegionS conn.getAdmin(getLocation().getServerName()); CompactRegionRequest request = RequestConverter.buildCompactRegionRequest( - getLocation().getRegionInfo().getRegionName(), true, null); + getLocation().getRegionInfo().getRegionName(), true, Optional.empty()); server.compactRegion(null, request); numCompactions.incrementAndGet(); return null; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBalancerAdminApi.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBalancerAdminApi.java index b1df40ea106..00303e2489e 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBalancerAdminApi.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBalancerAdminApi.java @@ -29,23 +29,23 @@ public class TestAsyncBalancerAdminApi extends TestAsyncAdminBase { @Test public void testBalancer() throws Exception { - boolean initialState = admin.isBalancerEnabled().get(); + boolean initialState = admin.isBalancerOn().get(); // Start the balancer, wait for it. - boolean prevState = admin.setBalancerRunning(!initialState).get(); + boolean prevState = admin.setBalancerOn(!initialState).get(); // The previous state should be the original state we observed assertEquals(initialState, prevState); // Current state should be opposite of the original - assertEquals(!initialState, admin.isBalancerEnabled().get()); + assertEquals(!initialState, admin.isBalancerOn().get()); // Reset it back to what it was - prevState = admin.setBalancerRunning(initialState).get(); + prevState = admin.setBalancerOn(initialState).get(); // The previous state should be the opposite of the initial state assertEquals(!initialState, prevState); // Current state should be the original state again - assertEquals(initialState, admin.isBalancerEnabled().get()); + assertEquals(initialState, admin.isBalancerOn().get()); } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNamespaceAdminApi.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNamespaceAdminApi.java index ed2e246a8bb..eccff3ff398 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNamespaceAdminApi.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNamespaceAdminApi.java @@ -74,7 +74,7 @@ public class TestAsyncNamespaceAdminApi extends TestAsyncAdminBase { // create namespace and verify admin.createNamespace(NamespaceDescriptor.create(nsName).build()).join(); - assertEquals(3, admin.listNamespaceDescriptors().get().length); + assertEquals(3, admin.listNamespaceDescriptors().get().size()); TEST_UTIL.waitFor(60000, new Waiter.Predicate() { @Override public boolean evaluate() throws Exception { @@ -84,7 +84,7 @@ public class TestAsyncNamespaceAdminApi extends TestAsyncAdminBase { assertNotNull(zkNamespaceManager.get(nsName)); // delete namespace and verify admin.deleteNamespace(nsName).join(); - assertEquals(2, admin.listNamespaceDescriptors().get().length); + assertEquals(2, admin.listNamespaceDescriptors().get().size()); assertEquals(2, zkNamespaceManager.list().size()); assertNull(zkNamespaceManager.get(nsName)); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcedureAdminApi.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcedureAdminApi.java index 82f627cc414..832bcbe2f80 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcedureAdminApi.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcedureAdminApi.java @@ -34,6 +34,7 @@ import org.junit.Test; import org.junit.experimental.categories.Category; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Random; @@ -94,8 +95,8 @@ public class TestAsyncProcedureAdminApi extends TestAsyncAdminBase { @Test public void listProcedure() throws Exception { - ProcedureInfo[] procList = admin.listProcedures().get(); - assertTrue(procList.length >= 0); + List procList = admin.listProcedures().get(); + assertTrue(procList.size() >= 0); } @Test diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionAdminApi.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionAdminApi.java index 3bdd5fdc94e..a3afabc93aa 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionAdminApi.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionAdminApi.java @@ -25,6 +25,7 @@ import static org.junit.Assert.fail; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Random; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicInteger; @@ -84,8 +85,8 @@ public class TestAsyncRegionAdminApi extends TestAsyncAdminBase { for (HRegionInfo regionInfo : onlineRegions) { if (!regionInfo.getTable().isSystemTable()) { info = regionInfo; - boolean closed = admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), - rs.getServerName().getServerName()).get(); + boolean closed = admin.closeRegion(regionInfo.getRegionName(), + Optional.of(rs.getServerName())).get(); assertTrue(closed); } } @@ -114,7 +115,7 @@ public class TestAsyncRegionAdminApi extends TestAsyncAdminBase { info = regionInfo; boolean catchNotServingException = false; try { - admin.closeRegionWithEncodedRegionName("sample", rs.getServerName().getServerName()) + admin.closeRegion(Bytes.toBytes("sample"), Optional.of(rs.getServerName())) .get(); } catch (Exception e) { catchNotServingException = true; @@ -129,77 +130,20 @@ public class TestAsyncRegionAdminApi extends TestAsyncAdminBase { onlineRegions.contains(info)); } - @Test - public void testCloseRegionWhenServerNameIsNull() throws Exception { - byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion3"); - createTableWithDefaultConf(TableName.valueOf(TABLENAME)); - - HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME)); - - try { - List onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()); - for (HRegionInfo regionInfo : onlineRegions) { - if (!regionInfo.isMetaTable()) { - if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion3")) { - admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), null).get(); - } - } - } - fail("The test should throw exception if the servername passed is null."); - } catch (IllegalArgumentException e) { - } - } - @Test public void testCloseRegionWhenServerNameIsEmpty() throws Exception { byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegionWhenServerNameIsEmpty"); createTableWithDefaultConf(TableName.valueOf(TABLENAME)); HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME)); - - try { - List onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()); - for (HRegionInfo regionInfo : onlineRegions) { - if (!regionInfo.isMetaTable()) { - if (regionInfo.getRegionNameAsString() - .contains("TestHBACloseRegionWhenServerNameIsEmpty")) { - admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), " ").get(); - } - } - } - fail("The test should throw exception if the servername passed is empty."); - } catch (IllegalArgumentException e) { - } - } - - @Test - public void testCloseRegionWhenEncodedRegionNameIsNotGiven() throws Exception { - byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion4"); - createTableWithDefaultConf(TableName.valueOf(TABLENAME)); - - HRegionInfo info = null; - HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME)); - List onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()); for (HRegionInfo regionInfo : onlineRegions) { if (!regionInfo.isMetaTable()) { - if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion4")) { - info = regionInfo; - boolean catchNotServingException = false; - try { - admin.closeRegionWithEncodedRegionName(regionInfo.getRegionNameAsString(), - rs.getServerName().getServerName()).get(); - } catch (Exception e) { - // expected, ignore it. - catchNotServingException = true; - } - assertTrue(catchNotServingException); + if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegionWhenServerNameIsEmpty")) { + admin.closeRegion(regionInfo.getRegionName(), Optional.empty()).get(); } } } - onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()); - assertTrue("The region should be present in online regions list.", - onlineRegions.contains(info)); } @Test @@ -214,10 +158,10 @@ public class TestAsyncRegionAdminApi extends TestAsyncAdminBase { HRegionLocation regionLocation = locator.getRegionLocation(Bytes.toBytes("mmm")); HRegionInfo region = regionLocation.getRegionInfo(); byte[] regionName = region.getRegionName(); - Pair pair = rawAdmin.getRegion(regionName).get(); - assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName())); - pair = rawAdmin.getRegion(region.getEncodedNameAsBytes()).get(); - assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName())); + HRegionLocation location = rawAdmin.getRegionLocation(regionName).get(); + assertTrue(Bytes.equals(regionName, location.getRegionInfo().getRegionName())); + location = rawAdmin.getRegionLocation(region.getEncodedNameAsBytes()).get(); + assertTrue(Bytes.equals(regionName, location.getRegionInfo().getRegionName())); } } @@ -289,7 +233,7 @@ public class TestAsyncRegionAdminApi extends TestAsyncAdminBase { table.put(puts); if (isSplitRegion) { - admin.splitRegion(regions.get(0).getRegionName(), splitPoint).get(); + admin.splitRegion(regions.get(0).getRegionName(), Optional.ofNullable(splitPoint)).get(); } else { if (splitPoint == null) { admin.split(tableName).get(); @@ -456,7 +400,7 @@ public class TestAsyncRegionAdminApi extends TestAsyncAdminBase { } } assertTrue(destServerName != null && !destServerName.equals(serverName)); - admin.move(hri.getEncodedNameAsBytes(), Bytes.toBytes(destServerName.getServerName())).get(); + admin.move(hri.getRegionName(), Optional.of(destServerName)).get(); long timeoutTime = System.currentTimeMillis() + 30000; while (true) { @@ -607,15 +551,15 @@ public class TestAsyncRegionAdminApi extends TestAsyncAdminBase { assertTrue(countBefore > 0); // there should be some data files if (expectedState == CompactionState.MINOR) { if (singleFamily) { - admin.compact(table, family).get(); + admin.compact(table, Optional.of(family)).get(); } else { - admin.compact(table).get(); + admin.compact(table, Optional.empty()).get(); } } else { if (singleFamily) { - admin.majorCompact(table, family).get(); + admin.majorCompact(table, Optional.of(family)).get(); } else { - admin.majorCompact(table).get(); + admin.majorCompact(table, Optional.empty()).get(); } } long curt = System.currentTimeMillis(); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSnapshotAdminApi.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSnapshotAdminApi.java index f71f31120e2..3e0c261e772 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSnapshotAdminApi.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSnapshotAdminApi.java @@ -53,9 +53,9 @@ public class TestAsyncSnapshotAdminApi extends TestAsyncAdminBase { @After public void cleanup() throws Exception { - admin.deleteSnapshots(".*").get(); - admin.disableTables(".*").get(); - admin.deleteTables(".*").get(); + admin.deleteSnapshots(Pattern.compile(".*")).get(); + admin.disableTables(Pattern.compile(".*")).get(); + admin.deleteTables(Pattern.compile(".*")).get(); } @Test @@ -175,13 +175,22 @@ public class TestAsyncSnapshotAdminApi extends TestAsyncAdminBase { admin.snapshot(snapshotName3, tableName).get(); Assert.assertEquals(admin.listSnapshots().get().size(), 3); - Assert.assertEquals(admin.listSnapshots("(.*)").get().size(), 3); - Assert.assertEquals(admin.listSnapshots("snapshotName(\\d+)").get().size(), 3); - Assert.assertEquals(admin.listSnapshots("snapshotName[1|3]").get().size(), 2); + Assert.assertEquals(admin.listSnapshots(Pattern.compile("(.*)")).get().size(), 3); + Assert.assertEquals(admin.listSnapshots(Pattern.compile("snapshotName(\\d+)")).get().size(), 3); + Assert.assertEquals(admin.listSnapshots(Pattern.compile("snapshotName[1|3]")).get().size(), 2); Assert.assertEquals(admin.listSnapshots(Pattern.compile("snapshot(.*)")).get().size(), 3); - Assert.assertEquals(admin.listTableSnapshots("testListSnapshots", "s(.*)").get().size(), 3); - Assert.assertEquals(admin.listTableSnapshots("fakeTableName", "snap(.*)").get().size(), 0); - Assert.assertEquals(admin.listTableSnapshots("test(.*)", "snap(.*)[1|3]").get().size(), 2); + Assert.assertEquals( + admin.listTableSnapshots(Pattern.compile("testListSnapshots"), Pattern.compile("s(.*)")).get() + .size(), + 3); + Assert.assertEquals( + admin.listTableSnapshots(Pattern.compile("fakeTableName"), Pattern.compile("snap(.*)")).get() + .size(), + 0); + Assert.assertEquals( + admin.listTableSnapshots(Pattern.compile("test(.*)"), Pattern.compile("snap(.*)[1|3]")).get() + .size(), + 2); } @Test @@ -201,19 +210,19 @@ public class TestAsyncSnapshotAdminApi extends TestAsyncAdminBase { admin.deleteSnapshot(snapshotName1).get(); Assert.assertEquals(admin.listSnapshots().get().size(), 2); - admin.deleteSnapshots("(.*)abc").get(); + admin.deleteSnapshots(Pattern.compile("(.*)abc")).get(); Assert.assertEquals(admin.listSnapshots().get().size(), 2); - admin.deleteSnapshots("(.*)1").get(); + admin.deleteSnapshots(Pattern.compile("(.*)1")).get(); Assert.assertEquals(admin.listSnapshots().get().size(), 2); - admin.deleteTableSnapshots("(.*)", "(.*)1").get(); + admin.deleteTableSnapshots(Pattern.compile("(.*)"), Pattern.compile("(.*)1")).get(); Assert.assertEquals(admin.listSnapshots().get().size(), 2); - admin.deleteTableSnapshots("(.*)", "(.*)2").get(); + admin.deleteTableSnapshots(Pattern.compile("(.*)"), Pattern.compile("(.*)2")).get(); Assert.assertEquals(admin.listSnapshots().get().size(), 1); - admin.deleteTableSnapshots("(.*)", "(.*)3").get(); + admin.deleteTableSnapshots(Pattern.compile("(.*)"), Pattern.compile("(.*)3")).get(); Assert.assertEquals(admin.listSnapshots().get().size(), 0); } } \ No newline at end of file diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java index c0ccd5e018d..6586a03afc2 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java @@ -80,7 +80,7 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { @Test public void testListTables() throws Exception { - int numTables = admin.listTables().get().length; + int numTables = admin.listTables().get().size(); final TableName tableName1 = TableName.valueOf(name.getMethodName() + "1"); final TableName tableName2 = TableName.valueOf(name.getMethodName() + "2"); final TableName tableName3 = TableName.valueOf(name.getMethodName() + "3"); @@ -89,13 +89,13 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { TEST_UTIL.createTable(tables[i], FAMILY); } - TableDescriptor[] tableDescs = admin.listTables().get(); - int size = tableDescs.length; + List tableDescs = admin.listTables().get(); + int size = tableDescs.size(); assertTrue(size >= tables.length); for (int i = 0; i < tables.length && i < size; i++) { boolean found = false; - for (int j = 0; j < tableDescs.length; j++) { - if (tableDescs[j].getTableName().equals(tables[i])) { + for (int j = 0; j < size; j++) { + if (tableDescs.get(j).getTableName().equals(tables[i])) { found = true; break; } @@ -103,13 +103,13 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { assertTrue("Not found: " + tables[i], found); } - TableName[] tableNames = admin.listTableNames().get(); - size = tableNames.length; + List tableNames = admin.listTableNames().get(); + size = tableNames.size(); assertTrue(size == (numTables + tables.length)); for (int i = 0; i < tables.length && i < size; i++) { boolean found = false; - for (int j = 0; j < tableNames.length; j++) { - if (tableNames[j].equals(tables[i])) { + for (int j = 0; j < size; j++) { + if (tableNames.get(j).equals(tables[i])) { found = true; break; } @@ -121,10 +121,10 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { TEST_UTIL.deleteTable(tables[i]); } - tableDescs = admin.listTables((Pattern) null, true).get(); - assertTrue("Not found system tables", tableDescs.length > 0); - tableNames = admin.listTableNames((Pattern) null, true).get(); - assertTrue("Not found system tables", tableNames.length > 0); + tableDescs = admin.listTables(Optional.empty(), true).get(); + assertTrue("Not found system tables", tableDescs.size() > 0); + tableNames = admin.listTableNames(Optional.empty(), true).get(); + assertTrue("Not found system tables", tableNames.size() > 0); } @Test(timeout = 300000) @@ -143,13 +143,13 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { @Test(timeout = 300000) public void testCreateTable() throws Exception { - TableDescriptor[] tables = admin.listTables().get(); - int numTables = tables.length; + List tables = admin.listTables().get(); + int numTables = tables.size(); final TableName tableName = TableName.valueOf(name.getMethodName()); admin.createTable(new HTableDescriptor(tableName).addFamily(new HColumnDescriptor(FAMILY))) .join(); tables = admin.listTables().get(); - assertEquals(numTables + 1, tables.length); + assertEquals(numTables + 1, tables.size()); assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster().getMaster() .getTableStateManager().isTableState(tableName, TableState.State.ENABLED)); assertEquals(TableState.State.ENABLED, getStateFromMeta(tableName)); @@ -449,8 +449,8 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { } catch (Exception e) { } }); - TableDescriptor[] failed = admin.deleteTables(Pattern.compile("testDeleteTables.*")).get(); - assertEquals(0, failed.length); + List failed = admin.deleteTables(Pattern.compile("testDeleteTables.*")).get(); + assertEquals(0, failed.size()); Arrays.stream(tables).forEach((table) -> { admin.tableExists(table).thenAccept((exist) -> assertFalse(exist)).join(); }); @@ -572,7 +572,7 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { ht1.get(get); ht2.get(get); - this.admin.disableTables("testDisableAndEnableTable.*").join(); + this.admin.disableTables(Pattern.compile("testDisableAndEnableTable.*")).join(); // Test that tables are disabled get = new Get(row); @@ -589,7 +589,7 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase { assertEquals(TableState.State.DISABLED, getStateFromMeta(tableName2)); assertTrue(ok); - this.admin.enableTables("testDisableAndEnableTable.*").join(); + this.admin.enableTables(Pattern.compile("testDisableAndEnableTable.*")).join(); // Test that tables are enabled try { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoad.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoad.java index 61fe2cc1cdf..d640cbf63fe 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoad.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoad.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; @@ -236,7 +237,7 @@ public class TestHRegionServerBulkLoad { AdminProtos.AdminService.BlockingInterface server = conn.getAdmin(getLocation().getServerName()); CompactRegionRequest request = RequestConverter.buildCompactRegionRequest( - getLocation().getRegionInfo().getRegionName(), true, null); + getLocation().getRegionInfo().getRegionName(), true, Optional.empty()); server.compactRegion(null, request); numCompactions.incrementAndGet(); return null; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldClient.java index 7aa1b31baa2..a28f8f1a73b 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldClient.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionServerBulkLoadWithOldClient.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.regionserver; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; @@ -122,7 +123,7 @@ public class TestHRegionServerBulkLoadWithOldClient extends TestHRegionServerBul conn.getAdmin(getLocation().getServerName()); CompactRegionRequest request = RequestConverter.buildCompactRegionRequest( - getLocation().getRegionInfo().getRegionName(), true, null); + getLocation().getRegionInfo().getRegionName(), true, Optional.empty()); server.compactRegion(null, request); numCompactions.incrementAndGet(); return null;