HBASE-24997 [hbase-operator-tools] NPE in RegionsMerger#mergeRegions (#75)
Signed-off-by: Wellington Chevreuil <wchevreuil@apache.org>
diff --git a/hbase-tools/src/main/java/org/apache/hbase/RegionsMerger.java b/hbase-tools/src/main/java/org/apache/hbase/RegionsMerger.java
index 6a3e1e8..abfc6c9 100644
--- a/hbase-tools/src/main/java/org/apache/hbase/RegionsMerger.java
+++ b/hbase-tools/src/main/java/org/apache/hbase/RegionsMerger.java
@@ -114,6 +114,7 @@
new SubstringComparator(tblName+","));
SingleColumnValueFilter colFilter = new SingleColumnValueFilter(CATALOG_FAMILY,
STATE_QUALIFIER, CompareOperator.EQUAL, Bytes.toBytes("OPEN"));
+ colFilter.setFilterIfMissing(true);
Scan scan = new Scan();
FilterList filter = new FilterList(FilterList.Operator.MUST_PASS_ALL);
filter.addFilter(rowFilter);
diff --git a/hbase-tools/src/test/java/org/apache/hbase/TestRegionsMerger.java b/hbase-tools/src/test/java/org/apache/hbase/TestRegionsMerger.java
index 9c5fe37..e2513a2 100644
--- a/hbase-tools/src/test/java/org/apache/hbase/TestRegionsMerger.java
+++ b/hbase-tools/src/test/java/org/apache/hbase/TestRegionsMerger.java
@@ -22,16 +22,23 @@
import java.io.IOException;
import java.util.List;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.CellBuilderFactory;
+import org.apache.hadoop.hbase.CellBuilderType;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.*;
-
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
public class TestRegionsMerger {
private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@@ -132,6 +139,34 @@
originalCount, TEST_UTIL.countRows(table));
}
+ @Test
+ public void testRegionHasNoState() throws Exception {
+ TEST_UTIL.getConfiguration().setInt(RegionsMerger.MAX_ROUNDS_IDLE, 3);
+ generateTableData();
+ // Turn on the replication of the table, and then merge two regions, the parent regions will
+ // not have the column info:state in the meta table, only the column
+ // rep_barrier:seqnumDuringOpen is left. And we should skip the parent regions.
+ // Here we manually put a region with no state defined.
+ String noStateRegion = TABLE_NAME.getNameAsString()+",0";
+ Put put = new Put(Bytes.toBytes(noStateRegion));
+ put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
+ .setRow(put.getRow())
+ .setFamily(HConstants.REPLICATION_BARRIER_FAMILY)
+ .setQualifier(HConstants.SEQNUM_QUALIFIER)
+ .setTimestamp(put.getTimestamp())
+ .setType(Cell.Type.Put)
+ .setValue(Bytes.toBytes(1))
+ .build());
+ MetaTableAccessor.getMetaHTable(TEST_UTIL.getConnection()).put(put);
+
+ TEST_UTIL.getAdmin().flush(TABLE_NAME);
+ final int originalCount = TEST_UTIL.countRows(table);
+ List<RegionInfo> result = mergeRegionsToTarget(TABLE_NAME, 10);
+ assertEquals(10, result.size());
+ assertEquals("Row count before and after merge should be equal",
+ originalCount, TEST_UTIL.countRows(table));
+ }
+
private void generateTableData() throws Exception {
TEST_UTIL.getAdmin().getRegions(TABLE_NAME).forEach(r -> {
byte[] key = r.getStartKey().length == 0 ? new byte[]{0} : r.getStartKey();