This is an automated email from the ASF dual-hosted git repository.
junegunn pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-3 by this push:
new 93fb422cd37 HBASE-30117 TableDescriptorChecker should verify CF
date-tiered and bloom filter configuration set via setValue (#8144)
93fb422cd37 is described below
commit 93fb422cd37bb70c2fe67bf7b437e979493fc29d
Author: Jinhyuk Kim <[email protected]>
AuthorDate: Fri May 8 10:13:33 2026 +0900
HBASE-30117 TableDescriptorChecker should verify CF date-tiered and bloom
filter configuration set via setValue (#8144)
Signed-off-by: Junegunn Choi <[email protected]>
---
.../hadoop/hbase/util/TableDescriptorChecker.java | 7 ++--
.../hbase/client/TestIllegalTableDescriptor.java | 43 ++++++++++++++--------
.../hbase/util/TestTableDescriptorChecker.java | 35 ++++++++++++++++++
3 files changed, 66 insertions(+), 19 deletions(-)
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/TableDescriptorChecker.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/TableDescriptorChecker.java
index 409cc284dee..691103ba256 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/TableDescriptorChecker.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/TableDescriptorChecker.java
@@ -233,8 +233,8 @@ public final class TableDescriptorChecker {
checkDateTieredCompactionForTimeRangeDataTiering(conf);
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
// Column family level configurations
- Configuration cfdConf =
- new
CompoundConfiguration().add(conf).addStringMap(cfd.getConfiguration());
+ Configuration cfdConf = new CompoundConfiguration().add(conf)
+ .addStringMap(cfd.getConfiguration()).addBytesMap(cfd.getValues());
checkDateTieredCompactionForTimeRangeDataTiering(cfdConf);
}
}
@@ -318,7 +318,8 @@ public final class TableDescriptorChecker {
throws IOException {
warnOrThrowExceptionForFailure(conf, () -> {
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
- Configuration cfdConf = new
CompoundConfiguration().addStringMap(cfd.getConfiguration());
+ Configuration cfdConf = new
CompoundConfiguration().addStringMap(cfd.getConfiguration())
+ .addBytesMap(cfd.getValues());
try {
BloomFilterUtil.getBloomFilterParam(cfd.getBloomFilterType(),
cfdConf);
} catch (IllegalArgumentException e) {
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java
index 666cfbdf54a..9b314ba87c5 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java
@@ -213,23 +213,34 @@ public class TestIllegalTableDescriptor {
checkTableIsIllegal(builder.build());
// column family level configuration changes
- builder =
TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));
- cfBuilder = ColumnFamilyDescriptorBuilder.newBuilder(FAMILY);
-
- // First scenario: DataTieringType set to TIME_RANGE without
DateTieredStoreEngine
- cfBuilder.setConfiguration(DataTieringManager.DATATIERING_KEY,
- DataTieringType.TIME_RANGE.name());
- checkTableIsIllegal(builder.setColumnFamily(cfBuilder.build()).build());
-
- // Second scenario: DataTieringType set to TIME_RANGE with
DateTieredStoreEngine
- cfBuilder.setConfiguration(StoreEngine.STORE_ENGINE_CLASS_KEY,
- "org.apache.hadoop.hbase.regionserver.DateTieredStoreEngine");
- checkTableIsLegal(builder.modifyColumnFamily(cfBuilder.build()).build());
+ for (boolean viaSetValue : new boolean[] { false, true }) {
+ builder =
TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));
+ cfBuilder = ColumnFamilyDescriptorBuilder.newBuilder(FAMILY);
+
+ // First scenario: DataTieringType set to TIME_RANGE without
DateTieredStoreEngine
+ setCfKey(cfBuilder, viaSetValue, DataTieringManager.DATATIERING_KEY,
+ DataTieringType.TIME_RANGE.name());
+ checkTableIsIllegal(builder.setColumnFamily(cfBuilder.build()).build());
+
+ // Second scenario: DataTieringType set to TIME_RANGE with
DateTieredStoreEngine
+ setCfKey(cfBuilder, viaSetValue, StoreEngine.STORE_ENGINE_CLASS_KEY,
+ "org.apache.hadoop.hbase.regionserver.DateTieredStoreEngine");
+ checkTableIsLegal(builder.modifyColumnFamily(cfBuilder.build()).build());
+
+ // Third scenario: Disabling DateTieredStoreEngine while Time Range
DataTiering is active
+ setCfKey(cfBuilder, viaSetValue, StoreEngine.STORE_ENGINE_CLASS_KEY,
+ "org.apache.hadoop.hbase.regionserver.DefaultStoreEngine");
+
checkTableIsIllegal(builder.modifyColumnFamily(cfBuilder.build()).build());
+ }
+ }
- // Third scenario: Disabling DateTieredStoreEngine while Time Range
DataTiering is active
- cfBuilder.setConfiguration(StoreEngine.STORE_ENGINE_CLASS_KEY,
- "org.apache.hadoop.hbase.regionserver.DefaultStoreEngine");
- checkTableIsIllegal(builder.modifyColumnFamily(cfBuilder.build()).build());
+ private static void setCfKey(ColumnFamilyDescriptorBuilder cfb, boolean
viaSetValue, String key,
+ String value) {
+ if (viaSetValue) {
+ cfb.setValue(key, value);
+ } else {
+ cfb.setConfiguration(key, value);
+ }
}
private void checkTableIsLegal(TableDescriptor tableDescriptor) throws
IOException {
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestTableDescriptorChecker.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestTableDescriptorChecker.java
index fcc2ab4ce8f..17a36b43750 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestTableDescriptorChecker.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestTableDescriptorChecker.java
@@ -26,6 +26,7 @@ import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.conf.ConfigKey;
+import org.apache.hadoop.hbase.regionserver.BloomType;
import org.apache.hadoop.hbase.testclassification.MiscTests;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.junit.jupiter.api.Tag;
@@ -84,4 +85,38 @@ public class TestTableDescriptorChecker {
TableDescriptorChecker.sanityCheck(conf, t.build());
}
}
+
+ @Test
+ public void testBloomFilterPrefixLengthValidation() throws IOException {
+ Configuration conf = new Configuration();
+ String key = BloomFilterUtil.PREFIX_LENGTH_KEY;
+
+ for (boolean viaSetValue : new boolean[] { true, false }) {
+ ColumnFamilyDescriptorBuilder cf =
ColumnFamilyDescriptorBuilder.newBuilder("cf".getBytes())
+ .setBloomFilterType(BloomType.ROWPREFIX_FIXED_LENGTH);
+ TableDescriptorBuilder t =
TableDescriptorBuilder.newBuilder(TableName.valueOf("test"));
+
+ // Invalid: prefix length must be > 0 for ROWPREFIX_FIXED_LENGTH
+ if (viaSetValue) {
+ cf.setValue(key, "0");
+ } else {
+ cf.setConfiguration(key, "0");
+ }
+ t.setColumnFamily(cf.build());
+ assertThrows(DoNotRetryIOException.class,
+ () -> TableDescriptorChecker.sanityCheck(conf, t.build()),
+ "Should reject ROWPREFIX_FIXED_LENGTH with prefix length 0 set via "
+ + (viaSetValue ? "setValue" : "setConfiguration"));
+
+ // Fix the error.
+ if (viaSetValue) {
+ cf.setValue(key, "5");
+ } else {
+ cf.setConfiguration(key, "5");
+ }
+ t.removeColumnFamily("cf".getBytes());
+ t.setColumnFamily(cf.build());
+ TableDescriptorChecker.sanityCheck(conf, t.build());
+ }
+ }
}