Index: hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (revision 1455001) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (working copy) @@ -976,6 +976,38 @@ public boolean isTableAvailable(String tableName) throws IOException { return connection.isTableAvailable(Bytes.toBytes(tableName)); } + + /** + * Use this api to check if the table has been created with the specified number of + * splitkeys which was used while creating the given table. + * Note : If this api is used after a table's region gets splitted, the api may return + * false. + * @param table + * name of table to check + * @param split + * keys to check if the table has been created with all split keys + * @throws IOException + * if a remote or network excpetion occurs + */ + public boolean isTableAvailable(String tableName, byte[][] splitKeys) throws IOException { + return connection.isTableAvailable(Bytes.toBytes(tableName), splitKeys); + } + + /** + * Use this api to check if the table has been created with the specified number of + * splitkeys which was used while creating the given table. + * Note : If this api is used after a table's region gets splitted, the api may return + * false. + * @param table + * name of table to check + * @param split + * keys to check if the table has been created with all split keys + * @throws IOException + * if a remote or network excpetion occurs + */ + public boolean isTableAvailable(byte[] tableName, byte[][] splitKeys) throws IOException { + return connection.isTableAvailable(tableName, splitKeys); + } /** * Get the status of alter command - indicates how many regions have received Index: hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java (revision 1455001) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java (working copy) @@ -101,6 +101,20 @@ * @throws IOException if a remote or network exception occurs */ public boolean isTableAvailable(byte[] tableName) throws IOException; + + /** + * Use this api to check if the table has been created with the specified number of + * splitkeys which was used while creating the given table. + * Note : If this api is used after a table's region gets splitted, the api may return + * false. + * @param tableName + * tableName + * @param splitKeys + * splitKeys used while creating table + * @throws IOException + * if a remote or network exception occurs + */ + public boolean isTableAvailable(byte[] tableName, byte[][] splitKeys) throws IOException; /** * List all the userspace tables. In other words, scan the META table. Index: hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (revision 1455001) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (working copy) @@ -848,21 +848,65 @@ public boolean processRow(Result row) throws IOException { HRegionInfo info = MetaScanner.getHRegionInfo(row); if (info != null) { - if (Bytes.equals(tableName, info.getTableName())) { + if (Bytes.compareTo(tableName, info.getTableName()) == 0) { ServerName server = HRegionInfo.getServerName(row); if (server == null) { available.set(false); return false; } regionCount.incrementAndGet(); + } else if (Bytes.compareTo(tableName, info.getTableName()) < 0) { + // Return if we are done with the current table + return false; } } return true; } }; - MetaScanner.metaScan(conf, visitor); + MetaScanner.metaScan(conf, visitor, tableName); return available.get() && (regionCount.get() > 0); } + + @Override + public boolean isTableAvailable(final byte[] tableName, final byte[][] splitKeys) + throws IOException { + final AtomicBoolean available = new AtomicBoolean(true); + final AtomicInteger regionCount = new AtomicInteger(0); + MetaScannerVisitor visitor = new MetaScannerVisitorBase() { + @Override + public boolean processRow(Result row) throws IOException { + HRegionInfo info = MetaScanner.getHRegionInfo(row); + if (info != null) { + if (Bytes.compareTo(tableName, info.getTableName()) == 0) { + ServerName server = HRegionInfo.getServerName(row); + if (server == null) { + available.set(false); + return false; + } + if (!Bytes.equals(info.getStartKey(), HConstants.EMPTY_BYTE_ARRAY)) { + for (byte[] splitKey : splitKeys) { + // Just check if the splitkey is available + if (Bytes.equals(info.getStartKey(), splitKey)) { + regionCount.incrementAndGet(); + break; + } + } + } else { + // Always empty start row should be counted + regionCount.incrementAndGet(); + } + } else if (Bytes.compareTo(tableName, info.getTableName()) < 0) { + // Return if we are done with the current table + return false; + } + } + return true; + } + }; + MetaScanner.metaScan(conf, visitor, tableName); + // +1 needs to be added so that the empty start row is also taken into account + return available.get() && (regionCount.get() == splitKeys.length + 1); + } /* * @param enabled True if table is enabled Index: hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (revision 1455001) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (working copy) @@ -558,6 +558,9 @@ HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); admin.createTable(desc, splitKeys); + + boolean tableAvailable = admin.isTableAvailable(Bytes.toString(tableName), splitKeys); + assertTrue("Table should be created with splitKyes + 1 rows in META", tableAvailable); HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName); Map regions = ht.getRegionLocations(); @@ -710,6 +713,21 @@ } @Test + public void testTableAvailableWithRandomSplitKeys() throws Exception { + byte[] tableName = Bytes.toBytes("testTableAvailableWithRandomSplitKeys"); + HTableDescriptor desc = new HTableDescriptor(tableName); + desc.addFamily(new HColumnDescriptor("col")); + byte[][] splitKeys = new byte[1][]; + splitKeys = new byte [][] { + new byte [] { 1, 1, 1 }, + new byte [] { 2, 2, 2 } + }; + admin.createTable(desc); + boolean tableAvailable = admin.isTableAvailable(Bytes.toString(tableName), splitKeys); + assertFalse("Table should be created with 1 row in META", tableAvailable); + } + + @Test public void testCreateTableWithOnlyEmptyStartRow() throws IOException { byte[] tableName = Bytes.toBytes("testCreateTableWithOnlyEmptyStartRow"); byte[][] splitKeys = new byte[1][];